Beispiel #1
0
        /// <summary>
        /// Setup as empty map with only one value at 1.
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="fieldEnsemble"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        public void SetupPoint(Int2 pos, int startTime)
        {
            // ~~~~~~~~~~~~~~ Copy relevant data ~~~~~~~~~~~~~~ \\
            // Count up when advection was executed.
            CurrentTime = startTime;
            _startTime  = startTime;

            // ~~~~~~~~~~~~ Load ensemble ~~~~~~~~~~~~ \\
            // Load fields first to get the grid size.
            //Loader ncFile = new Loader(RedSea.Singleton.DataFolder + (_startTime + 1) + RedSea.Singleton.FileName);
            //ScalarField t0X = ncFile.LoadFieldSlice(_ensembleRanges[0]);
            //ScalarField t0Y = ncFile.LoadFieldSlice(_ensembleRanges[1]);
            //ncFile.Close();

            LoaderNCF   ncFile = RedSea.Singleton.GetLoaderNCF(_startTime);
            ScalarField t1X    = ncFile.LoadFieldSlice(_ensembleRanges[0]);
            ScalarField t1Y    = ncFile.LoadFieldSlice(_ensembleRanges[1]);

            ncFile.Close();

            // ~~~~~~~~~~~~~~ Copy relevant data ~~~~~~~~~~~~~~ \\
            // Keep for plane creation and size reference.
            _ensembleGrid = t1X.Grid as RectlinearGrid;
            // Mapper for binding the SlimDX texture to CUDA easily.
            _cudaDxMapper = new CudaGraphicsInteropResourceCollection();
            // Tell CUDA which value is a border.
            _texInvalidValue = t1X.InvalidValue ?? float.MaxValue;

            // ~~~~~~~~~~~~ Fill CUDA resources ~~~~~~~~~~~~ \\
            // All members are above each other.
            int vHeight = _height * _numMembers;

            //// vX, t=0
            //_t0X = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One);
            //_t0X.CopyFromHostToThis<float>(t0X.Data);
            //new CudaTextureArray2D(_advectParticlesKernel, "vX_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0X);

            //// vY, t=0
            //_t0Y = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One);
            //_t0Y.CopyFromHostToThis<float>(t0Y.Data);
            //new CudaTextureArray2D(_advectParticlesKernel, "vY_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0Y);

            // vX, t=1
            _t1X = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One);
            _t1X.CopyFromHostToThis <float>(t1X.Data);
            new CudaTextureArray2D(_advectParticlesKernel, "vX_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1X);

            // vY, t=1
            _t1Y = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One);
            _t1Y.CopyFromHostToThis <float>(t1Y.Data);
            new CudaTextureArray2D(_advectParticlesKernel, "vY_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1Y);

            // ~~~~~~~~~~~~~ Create texture ~~~~~~~~~~~~~~~~~~~~ \\
            // Create texture. Completely zero, except for one point.
            Texture2DDescription desc = new Texture2DDescription
            {
                ArraySize         = 1,
                BindFlags         = BindFlags.ShaderResource,
                CpuAccessFlags    = CpuAccessFlags.None,
                Format            = Format.R32_Float,
                Width             = _width,
                Height            = _height,
                MipLevels         = 1,
                OptionFlags       = ResourceOptionFlags.None,
                SampleDescription = new SampleDescription(1, 0),
                Usage             = ResourceUsage.Default
            };

            // Put field data into stream/rectangle object
            float[] zeros = new float[_width * _height];
            Array.Clear(zeros, 0, zeros.Length);

            // Fill the empty texture.
            DataRectangle texData = new DataRectangle(_width * sizeof(float), new DataStream(zeros, true, true));

            _pongFlowMap = new CudaDeviceVariable <float>(_width * _height);//new Texture2D(_device, desc, texData);
            // Magically, copy to device happens here.
            _pongFlowMap = zeros;

            // Add one pixel for integration.
            zeros[pos.X + pos.Y * _width] = 1;
            texData = new DataRectangle(_width * sizeof(float), new DataStream(zeros, true, true));

            // Create texture.
            FlowMap = new Texture2D(_device, desc, texData);

            // ~~~~~~~~~ Make textures mappable to CUDA ~~~~~~~~~~ \\
            _cudaDxMapper.Add(new CudaDirectXInteropResource(FlowMap.ComPointer, CUGraphicsRegisterFlags.None, CudaContext.DirectXVersion.D3D11));


            _cudaDxMapper.MapAllResources();
            CudaArray2D lastFlowMap = _cudaDxMapper[0].GetMappedArray2D(0, 0);

            new CudaTextureArray2D(_advectParticlesKernel, "flowMap", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, lastFlowMap);
            _cudaDxMapper.UnmapAllResources();
        }
Beispiel #2
0
        protected void BuildGraph()
        {
            // Compute ftle.
            if (LineX == 0)
            {
                return;
            }

            _graphData        = FieldAnalysis.WriteGraphToSun(_okubo, new Vector3(_selection.X, _selection.Y, 0));
            _graph            = new LineBall(_graphPlane, _graphData, LineBall.RenderEffect.HEIGHT, Colormap, Flat, SliceTimeMain);
            _graph.LowerBound = -0.05f;
            _graph.UpperBound = 0.05f;

            _rebuilt = false;

            // Load or compute selection by floodfill.
            Graph2D[] okuboSelection;
            LineSet   okuboLines;

            if (LoadGraph("OkuboSelection", _selectedCore, out okuboSelection, out okuboLines))
            {
                return;
            }

            // Floodfill.
            int            numAngles = _okubo.Length;
            int            numRadii  = _okubo[0].Length;
            HashSet <Int2> toFlood   = new HashSet <Int2>();

            okuboSelection = new Graph2D[numAngles];
            for (int angle = 0; angle < numAngles; ++angle)
            {
                toFlood.Add(new Int2(angle, 0));

                okuboSelection[angle] = new Graph2D(numRadii);
                for (int r = 1; r < numRadii; ++r)
                {
                    okuboSelection[angle].Fx[r] = 0;
                    okuboSelection[angle].X[r]  = _okubo[angle].X[r];
                }
            }

            while (toFlood.Count > 0)
            {
                Int2 current = toFlood.Last();
                toFlood.Remove(current);
                okuboSelection[current.X].Fx[current.Y] = 1;

                // In each direction, go negative and positive.
                for (int dim = 0; dim < 2; ++dim)
                {
                    for (int sign = -1; sign <= 1; sign += 2)
                    {
                        Int2 neighbor = new Int2(current);
                        neighbor[dim] += sign;

                        // Wrap angle around.
                        neighbor[0] = (neighbor[0] + numAngles) % numAngles;
                        if (neighbor.Y >= 0 && neighbor.Y < numRadii &&
                            _okubo[neighbor.X].Fx[neighbor.Y] <= 0 &&
                            okuboSelection[neighbor.X].Fx[neighbor.Y] == 0)
                        {
                            toFlood.Add(neighbor);
                        }
                    }
                }
            }

            LineSet sun = FieldAnalysis.WriteGraphToSun(okuboSelection, new Vector3(_selection, SliceTimeMain));

            WriteGraph("OkuboSelection", _selectedCore, okuboSelection, sun);
        }
Beispiel #3
0
 public abstract void Subrange(Int2 min, Int2 max, Int2 selection);
Beispiel #4
0
 public abstract void CompleteRange(Int2 selection);
Beispiel #5
0
 public static bool Equals(Int2 a, Int2 b)
 {
     return(a == b);
 }
Beispiel #6
0
 public Int2(Int2 copy) : base(copy)
 {
 }
Beispiel #7
0
 public float this[Int2 index]
 {
     get { return(this[index.X][index.Y]); }
     set { this[index.X][index.Y] = value; }
 }