Пример #1
0
        public static ScalarField FromAnalyticalField(AnalyticalField func, Index size, Vector origin, Vector cellSize)
        {
            Debug.Assert(size.Length == origin.Length && size.Length == cellSize.Length);

            RectlinearGrid grid  = new RectlinearGrid(size);
            ScalarField    field = new ScalarField(grid);

            for (int idx = 0; idx < size.Product(); ++idx)
            {
                // Compute the n-dimensional position.
                int   index = idx;
                Index pos   = new Index(0, size.Length);
                pos[0] = index % size[0];

                for (int dim = 1; dim < size.Length; ++dim)
                {
                    index   -= pos[dim - 1];
                    index   /= size[dim - 1];
                    pos[dim] = index % size[dim];
                }

                Vector posV = origin + pos * cellSize;
                field[idx] = func(posV);
            }

            return(field);
        }
Пример #2
0
        public virtual float Sample(ScalarField field, Vector position)
        {
            // Query relevant edges and their weights. Reault varies with different grid types.
            int numCells = NumAdjacentPoints();

            float[] weights;
            int[]   indices = FindAdjacentIndices(position, out weights);

            Debug.Assert(indices.Length == weights.Length);

            // Start with the first grid point.
            float result = field[indices[0]];

            if (result == field.InvalidValue)
            {
                return((float)field.InvalidValue);
            }
            result *= weights[0];

            // Add the other weightes grid points.
            for (int dim = 1; dim < indices.Length; ++dim)
            {
                if (field[indices[dim]] == field.InvalidValue)
                {
                    return((float)field.InvalidValue);
                }
                result += weights[dim] * field[indices[dim]];
            }

            return(result);
        }
Пример #3
0
        /// <summary>
        /// Class to define a slice to be loaded. Dimensions may be either included completely, or only one value is taken.
        /// </summary>
        //public partial class SliceRange
        //{
        //    public SliceRange(LoaderNCF file, RedSea.Variable var) : base()
        //    {
        //        // Query number of dimensions of variable.
        //        int numDims;
        //        NetCDF.ResultCode ncState = NetCDF.nc_inq_varndims(file.GetID(), (int)var, out numDims);
        //        Debug.Assert(ncState == NetCDF.ResultCode.NC_NOERR);
        //        int[] dimIDs = new int[numDims];

        //        // Query relevant dimensions.
        //        ncState = NetCDF.nc_inq_vardimid(file.GetID(), (int)var, dimIDs);
        //        Debug.Assert(ncState == NetCDF.ResultCode.NC_NOERR);

        //        Initialize(dimIDs, var);
        //    }
        //}

        //        public delegate string FilenameFromIndex(int index);
        public static VectorFieldUnsteady LoadTimeSeries(SliceRange[] vars, int starttime, int timelength)
        {
            ScalarField[][] slices = new ScalarField[vars.Length][];
            for (int var = 0; var < vars.Length; ++var)
            {
                slices[var] = new ScalarField[timelength];
            }


            LoaderNCF ncFile;

            for (int time = 0; time < timelength; ++time)
            {
                ncFile = RedSea.Singleton.GetLoaderNCF(time + starttime);// path + (time + 1) + filename);
                for (int var = 0; var < vars.Length; ++var)
                {
                    slices[var][time] = ncFile.LoadFieldSlice(vars[var]);
                }
                ncFile.Close();
            }

            ScalarFieldUnsteady[] scalars = new ScalarFieldUnsteady[vars.Length];
            for (int var = 0; var < vars.Length; ++var)
            {
                scalars[var] = new ScalarFieldUnsteady(slices[var], starttime);
            }

            return(new VectorFieldUnsteady(scalars));
        }
Пример #4
0
        protected void LoadNextField()
        {
            // Keep t1 timestep as new t0. Update mapping on device side.
            _t0X = _t1X;
            new CudaTextureArray2D(_advectParticlesKernel, "vX_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0X);
            _t0Y = _t1Y;
            new CudaTextureArray2D(_advectParticlesKernel, "vY_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0Y);
            CurrentTime++;

            // Load new t1.
            LoaderNCF   ncFile = RedSea.Singleton.GetLoaderNCF(CurrentTime);
            ScalarField t1X    = ncFile.LoadFieldSlice(_ensembleRanges[0]);
            ScalarField t1Y    = ncFile.LoadFieldSlice(_ensembleRanges[1]);

            ncFile.Close();

            // All members are above each other.
            int vHeight = _height * _numMembers;

            // vX, t=1
            _t1X = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One);
            _t1X.CopyFromHostToThis(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(t1Y.Data);
            new CudaTextureArray2D(_advectParticlesKernel, "vY_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1Y);
        }
Пример #5
0
 public ScalarFieldUnsteady(ScalarField[] fields, float timeStart, float timeStep = 1.0f)
     : base()
 {
     _slices = fields;
     _sliceGrid = fields[0].Grid.GetAsTimeGrid(fields.Length, timeStart, timeStep);
     //for (int slice = 0; slice < _slices.Length; ++slice)
     //{
     //    _slices[slice].TimeOrigin = timeStart + timeStep * slice;
     //}
 }
Пример #6
0
        public ScalarFieldUnsteady(ScalarField[] fields)
            : base()
        {
            _slices = fields;

            Grid = fields[0].Grid.GetAsTimeGrid(fields.Length, fields[0].TimeOrigin??0, 1.0f);
            //for (int slice = 0; slice < _slices.Length; ++slice)
            //{
            //    _slices[slice].TimeOrigin = (fields[0].TimeOrigin??0) + slice;
            //}
        }
Пример #7
0
        public VectorFieldUnsteady(VectorFieldUnsteady field, VFJFunction function, int outputDim)
        {
            int       scalars  = outputDim;
            FieldGrid gridCopy = field._scalarsUnsteady[0].TimeSlices[0].Grid.Copy();

            _scalarsUnsteady = new ScalarFieldUnsteady[outputDim];

            // Reserve the space.
            for (int comp = 0; comp < outputDim; ++comp)
            {
                ScalarField[] fields = new ScalarField[field.Size.T]; //(field.Grid);

                for (int t = 0; t < field.Size.T; ++t)

                {
                    fields[t] = new ScalarField(gridCopy);
                }

                _scalarsUnsteady[comp]              = new ScalarFieldUnsteady(fields);
                _scalarsUnsteady[comp].TimeOrigin   = field[0].TimeOrigin ?? 0;
                _scalarsUnsteady[comp].InvalidValue = field.InvalidValue;
                _scalarsUnsteady[comp].DoNotScale();
            }

            this.InvalidValue = field.InvalidValue;
            this.TimeOrigin   = field.TimeOrigin;

            Grid = field.Grid.Copy();

            // Since the time component is in the grid size as well, we do not need to account for time specially.
            GridIndex indexIterator = new GridIndex(field.Size);

            foreach (GridIndex index in indexIterator)
            {
                Vector v = field.Sample((int)index);

                if (v[0] == InvalidValue)
                {
                    for (int dim = 0; dim < Scalars.Length; ++dim)
                    {
                        _scalarsUnsteady[dim][(int)index] = (float)InvalidValue;
                    }
                    continue;
                }

                SquareMatrix J         = field.SampleDerivative(index);
                Vector       funcValue = function(v, J);

                for (int dim = 0; dim < Scalars.Length; ++dim)
                {
                    Scalars[dim][(int)index] = funcValue[dim];
                }
            }
        }
Пример #8
0
        /// <summary>
        /// Add one field given as texture.
        /// </summary>
        /// <param name="field"></param>
        public void AddScalar(ScalarField field)
        {
            ShaderResourceView[] cpy = _fieldTextures;
            _fieldTextures = new ShaderResourceView[_fieldTextures.Length + 1];
            Array.Copy(cpy, _fieldTextures, cpy.Length);

            Texture2D tex = ColorMapping.GenerateTextureFromField(_device, field);

            _fieldTextures[cpy.Length] = new ShaderResourceView(_device, tex);

            SetRenderEffect(Effect);
        }
Пример #9
0
        public static VectorField GetRingField(int numCells)
        {
            ScalarField[] fields = new ScalarField[2];
            Index         size   = new Index(numCells + 1, 2);
            Vector        origin = new Vector(-2, 2);
            Vector        cell   = new Vector(4.0f / numCells, 2);

            fields[0] = ScalarField.FromAnalyticalField(RingFieldX, size, origin, cell);
            fields[1] = ScalarField.FromAnalyticalField(RingFieldY, size, origin, cell);

            return(new VectorField(fields));
        }
Пример #10
0
        public VectorField GetTimeSlice(int slice)
        {
            ScalarField[] slices = new ScalarField[Scalars.Length];
            for (int scalar = 0; scalar < Scalars.Length; ++scalar)
            {
                slices[scalar] = _scalarsUnsteady[scalar].GetTimeSlice(slice);
            }

            var result = new VectorField(slices);

            result.TimeSlice    = slice;
            result.InvalidValue = InvalidValue;
            return(result);
        }
Пример #11
0
        public static VectorFieldUnsteady CreatePathlineSpiral(int numCells, int numSlices, float domainR = 2)
        {
            Vector origin = new Vec2(-domainR);
            Vector cell   = new Vec2(2 * domainR / numCells);
            Index  size   = new Index(numCells + 1, 2);

            ScalarField[] vX = new ScalarField[numSlices];
            ScalarField[] vY = new ScalarField[numSlices];

            for (int slice = 0; slice < numSlices; ++slice)
            {
                vX[slice] = ScalarField.FromAnalyticalField(x => (float)Math.Cos((float)slice / 3) * 4, size, origin, cell);
                vY[slice] = ScalarField.FromAnalyticalField(x => (float)Math.Sin((float)slice / 3) * 4, size, origin, cell);
            }

            return(new VectorFieldUnsteady(new ScalarFieldUnsteady[] { new ScalarFieldUnsteady(vX), new ScalarFieldUnsteady(vY) }));
        }
Пример #12
0
        public static ScalarFieldUnsteady LoadTimeSeries(SliceRange var, int starttime, int timelength)
        {
            ScalarField[] slices = new ScalarField[timelength];


            LoaderNCF ncFile;

            for (int time = starttime; time < starttime + timelength; ++time)
            {
                ncFile = RedSea.Singleton.GetLoaderNCF(time);// path + (time + 1) + filename);

                slices[time] = ncFile.LoadFieldSlice(var);
                ncFile.Close();
            }

            return(new ScalarFieldUnsteady(slices, starttime));
        }
Пример #13
0
        public static void TestCP()
        {
            Random         rnd   = new Random(DateTime.Today.Millisecond);
            RectlinearGrid grid  = new RectlinearGrid(new Index(2, 2));
            ScalarField    cell0 = new ScalarField(grid);
            ScalarField    cell1 = new ScalarField(grid);

            for (int tests = 0; tests < 100; ++tests)
            {
                for (int i = 0; i < 4; ++i)
                {
                    cell0.Data[i] = (float)rnd.NextDouble() - 0.5f;
                    cell1.Data[i] = (float)rnd.NextDouble() - 0.5f;
                }
                VectorField cell = new VectorField(new ScalarField[] { cell0, cell1 });
                //PointSet<Point> points = FieldAnalysis.ComputeCriticalPointsRegularAnalytical2D(cell);
            }
        }
Пример #14
0
        public override VectorField GetSlicePlanarVelocity(int timeSlice)
        {
            ScalarField[] slices = new ScalarField[Size.Length - 1];

            // Copy the grid - one dimension smaller!
            RectlinearGrid grid    = Grid as RectlinearGrid;
            Index          newSize = new Index(Size.Length - 1);

            Array.Copy(Size.Data, newSize.Data, newSize.Length);

            FieldGrid sliceGrid = new RectlinearGrid(newSize);

            for (int i = 0; i < Size.Length - 1; ++i)
            {
                slices[i] = this._scalarsUnsteady[i].GetTimeSlice(timeSlice);

                slices[i].TimeOrigin = timeSlice;
            }
            return(new VectorField(slices));
        }
Пример #15
0
        public static VectorFieldUnsteady CreateBowl(Vec2 center, int numCells, Vec2 dir, int numSlices, float domainR = 2)
        {
            Vector origin = center - new Vec2(domainR);
            Vector cell = new Vec2(2 * domainR / numCells);
            Index size = new Index(numCells + 1, 2);

            ScalarField[] vX = new ScalarField[numSlices];
            ScalarField[] vY = new ScalarField[numSlices];

            for (int slice = 0; slice < numSlices; ++slice)
            {
                vX[slice] = ScalarField.FromAnalyticalField(BowlX, size, origin + dir * slice, cell);
                vY[slice] = ScalarField.FromAnalyticalField(BowlY, size, origin + dir * slice, cell);
            }

            VectorFieldUnsteady field = new VectorFieldUnsteady(new ScalarFieldUnsteady[] { new ScalarFieldUnsteady(vX), new ScalarFieldUnsteady(vY) });
            field.InvalidValue = float.MaxValue;
            field.DoNotScale();
            return field;
        }
Пример #16
0
        public virtual VectorField GetSlicePlanarVelocity(int posInLastDimension)
        {
            ScalarField[] slices = new ScalarField[Size.Length - 1];

            // Copy the grid - one dimension smaller!
            RectlinearGrid grid    = Grid as RectlinearGrid;
            Index          newSize = new Index(Size.Length - 1);

            Array.Copy(Size.Data, newSize.Data, newSize.Length);

            FieldGrid sliceGrid = new RectlinearGrid(newSize);

            for (int i = 0; i < Size.Length - 1; ++i)
            {
                slices[i] = new ScalarField(sliceGrid);
                Array.Copy(((ScalarField)this.Scalars[i]).Data, newSize.Product() * posInLastDimension, slices[i].Data, 0, newSize.Product());
                slices[i].TimeOrigin = posInLastDimension;
            }
            return(new VectorField(slices));
        }
Пример #17
0
        public VectorField(VectorField field, VFJFunction function, int outputDim, bool needJacobian = true)
        {
            int scalars = outputDim;/*function(field.Sample(0), field.SampleDerivative(new Vector(0, field.Size.Length))).Length;*/

            _scalars = new ScalarField[scalars];
            FieldGrid gridCopy = field.Grid.Copy();

            // In case the input field was time dependant, this one is not. Still, we keep the size and origin of the time as new dimension!
            gridCopy.TimeDependant = false;

            for (int dim = 0; dim < scalars; ++dim)
            {
                Scalars[dim] = new ScalarField(gridCopy);
            }
            this.InvalidValue = field.InvalidValue;

            GridIndex indexIterator = new GridIndex(field.Size);

            foreach (GridIndex index in indexIterator)
            {
                Vector v = field.Sample((int)index);

                if (v[0] == InvalidValue)
                {
                    for (int dim = 0; dim < Scalars.Length; ++dim)
                    {
                        Scalars[dim][(int)index] = (float)InvalidValue;
                    }
                    continue;
                }

                SquareMatrix J         = needJacobian? field.SampleDerivative(index) : null;
                Vector       funcValue = function(v, J);

                for (int dim = 0; dim < Scalars.Length; ++dim)
                {
                    var vec = Scalars[dim];
                    Scalars[dim][(int)index] = funcValue[dim];
                }
            }
        }
Пример #18
0
        public static VectorFieldUnsteady CreatePerfect(Vec2 center, int numCells, Vec2 dir, int numSlices, float domainR = 2)
        {
            Vector origin = center - new Vec2(domainR);
            Vector cell   = new Vec2(2 * domainR / numCells);
            Index  size   = new Index(numCells + 1, 2);

            ScalarField[] vX = new ScalarField[numSlices];
            ScalarField[] vY = new ScalarField[numSlices];

            for (int slice = 0; slice < numSlices; ++slice)
            {
                vX[slice] = ScalarField.FromAnalyticalField(PerfX, size, origin + dir * slice, cell);
                vY[slice] = ScalarField.FromAnalyticalField(PerfY, size, origin + dir * slice, cell);
            }

            VectorFieldUnsteady field = new VectorFieldUnsteady(new ScalarFieldUnsteady[] { new ScalarFieldUnsteady(vX), new ScalarFieldUnsteady(vY) });

            field.InvalidValue = float.MaxValue;
            field.DoNotScale();
            return(field);
        }
Пример #19
0
        protected void LoadNextField()
        {
            // Keep t1 timestep as new t0. Update mapping on device side.
            var tmp = _t0X;

            _t0X = _t1X;
            _t1X = tmp;
            new CudaTextureArray2D(_advectParticlesKernel, "vX_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0X);

            tmp  = _t0X;
            _t0Y = _t1Y;
            _t1Y = tmp;
            new CudaTextureArray2D(_advectParticlesKernel, "vY_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0Y);
            CurrentTime++;

            // Load new t1.
            LoaderNCF   ncFile = RedSea.Singleton.GetLoaderNCF(CurrentTime);
            ScalarField t1X    = ncFile.LoadFieldSlice(_ensembleRanges[0]);
            ScalarField t1Y    = ncFile.LoadFieldSlice(_ensembleRanges[1]);

            ncFile.Close();

            // All members are above each other.
            int vHeight = _height * _numMembers;

            float[] paddedArray = new float[_t1X.Width * _t1X.Height];
            Array.Copy(t1X.Data, paddedArray, t1X.Data.Length);
            // vX, t=1
            _t1X.CopyFromHostToThis <float>(paddedArray);
            new CudaTextureArray2D(_advectParticlesKernel, "vX_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1X);

            Array.Copy(t1Y.Data, paddedArray, t1Y.Data.Length);
            // vY, t=1
            _t1Y.CopyFromHostToThis <float>(paddedArray);
            new CudaTextureArray2D(_advectParticlesKernel, "vY_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1Y);
        }
Пример #20
0
        public ScalarField(ScalarField field, SGFunction function, bool needJ = true)
        {
            _data = new float[field.Size.Product()];
            Grid  = field.Grid;

            this.InvalidValue = field.InvalidValue;

            GridIndex indexIterator = new GridIndex(field.Size);

            foreach (GridIndex index in indexIterator)
            {
                float s = field[(int)index];

                if (s == InvalidValue)
                {
                    this[(int)index] = (float)InvalidValue;
                }
                else
                {
                    Vector g = needJ ? field.SampleDerivative(index) : new Vec2(0, 0);
                    this[(int)index] = function(s, g);
                }
            }
        }
Пример #21
0
        public static ScalarField FromAnalyticalField(AnalyticalField func, Index size, Vector origin, Vector cellSize)
        {
            Debug.Assert(size.Length == origin.Length && size.Length == cellSize.Length);

            RectlinearGrid grid = new RectlinearGrid(size);
            ScalarField field = new ScalarField(grid);

            for(int idx = 0; idx < size.Product(); ++idx)
            {
                // Compute the n-dimensional position.
                int index = idx;
                Index pos = new Index(0, size.Length);
                pos[0] = index % size[0];

                for(int dim = 1; dim < size.Length; ++dim)
                {
                    index -= pos[dim - 1];
                    index /= size[dim - 1];
                    pos[dim] = index % size[dim];
                }

                Vector posV = origin + pos * cellSize;
                field[idx] = func(posV);
            }

            return field;
        }
Пример #22
0
        public VectorFieldUnsteady(VectorFieldUnsteady field, VFJFunction function, int outputDim)
        {
            int scalars = outputDim;
            FieldGrid gridCopy = field._scalarsUnsteady[0].TimeSlices[0].Grid.Copy();
            _scalarsUnsteady = new ScalarFieldUnsteady[outputDim];

            // Reserve the space.
            for (int comp = 0; comp < outputDim; ++comp)
            {
                ScalarField[] fields = new ScalarField[field.Size.T]; //(field.Grid);

                for (int t = 0; t < field.Size.T; ++t)

                {
                    fields[t] = new ScalarField(gridCopy);
                }

                _scalarsUnsteady[comp] = new ScalarFieldUnsteady(fields);
                _scalarsUnsteady[comp].TimeOrigin = field[0].TimeOrigin ?? 0;
                _scalarsUnsteady[comp].InvalidValue = field.InvalidValue;
                _scalarsUnsteady[comp].DoNotScale();
            }

            this.InvalidValue = field.InvalidValue;
            this.TimeOrigin = field.TimeOrigin;

            Grid = field.Grid.Copy();

            // Since the time component is in the grid size as well, we do not need to account for time specially.
            GridIndex indexIterator = new GridIndex(field.Size);
            foreach (GridIndex index in indexIterator)
            {
                Vector v = field.Sample((int)index);

                if (v[0] == InvalidValue)
                {
                    for (int dim = 0; dim < Scalars.Length; ++dim)
                        _scalarsUnsteady[dim][(int)index] = (float)InvalidValue;
                    continue;
                }

                SquareMatrix J = field.SampleDerivative(index);
                Vector funcValue = function(v, J);

                for (int dim = 0; dim < Scalars.Length; ++dim)
                {
                    Scalars[dim][(int)index] = funcValue[dim];
                }
            }
        }
Пример #23
0
        /// <summary>
        /// Load a slice from the file.
        /// </summary>
        /// <param name="slice">Carries variable to load, dimensions in file and what to load.</param>
        /// <returns></returns>
        public override ScalarFieldUnsteady LoadTimeSlices(SliceRange slice, int starttime = -1, int timelength = -1)
        {
            Index offsets = new Index(slice.GetOffsets());
            int spaceDims = 4;

            int[] sizeInFile = slice.GetLengths();
            Debug.Assert(starttime == -1 && timelength == -1, "Ignoring those parameters. Plase specify in the SliceRange instance!");

            // Probably has less dimensions.
            int[] sizeField = new int[spaceDims];
            int numDimsField = 0;

            // Exclude time dimension. It will be treated differently.
            for (int dim = 0; dim < offsets.Length; ++dim)
            {

                if (offsets[dim] != -1 && sizeInFile[dim] > 1)
                {
                    sizeField[numDimsField++] = sizeInFile[dim];
                }
                // Include whole dimension.
                else if (offsets[dim] == -1)
                {
                    // Fill size.
                    sizeInFile[dim] = _dimLengths[dim];

                    // Set offset to one. offset = 0, size = size of dimension.
                    offsets[dim] = 0;

                    // Save size in size-vector for the scalar field.
                    sizeField[numDimsField++] = sizeInFile[dim];
                }
            }
            int numSpaceDims = ((sizeInFile[0] > 1) ? 1 : 0) + ((sizeInFile[1] > 1) ? 1 : 0) + ((sizeInFile[2] > 1) ? 1 : 0);
            Index fieldSize = new Index(numSpaceDims);
            Array.Copy(sizeField, fieldSize.Data, fieldSize.Length);

            Debug.Assert(sizeInFile[3] == 1, "How should I load several members into one data block???");

            // Create a grid descriptor for the field.
            // TODO: Actually load this data.
            RectlinearGrid grid = new RectlinearGrid(fieldSize);

            // Create scalar field instance and fill it with data.
            int sliceSize = grid.Size.Product();

            // For each time and subtime step, run through them.
            ScalarField[] fields = new ScalarField[sizeInFile[4] * sizeInFile[5]];

            int indexTime = 0;
            for (int time = 0; time < sizeInFile[spaceDims]; ++time)
            {
                for (int subtime = 0; subtime < sizeInFile[spaceDims + 1]; ++subtime)
                {

                    // Now, load one single file.
                    string filename = RedSea.Singleton.GetFilename(offsets[spaceDims] + time, offsets[spaceDims + 1] + subtime, offsets[3], slice.GetVariable());

                    using (FileStream fs = File.Open(@filename, FileMode.Open))
                    {
                        // Read in the data you need.
                        using (BinaryReader reader = new BinaryReader(fs))
                        {
                            // Read in all floats.
                            Debug.Assert(reader.BaseStream.Length >= sliceSize * sizeof(float));

                            fields[indexTime] = new ScalarField(grid);
                            int indexSpace = 0;
                            for (int z = offsets[2]; z < offsets[2] + sizeInFile[2]; ++z)
                            {
                                // Set file reader position to right start point.
                                reader.BaseStream.Seek(z * _dimLengths[0] * _dimLengths[1] + offsets[1] * _dimLengths[0] + offsets[0], SeekOrigin.Begin);
                                for (int y = offsets[1]; y < offsets[1] + sizeInFile[1]; ++y)
                                {
                                    for (int x = offsets[0]; x < offsets[0] + sizeInFile[0]; ++x)
                                    {
                                        fields[indexTime][indexSpace++] = reader.ReadSingle();
                                    }
                                    // Advance one line.
                                    reader.BaseStream.Seek((_dimLengths[0] - sizeInFile[0]) * sizeof(float), SeekOrigin.Current);
                                }
                            }
                        }
                    }

                    // Change Endian of data.
                    if (!Range.CorrectEndian)
                    {
                        fields[indexTime].ChangeEndian();

                        for (int i = 0; i < fields[indexTime].Data.Length; ++i)
                        {
                            if (fields[indexTime].Data[i] == 0)
                                fields[indexTime].Data[i] = float.MaxValue;
                        }
                        fields[indexTime].InvalidValue = float.MaxValue;
                    }

                    // Go on to next file.
                    indexTime++;
                }

            }

            return new ScalarFieldUnsteady(fields, offsets[spaceDims] * _dimLengths[spaceDims+1] + offsets[spaceDims+1]);
        }
Пример #24
0
        public List<Renderable> ShowPaths()
        {
            bool mapLines = false;

            // Setup an integrator.
            VectorField.Integrator intVF = VectorField.Integrator.CreateIntegrator(Velocity, _currentSetting.IntegrationType);
            intVF.MaxNumSteps = 10000;
            intVF.StepSize = _currentSetting.StepSize;

            if (_lastSetting == null ||
                IntegrationTypeChanged ||
                StepSizeChanged)
            {
                // ~~~~~~~~~~~ Line Integration ~~~~~~~~~~~ \\
                // Clear the raw lines.
                int timeLength = Velocity.Size.T;
                _rawLines = new LineSet[Velocity.Size.T];

                // Initialize the firth
                _rawLines[0] = new LineSet(new Line[0]);
                ScalarField[] lengths = new ScalarField[timeLength];
                lengths[0] = new ScalarField(Velocity.ScalarsAsSFU[0].TimeSlices[0], (v, J) => 0);

                _minLength = new float[timeLength];
                _maxLength = new float[timeLength];

                // Integrate the path line segments between each neighboring pair of time slices.
                for (int time = 1; time < timeLength; ++time)
                {
                    _minLength[time] = float.MaxValue;
                    _maxLength[time] = float.MinValue;

                    // Integrate last points until next time slice.
                    _pathlineSegments[time-1] = intVF.Integrate(_intersectTimeSlices[time - 1], false, time)[0];
                    _pathlineSegments[time - 1].Color = Vector3.UnitZ * (float)time / timeLength;

                    //                    if(time == timeLength - 1)
                    _intersectTimeSlices[time] = _pathlineSegments[time - 1].GetValidEndPoints();//VectorField.Integrator.Status.BORDER);
                    //else
                    //    _intersectTimeSlices[time] = _pathlineSegments[time - 1].GetEndPoints(VectorField.Integrator.Status.TIME_BORDER);
                    _points[time] = new PointCloud(Plane, _intersectTimeSlices[time].ToBasicSet());

                    // Set all positions to 0, or invalid value.
                    lengths[time] = new ScalarField(lengths[time-1], (s, g) => s, false);
                    int i = 0;
                    for (int p = 0; p < _intersectTimeSlices[time].Points.Length; ++p)
                    {
                        EndPoint pP = _intersectTimeSlices[time].Points[p];
                        ++i;
                        // Map floating position to int position.
                        int iPos = _fieldPositionOfValidCell[p];
                        float timeStepped = (pP.Position.Z - (time-1));
                        lengths[time][iPos] += timeStepped > 0 ? pP.LengthLine / timeStepped : 0;
                        float tmp = lengths[time][iPos];
                        _minLength[time] = Math.Min(lengths[time][iPos], _minLength[time]);
                        _maxLength[time] = Math.Max(lengths[time][iPos], _maxLength[time]);

                        if (_minLength[time] < 0 || pP.Status != VectorField.Integrator.Status.TIME_BORDER)
                            i += 0;
                        //Console.WriteLine(lengths[time][iPos]);
                    }
                    Console.WriteLine("Integrated lines until time " + time);
                }

                lengths[0] = new VectorField(Velocity.GetTimeSlice(0), FieldAnalysis.VFLength, 1, false).Scalars[0] as ScalarField;
                _minLength[0] = 0;
                _maxLength[0] = RedSea.Singleton.NumTimeSlices;
                _pathLengths = new ScalarFieldUnsteady(lengths);
                mapLines = true;
            }

            if (_lastSetting == null ||
                SliceTimeMainChanged||
                ShaderChanged)
            {
                ScalarField f = _pathLengths.GetTimeSlice(_currentSetting.SliceTimeMain);
                f.TimeOrigin = 0;
                VectorField vecField;
                switch(_currentSetting.Shader)
                {
                    case FieldPlane.RenderEffect.LIC:
                        VectorField slice = Velocity.GetTimeSlice(0);
                        slice.TimeSlice = 0;
                        vecField = new VectorField(new Field[] { slice.Scalars[0], slice.Scalars[1], f });
                        break;
                    case FieldPlane.RenderEffect.LIC_LENGTH:
                        vecField = Velocity.GetTimeSlice(_currentSetting.SliceTimeMain);
                        vecField.TimeSlice = 0;
                        break;
                    default:
                    case FieldPlane.RenderEffect.COLORMAP:
                    case FieldPlane.RenderEffect.DEFAULT:
                        vecField = new VectorField(new Field[] { f });
                        break;
                }
                _plane = new FieldPlane(Plane, vecField /*Velocity.GetSlice(_currentSetting.SliceTimeReference)*/, _currentSetting.Shader);
            }

            // The line settings have changed. Create new renderables from the lines.
            if (mapLines || LineSettingChanged)
            {
                _lines = new Renderable[_pathlineSegments.Length];

                switch (_currentSetting.LineSetting)
                {
                    // Map the vertices to colored points.
                    case RedSea.DisplayLines.POINTS_2D_LENGTH:
                        for (int i = 0; i < _pathlineSegments.Length; ++i)
                        {
                            PointSet<Point> linePoints = Velocity.ColorCodeArbitrary(_pathlineSegments[i], RedSea.DisplayLineFunctions[(int)_currentSetting.LineSetting]);
                            _lines[i] = new PointCloud(Plane, linePoints);
                        }
                        break;

                    // Render as line.
                    default:
                    case RedSea.DisplayLines.LINE:
                        for (int i = 0; i < _pathlineSegments.Length; ++i)
                        {
                            _lines[i] = new LineBall(Plane, _pathlineSegments[i]);
                        }
                        break;
                }
            }

            // Set mapping values.
            //_plane.UpperBound = 0; //= (1 + _currentSetting.WindowWidth) * (_maxLength[_currentSetting.SliceTimeMain] - _minLength[_currentSetting.SliceTimeMain]) /2 + _minLength[_currentSetting.SliceTimeMain];
            _plane.UpperBound = _currentSetting.WindowWidth + _currentSetting.WindowStart; ///= _currentSetting.SliceTimeMain;
            //_plane.LowerBound = 0; //= (1 - _currentSetting.WindowWidth) * (_maxLength[_currentSetting.SliceTimeMain] - _minLength[_currentSetting.SliceTimeMain]) /2 + _minLength[_currentSetting.SliceTimeMain];
            _plane.LowerBound = _currentSetting.WindowStart; ///= _currentSetting.SliceTimeMain;
            _plane.UsedMap = _currentSetting.Colormap;
            _plane.SetRenderEffect(_currentSetting.Shader);

            List<Renderable> result = new List<Renderable>(50);
            result.Add(_plane);
            switch(_currentSetting.Tracking)
            {
                case RedSea.DisplayTracking.LINE:
                case RedSea.DisplayTracking.LINE_POINTS:
                    Renderable[] lines = new Renderable[_currentSetting.SliceTimeMain];
                    Array.Copy(_lines, lines, _currentSetting.SliceTimeMain);
                    result = result.Concat(lines).ToList();
                    break;
                case RedSea.DisplayTracking.POINTS:
                    result.Add(_points[_currentSetting.SliceTimeMain]);
                    break;
                case RedSea.DisplayTracking.LINE_SELECTION:
                    VectorField.StreamLine<Vector3> line = intVF.IntegrateLineForRendering(new Vec3(_startPoint.X, _startPoint.Y, 0));
                    LineSet set = new LineSet(new Line[] { new Line() { Positions = line.Points.ToArray() } });
                    if(_currentSetting.Flat)
                        set.FlattenLines(_currentSetting.SliceTimeMain);
                    result.Add(new LineBall(Plane, set));
                    break;
                default:
                    break;
            }

            return result;
        }
Пример #25
0
        public List <Renderable> ShowPaths()
        {
            bool mapLines = false;

            // Setup an integrator.
            VectorField.Integrator intVF = VectorField.Integrator.CreateIntegrator(Velocity, _currentSetting.IntegrationType);
            intVF.MaxNumSteps = 10000;
            intVF.StepSize    = _currentSetting.StepSize;

            if (_lastSetting == null ||
                IntegrationTypeChanged ||
                StepSizeChanged)
            {
                // ~~~~~~~~~~~ Line Integration ~~~~~~~~~~~ \\
                // Clear the raw lines.
                int timeLength = Velocity.Size.T;
                _rawLines = new LineSet[Velocity.Size.T];

                // Initialize the firth
                _rawLines[0] = new LineSet(new Line[0]);
                ScalarField[] lengths = new ScalarField[timeLength];
                lengths[0] = new ScalarField(Velocity.ScalarsAsSFU[0].TimeSlices[0], (v, J) => 0);

                _minLength = new float[timeLength];
                _maxLength = new float[timeLength];

                // Integrate the path line segments between each neighboring pair of time slices.
                for (int time = 1; time < timeLength; ++time)
                {
                    _minLength[time] = float.MaxValue;
                    _maxLength[time] = float.MinValue;

                    // Integrate last points until next time slice.
                    _pathlineSegments[time - 1]       = intVF.Integrate(_intersectTimeSlices[time - 1], false, time)[0];
                    _pathlineSegments[time - 1].Color = Vector3.UnitZ * (float)time / timeLength;

                    //                    if(time == timeLength - 1)
                    _intersectTimeSlices[time] = _pathlineSegments[time - 1].GetValidEndPoints();//VectorField.Integrator.Status.BORDER);
                    //else
                    //    _intersectTimeSlices[time] = _pathlineSegments[time - 1].GetEndPoints(VectorField.Integrator.Status.TIME_BORDER);
                    _points[time] = new PointCloud(Plane, _intersectTimeSlices[time].ToBasicSet());

                    // Set all positions to 0, or invalid value.
                    lengths[time] = new ScalarField(lengths[time - 1], (s, g) => s, false);
                    int i = 0;
                    for (int p = 0; p < _intersectTimeSlices[time].Points.Length; ++p)
                    {
                        EndPoint pP = _intersectTimeSlices[time].Points[p];
                        ++i;
                        // Map floating position to int position.
                        int   iPos        = _fieldPositionOfValidCell[p];
                        float timeStepped = (pP.Position.Z - (time - 1));
                        lengths[time][iPos] += timeStepped > 0 ? pP.LengthLine / timeStepped : 0;
                        float tmp = lengths[time][iPos];
                        _minLength[time] = Math.Min(lengths[time][iPos], _minLength[time]);
                        _maxLength[time] = Math.Max(lengths[time][iPos], _maxLength[time]);


                        if (_minLength[time] < 0 || pP.Status != VectorField.Integrator.Status.TIME_BORDER)
                        {
                            i += 0;
                        }
                        //Console.WriteLine(lengths[time][iPos]);
                    }
                    Console.WriteLine("Integrated lines until time " + time);
                }

                lengths[0]    = new VectorField(Velocity.GetTimeSlice(0), FieldAnalysis.VFLength, 1, false).Scalars[0] as ScalarField;
                _minLength[0] = 0;
                _maxLength[0] = RedSea.Singleton.NumTimeSlices;
                _pathLengths  = new ScalarFieldUnsteady(lengths);
                mapLines      = true;
            }

            if (_lastSetting == null ||
                SliceTimeMainChanged ||
                ShaderChanged)
            {
                ScalarField f = _pathLengths.GetTimeSlice(_currentSetting.SliceTimeMain);
                f.TimeOrigin = 0;
                VectorField vecField;
                switch (_currentSetting.Shader)
                {
                case FieldPlane.RenderEffect.LIC:
                    VectorField slice = Velocity.GetTimeSlice(0);
                    slice.TimeSlice = 0;
                    vecField        = new VectorField(new Field[] { slice.Scalars[0], slice.Scalars[1], f });
                    break;

                case FieldPlane.RenderEffect.LIC_LENGTH:
                    vecField           = Velocity.GetTimeSlice(_currentSetting.SliceTimeMain);
                    vecField.TimeSlice = 0;
                    break;

                default:
                case FieldPlane.RenderEffect.COLORMAP:
                case FieldPlane.RenderEffect.DEFAULT:
                    vecField = new VectorField(new Field[] { f });
                    break;
                }
                _plane = new FieldPlane(Plane, vecField /*Velocity.GetSlice(_currentSetting.SliceTimeReference)*/, _currentSetting.Shader);
            }

            // The line settings have changed. Create new renderables from the lines.
            if (mapLines || LineSettingChanged)
            {
                _lines = new Renderable[_pathlineSegments.Length];

                switch (_currentSetting.LineSetting)
                {
                // Map the vertices to colored points.
                case RedSea.DisplayLines.POINTS_2D_LENGTH:
                    for (int i = 0; i < _pathlineSegments.Length; ++i)
                    {
                        PointSet <Point> linePoints = Velocity.ColorCodeArbitrary(_pathlineSegments[i], RedSea.DisplayLineFunctions[(int)_currentSetting.LineSetting]);
                        _lines[i] = new PointCloud(Plane, linePoints);
                    }
                    break;

                // Render as line.
                default:
                case RedSea.DisplayLines.LINE:
                    for (int i = 0; i < _pathlineSegments.Length; ++i)
                    {
                        _lines[i] = new LineBall(Plane, _pathlineSegments[i]);
                    }
                    break;
                }
            }

            // Set mapping values.
            //_plane.UpperBound = 0; //= (1 + _currentSetting.WindowWidth) * (_maxLength[_currentSetting.SliceTimeMain] - _minLength[_currentSetting.SliceTimeMain]) /2 + _minLength[_currentSetting.SliceTimeMain];
            _plane.UpperBound = _currentSetting.WindowWidth + _currentSetting.WindowStart; ///= _currentSetting.SliceTimeMain;
            //_plane.LowerBound = 0; //= (1 - _currentSetting.WindowWidth) * (_maxLength[_currentSetting.SliceTimeMain] - _minLength[_currentSetting.SliceTimeMain]) /2 + _minLength[_currentSetting.SliceTimeMain];
            _plane.LowerBound = _currentSetting.WindowStart;                               ///= _currentSetting.SliceTimeMain;
            _plane.UsedMap    = _currentSetting.Colormap;
            _plane.SetRenderEffect(_currentSetting.Shader);

            List <Renderable> result = new List <Renderable>(50);

            result.Add(_plane);
            switch (_currentSetting.Tracking)
            {
            case RedSea.DisplayTracking.LINE:
            case RedSea.DisplayTracking.LINE_POINTS:
                Renderable[] lines = new Renderable[_currentSetting.SliceTimeMain];
                Array.Copy(_lines, lines, _currentSetting.SliceTimeMain);
                result = result.Concat(lines).ToList();
                break;

            case RedSea.DisplayTracking.POINTS:
                result.Add(_points[_currentSetting.SliceTimeMain]);
                break;

            case RedSea.DisplayTracking.LINE_SELECTION:
                VectorField.StreamLine <Vector3> line = intVF.IntegrateLineForRendering(new Vec3(_startPoint.X, _startPoint.Y, 0));
                LineSet set = new LineSet(new Line[] { new Line()
                                                       {
                                                           Positions = line.Points.ToArray()
                                                       } });
                if (_currentSetting.Flat)
                {
                    set.FlattenLines(_currentSetting.SliceTimeMain);
                }
                result.Add(new LineBall(Plane, set));
                break;

            default:
                break;
            }

            return(result);
        }
Пример #26
0
        /// <summary>
        /// Load a slice from the file.
        /// </summary>
        /// <param name="slice">Carries variable to load, dimensions in file and what to load.</param>
        /// <returns></returns>
        public override ScalarField LoadFieldSlice(SliceRange slice)
        {
            ScalarField field;
            Index       offsets = new Index(slice.GetOffsets());

            NetCDF.ResultCode ncState = NetCDF.ResultCode.NC_NOERR;

            //int[] sizeInFile = new int[offsets.Length];
            int[] sizeInFile = slice.GetLengths();
            // Probably has less dimensions.
            int[] sizeField    = new int[offsets.Length];
            int   numDimsField = 0;

            //int currDimSlice = 0;
            for (int dim = 0; dim < offsets.Length; ++dim)
            {
                if (offsets[dim] != -1 && sizeInFile[dim] > 1)
                {
                    sizeField[numDimsField++] = sizeInFile[dim];
                }
                // Include whole dimension.
                else if (offsets[dim] == -1)
                {
                    // Fill size.
                    int sizeDim;
                    ncState = NetCDF.nc_inq_dimlen(_fileID, slice.GetDimensionID(dim), out sizeDim);
                    Debug.Assert(ncState == NetCDF.ResultCode.NC_NOERR);
                    sizeInFile[dim] = sizeDim;

                    // Set offset to one. offset = 0, size = size of dimension.
                    offsets[dim] = 0;

                    // Save size in size-vector for the scalar field.
                    sizeField[numDimsField++] = sizeDim;
                }
            }

            //if (slice.IsTimeDependent())
            //    numDimsField++;

            // Generate size index for field class.
            Index fieldSize = new Index(numDimsField);

            Array.Copy(sizeField, fieldSize.Data, numDimsField);

            // When the field has several time slices, add a time dimension.
            //if (slice.IsTimeDependent())
            //    fieldSize[numDimsField - 1] = slice.GetNumTimeSlices();

            // Change order of dimensions, so that fastest dimension is at the end.
            for (int dim = 0; dim < fieldSize.Length / 2; ++dim)
            {
                int tmp = fieldSize[dim];
                fieldSize[dim] = fieldSize[fieldSize.Length - 1 - dim];
                fieldSize[fieldSize.Length - 1 - dim] = tmp;
            }

            // Create a grid descriptor for the field.
            // TODO: Actually load this data.
            RectlinearGrid grid = new RectlinearGrid(fieldSize);//, new Vector(0.0f, fieldSize.Length), new Vector(0.1f, fieldSize.Length));

            // Create scalar field instance and fill it with data.
            field = new ScalarField(grid);
            int sliceSize = grid.Size.Product();// / slice.GetNumTimeSlices();

            // Get data. x64 dll fails in debug here...
            ncState = NetCDF.nc_get_vara_float(_fileID, (int)slice.GetVariable(), offsets.Data, sizeInFile, field.Data);
            Debug.Assert(ncState == NetCDF.ResultCode.NC_NOERR, ncState.ToString());

            // Read in invalid value.
            float[] invalidval = new float[1];
            ncState = NetCDF.nc_get_att_float(_fileID, (int)slice.GetVariable(), "_FillValue", invalidval);

            field.InvalidValue = invalidval[0];

            return(field);
        }
Пример #27
0
        public static VectorField GetRingField(int numCells)
        {
            ScalarField[] fields = new ScalarField[2];
            Index size = new Index(numCells + 1, 2);
            Vector origin = new Vector(-2, 2);
            Vector cell = new Vector(4.0f / numCells, 2);
            fields[0] = ScalarField.FromAnalyticalField(RingFieldX, size, origin, cell);
            fields[1] = ScalarField.FromAnalyticalField(RingFieldY, size, origin, cell);

            return new VectorField(fields);
        }
Пример #28
0
        public ScalarField(ScalarField field, SGFunction function, bool needJ = true)
        {
            _data = new float[field.Size.Product()];
            Grid = field.Grid;

            this.InvalidValue = field.InvalidValue;

            GridIndex indexIterator = new GridIndex(field.Size);
            foreach (GridIndex index in indexIterator)
            {
                float s = field[(int)index];

                if (s == InvalidValue)
                {
                    this[(int)index] = (float)InvalidValue;
                }
                else
                {
                    Vector g = needJ ? field.SampleDerivative(index) : new Vec2(0, 0);
                    this[(int)index] = function(s, g);
                }
            }
        }
Пример #29
0
        public virtual float Sample(ScalarField field, Vector position)
        {
            // Query relevant edges and their weights. Reault varies with different grid types.
            int numCells = NumAdjacentPoints();
            float[] weights;
            int[] indices = FindAdjacentIndices(position, out weights);

            Debug.Assert(indices.Length == weights.Length);

            // Start with the first grid point.
            float result = field[indices[0]];
            if (result == field.InvalidValue)
                return (float)field.InvalidValue;
            result *= weights[0];

            // Add the other weightes grid points.
            for (int dim = 1; dim < indices.Length; ++dim)
            {
                if (field[indices[dim]] == field.InvalidValue)
                    return (float)field.InvalidValue;
                result += weights[dim] * field[indices[dim]];
            }

            return result;
        }
Пример #30
0
        public static void TestCP()
        {
            Random rnd = new Random(DateTime.Today.Millisecond);
            RectlinearGrid grid = new RectlinearGrid(new Index(2, 2));
            ScalarField cell0 = new ScalarField(grid);
            ScalarField cell1 = new ScalarField(grid);

            for (int tests = 0; tests < 100; ++tests)
            {
                for (int i = 0; i < 4; ++i)
                {
                    cell0.Data[i] = (float)rnd.NextDouble() - 0.5f;
                    cell1.Data[i] = (float)rnd.NextDouble() - 0.5f;
                }
                VectorField cell = new VectorField(new ScalarField[] { cell0, cell1 });
                //PointSet<Point> points = FieldAnalysis.ComputeCriticalPointsRegularAnalytical2D(cell);
            }
        }
Пример #31
0
        /// <summary>
        /// Load a slice from the file.
        /// </summary>
        /// <param name="slice">Carries variable to load, dimensions in file and what to load.</param>
        /// <returns></returns>
        public override ScalarFieldUnsteady LoadTimeSlices(SliceRange slice, int starttime = -1, int timelength = -1)
        {
            Index offsets   = new Index(slice.GetOffsets());
            int   spaceDims = 4;

            int[] sizeInFile = slice.GetLengths();
            Debug.Assert(starttime == -1 && timelength == -1, "Ignoring those parameters. Plase specify in the SliceRange instance!");

            // Probably has less dimensions.
            int[] sizeField    = new int[spaceDims];
            int   numDimsField = 0;

            // Exclude time dimension. It will be treated differently.
            for (int dim = 0; dim < offsets.Length; ++dim)
            {
                if (offsets[dim] != -1 && sizeInFile[dim] > 1)
                {
                    sizeField[numDimsField++] = sizeInFile[dim];
                }
                // Include whole dimension.
                else if (offsets[dim] == -1)
                {
                    // Fill size.
                    sizeInFile[dim] = _dimLengths[dim];

                    // Set offset to one. offset = 0, size = size of dimension.
                    offsets[dim] = 0;

                    // Save size in size-vector for the scalar field.
                    sizeField[numDimsField++] = sizeInFile[dim];
                }
            }
            int   numSpaceDims = ((sizeInFile[0] > 1) ? 1 : 0) + ((sizeInFile[1] > 1) ? 1 : 0) + ((sizeInFile[2] > 1) ? 1 : 0);
            Index fieldSize    = new Index(numSpaceDims);

            Array.Copy(sizeField, fieldSize.Data, fieldSize.Length);

            Debug.Assert(sizeInFile[3] == 1, "How should I load several members into one data block???");

            // Create a grid descriptor for the field.
            // TODO: Actually load this data.
            RectlinearGrid grid = new RectlinearGrid(fieldSize);

            // Create scalar field instance and fill it with data.
            int sliceSize = grid.Size.Product();

            // For each time and subtime step, run through them.
            ScalarField[] fields = new ScalarField[sizeInFile[4] * sizeInFile[5]];

            int indexTime = 0;

            for (int time = 0; time < sizeInFile[spaceDims]; ++time)
            {
                for (int subtime = 0; subtime < sizeInFile[spaceDims + 1]; ++subtime)
                {
                    // Now, load one single file.
                    string filename = RedSea.Singleton.GetFilename(offsets[spaceDims] + time, offsets[spaceDims + 1] + subtime, offsets[3], slice.GetVariable());

                    using (FileStream fs = File.Open(@filename, FileMode.Open))
                    {
                        // Read in the data you need.
                        using (BinaryReader reader = new BinaryReader(fs))
                        {
                            // Read in all floats.
                            Debug.Assert(reader.BaseStream.Length >= sliceSize * sizeof(float));

                            fields[indexTime] = new ScalarField(grid);
                            int indexSpace = 0;
                            for (int z = offsets[2]; z < offsets[2] + sizeInFile[2]; ++z)
                            {
                                // Set file reader position to right start point.
                                reader.BaseStream.Seek(z * _dimLengths[0] * _dimLengths[1] + offsets[1] * _dimLengths[0] + offsets[0], SeekOrigin.Begin);
                                for (int y = offsets[1]; y < offsets[1] + sizeInFile[1]; ++y)
                                {
                                    for (int x = offsets[0]; x < offsets[0] + sizeInFile[0]; ++x)
                                    {
                                        fields[indexTime][indexSpace++] = reader.ReadSingle();
                                    }
                                    // Advance one line.
                                    reader.BaseStream.Seek((_dimLengths[0] - sizeInFile[0]) * sizeof(float), SeekOrigin.Current);
                                }
                            }
                        }
                    }

                    // Change Endian of data.
                    if (!Range.CorrectEndian)
                    {
                        fields[indexTime].ChangeEndian();

                        for (int i = 0; i < fields[indexTime].Data.Length; ++i)
                        {
                            if (fields[indexTime].Data[i] == 0)
                            {
                                fields[indexTime].Data[i] = float.MaxValue;
                            }
                        }
                        fields[indexTime].InvalidValue = float.MaxValue;
                    }

                    // Go on to next file.
                    indexTime++;
                }
            }

            return(new ScalarFieldUnsteady(fields, offsets[spaceDims] * _dimLengths[spaceDims + 1] + offsets[spaceDims + 1]));
        }
Пример #32
0
        public List <Renderable> ComputeStatistics()
        {
            List <Renderable> result = new List <Renderable>(200);

            result.Add(new FieldPlane(Plane, Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), _currentSetting.Shader, _currentSetting.Colormap));

            if (!_initialized)
            {
                return(result);
            }



            result.Add(new LineBall(Plane, new LineSet(new Line[] { new Line()
                                                                    {
                                                                        Positions = new Vector3[] { _startSelection, _endSelection }
                                                                    } })));


            bool completelyNew = false;

            // ~~~~~~~~~~~~~~ Get new Start Points ~~~~~~~~~~~~~~ //
            if (_lastSetting == null ||
                SliceTimeMainChanged ||
                LineXChanged ||
                _selectionChanged)
            {
                int     numPoints   = _startSelection == null ? 0 : Math.Max(2, _currentSetting.LineX + 1);
                Point[] startPoints = new Point[numPoints];

                // Compute point positions (linear interpolation).
                for (int x = 0; x < numPoints; ++x)
                {
                    float t = (float)x / (numPoints - 1);
                    startPoints[x] = new Point()
                    {
                        Position = _startSelection * (1.0f - t) + _endSelection * t
                    };
                }
                _linePoints = new PointSet <Point>(startPoints);
                _values     = new float[_linePoints.Length];

                completelyNew = true;
            }

            // ~~~~~~~~~~~~ Compute Selected Measure ~~~~~~~~~~~~ //
            if (completelyNew ||
                MeasureChanged ||
                FlatChanged ||
                IntegrationTimeChanged ||
                IntegrationTypeChanged ||
                StepSizeChanged)
            {
                // ~~~~~~~~~~~~~ Compute Scalar FIeld ~~~~~~~~~~~~~~~ //
                ScalarField measure = null;
                switch (_currentSetting.Measure)
                {
                // Velocity Length / Pathline Length.
                case RedSea.Measure.VELOCITY:
                    measure = new VectorField(Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), FieldAnalysis.VFLength, 1).Scalars[0] as ScalarField;
                    break;

                case RedSea.Measure.SURFACE_HEIGHT:
                    break;

                case RedSea.Measure.SALINITY:
                    break;

                case RedSea.Measure.TEMPERATURE:
                    break;

                case RedSea.Measure.DIVERGENCE:
                    measure = new VectorField(Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), FieldAnalysis.Divergence, 1).Scalars[0] as ScalarField;
                    break;

                // Closeness of Pathline.
                case RedSea.Measure.DIVERGENCE_2D:
                    break;

                case RedSea.Measure.VORTICITY:
                    measure = new VectorField(Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), FieldAnalysis.Vorticity, 1).Scalars[0] as ScalarField;
                    break;

                case RedSea.Measure.SHEAR:
                    measure = new VectorField(Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), FieldAnalysis.Shear, 1).Scalars[0] as ScalarField;
                    break;
                }

                // ~~~~~~~~~~~~~~~~ Sample Field ~~~~~~~~~~~~~~~~~~~ //
                switch (_currentSetting.Measure)
                {
                // Velocity Length / Pathline Length.
                case RedSea.Measure.VELOCITY:
                    if (_currentSetting.IntegrationTime == 0)
                    {
                        for (int index = 0; index < _values.Length; ++index)
                        {
                            _values[index] = measure.Sample(((Vec3)_linePoints.Points[index].Position).ToVec2());
                        }
                    }
                    else
                    {
                        VectorField.Integrator integrator = VectorField.Integrator.CreateIntegrator(Velocity, _currentSetting.IntegrationType);
                        integrator.Direction = Sign.POSITIVE;
                        integrator.StepSize  = _currentSetting.StepSize;

                        LineSet line = integrator.Integrate(_linePoints, _currentSetting.Flat, _currentSetting.IntegrationTime)[0];
                        for (int index = 0; index < _values.Length; ++index)
                        {
                            _values[index] = line.Lines[index].LineLength;
                        }
                        result.Add(new LineBall(Plane, line));
                    }
                    break;

                // Simply sample a field.
                case RedSea.Measure.SURFACE_HEIGHT:
                case RedSea.Measure.SALINITY:
                case RedSea.Measure.TEMPERATURE:
                case RedSea.Measure.DIVERGENCE:
                case RedSea.Measure.VORTICITY:
                case RedSea.Measure.SHEAR:
                    for (int index = 0; index < _values.Length; ++index)
                    {
                        _values[index] = measure.Sample(((Vec3)_linePoints.Points[index].Position).ToVec2());
                    }
                    break;

                // Closeness of Pathline.
                case RedSea.Measure.DIVERGENCE_2D:

                    break;
                }
                completelyNew = true;
            }

            //if (completelyNew ||
            //    AlphaStableChanged ||
            //    LineSettingChanged)
            //{
            // ~~~~~~~~~~~~~~~~ Display the Graph ~~~~~~~~~~~~~~~ //
            result.Add(FieldAnalysis.BuildGraph(Plane, _linePoints, _values, _currentSetting.AlphaStable, _currentSetting.LineSetting));
            //}
            _selectionChanged = false;
            return(result);
        }
Пример #33
0
        /// <summary>
        /// Add one field given as texture.
        /// </summary>
        /// <param name="field"></param>
        public void AddScalar(ScalarField field)
        {
            ShaderResourceView[] cpy = _fieldTextures;
            _fieldTextures = new ShaderResourceView[_fieldTextures.Length + 1];
            Array.Copy(cpy, _fieldTextures, cpy.Length);

            Texture2D tex = ColorMapping.GenerateTextureFromField(_device, field);
            _fieldTextures[cpy.Length] = new ShaderResourceView(_device, tex);

            SetRenderEffect(Effect);
        }
Пример #34
0
        public override VectorField GetSlicePlanarVelocity(int timeSlice)
        {
            ScalarField[] slices = new ScalarField[Size.Length - 1];

            // Copy the grid - one dimension smaller!
            RectlinearGrid grid = Grid as RectlinearGrid;
            Index newSize = new Index(Size.Length - 1);
            Array.Copy(Size.Data, newSize.Data, newSize.Length);

            FieldGrid sliceGrid = new RectlinearGrid(newSize);
            for (int i = 0; i < Size.Length - 1; ++i)
            {
                slices[i] = this._scalarsUnsteady[i].GetTimeSlice(timeSlice);

                slices[i].TimeOrigin = timeSlice;
            }
            return new VectorField(slices);
        }
Пример #35
0
        public static VectorFieldUnsteady CreatePathlineSpiral(int numCells, int numSlices, float domainR = 2)
        {
            Vector origin = new Vec2(-domainR);
            Vector cell = new Vec2(2 * domainR / numCells);
            Index size = new Index(numCells + 1, 2);

            ScalarField[] vX = new ScalarField[numSlices];
            ScalarField[] vY = new ScalarField[numSlices];

            for (int slice = 0; slice < numSlices; ++slice)
            {
                vX[slice] = ScalarField.FromAnalyticalField(x =>(float)Math.Cos((float)slice / 3)*4, size, origin, cell);
                vY[slice] = ScalarField.FromAnalyticalField(x =>(float)Math.Sin((float)slice / 3)*4, size, origin, cell);
            }

            return new VectorFieldUnsteady(new ScalarFieldUnsteady[] { new ScalarFieldUnsteady(vX), new ScalarFieldUnsteady(vY) });
        }
Пример #36
0
        public VectorField GetTimeSlice(int slice)
        {
            ScalarField[] slices = new ScalarField[Scalars.Length];
            for (int scalar = 0; scalar < Scalars.Length; ++scalar)
            {
                slices[scalar] = _scalarsUnsteady[scalar].GetTimeSlice(slice);
            }

            var result = new VectorField(slices);
            result.TimeSlice = slice;
            result.InvalidValue = InvalidValue;
            return result;
        }
Пример #37
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();
        }
Пример #38
0
        private FieldPlane LoadPlane(int member, int time)
        {
            ScalarField[] scalars;// = new ScalarField[2];

            //RedSea.Variable measureAsVar;
            //switch (_currentSetting.Measure)
            //{
            //    case RedSea.Measure.SALINITY:
            //    case RedSea.Measure.SURFACE_HEIGHT:
            //    case RedSea.Measure.TEMPERATURE:
            //        measureAsVar = (RedSea.Variable)(int)_currentSetting.Measure;
            //        break;
            //    default:
            //        measureAsVar = RedSea.Variable.VELOCITY_Z;
            //        break;
            //}

            int stepTime = time / 12;
            int substepTime = time - (stepTime * 12);
               // substepTime *= 9;

            LoaderRaw file = RedSea.Singleton.GetLoader(stepTime, substepTime, member, RedSea.Variable.VELOCITY_X) as LoaderRaw;
            int height = _currentSetting.Measure == RedSea.Measure.SURFACE_HEIGHT ? 0 : _currentSetting.SliceHeight;
            file.Range.SetMember(RedSea.Dimension.GRID_Z, height);
            file.Range.CorrectEndian = false;

            switch (_currentSetting.Measure)
            {
                case RedSea.Measure.VELOCITY:
                case RedSea.Measure.DIVERGENCE:
                case RedSea.Measure.VORTICITY:
                case RedSea.Measure.SHEAR:
                case RedSea.Measure.DIVERGENCE_2D:
                    scalars = new ScalarField[2];

                    LoadVelocity:

                    scalars[0] = file.LoadFieldSlice();
                    file.Range.SetVariable(RedSea.Variable.VELOCITY_Y);
                    scalars[1] = file.LoadFieldSlice();
                    break;

                default:
                    RedSea.Measure var = _currentSetting.Measure;

                    // Maybe load vector field too.
                    bool addVelocity = (_currentSetting.Shader == FieldPlane.RenderEffect.LIC || _currentSetting.Shader == FieldPlane.RenderEffect.LIC_LENGTH);
                    scalars = new ScalarField[addVelocity ? 3 : 1];
                    file.Range.SetVariable((RedSea.Variable)var);
                    scalars[scalars.Length - 1] = file.LoadFieldSlice();
                    if (addVelocity)
                        goto LoadVelocity;

                    break;
            }

            VectorField field;
            switch (_currentSetting.Measure)
            {
                case RedSea.Measure.DIVERGENCE:
                    {
                        VectorField vel = new VectorField(scalars);

                        bool keepField = _currentSetting.Shader == FieldPlane.RenderEffect.LIC;
                        scalars = new ScalarField[keepField ? 3 : 1];
                        scalars[scalars.Length - 1] = new VectorField(vel, FieldAnalysis.Divergence, 1, true).Scalars[0] as ScalarField;

                        if (keepField)
                        {
                            scalars[0] = vel.Scalars[0] as ScalarField;
                            scalars[1] = vel.Scalars[1] as ScalarField;
                        }
                        break;
                    }
                case RedSea.Measure.DIVERGENCE_2D:
                    {
                        VectorField vel = new VectorField(scalars);
                        scalars = new VectorField(vel, FieldAnalysis.Div2D, 2, true).Scalars as ScalarField[];
                        break;
                    }
                case RedSea.Measure.VORTICITY:
                    {
                        VectorField vel = new VectorField(scalars);

                        bool keepField = _currentSetting.Shader == FieldPlane.RenderEffect.LIC;
                        scalars = new ScalarField[keepField ? 3 : 1];
                        scalars[scalars.Length - 1] = new VectorField(vel, FieldAnalysis.Vorticity, 1, true).Scalars[0] as ScalarField;

                        if (keepField)
                        {
                            scalars[0] = vel.Scalars[0] as ScalarField;
                            scalars[1] = vel.Scalars[1] as ScalarField;
                        }
                        break;
                    }
                case RedSea.Measure.SHEAR:
                    {
                        VectorField vel = new VectorField(scalars);

                        bool keepField = _currentSetting.Shader == FieldPlane.RenderEffect.LIC;
                        scalars = new ScalarField[keepField ? 3 : 1];
                        scalars[scalars.Length - 1] = new VectorField(vel, FieldAnalysis.Shear, 1, true).Scalars[0] as ScalarField;

                        if (keepField)
                        {
                            scalars[0] = vel.Scalars[0] as ScalarField;
                            scalars[1] = vel.Scalars[1] as ScalarField;
                        }
                        break;
                    }
                default:
                    break;
            }
            field = new VectorField(scalars);

            _grid = field.Grid as RectlinearGrid;

            return new FieldPlane(Plane, field, _currentSetting.Shader, _currentSetting.Colormap);
        }
Пример #39
0
        private Tuple<FieldPlane, RectlinearGrid> LoadPlaneAndGrid(int member, int time, int subtime = 0, bool timeOffset = false)
        {
            LoaderRaw loader = new LoaderRaw();
            ScalarField[] scalars;// = new ScalarField[2];
            // Read in the data.
            //_ranges[0].SetMember(RedSea.Dimension.MEMBER, _currentSetting.MemberMain);
            //_ranges[1].SetMember(RedSea.Dimension.MEMBER, _currentSetting.MemberMain);

            //LoaderNCF ncFile = RedSea.Singleton.GetLoaderNCF(time);
            loader.Range.SetMember(RedSea.Dimension.MEMBER, member);
            loader.Range.SetMember(RedSea.Dimension.TIME, time);
            loader.Range.SetMember(RedSea.Dimension.SUBTIME, subtime);
            switch (_currentSetting.Measure)
            {
                case RedSea.Measure.VELOCITY:
                case RedSea.Measure.DIVERGENCE:
                case RedSea.Measure.VORTICITY:
                case RedSea.Measure.SHEAR:
                case RedSea.Measure.DIVERGENCE_2D:
                    scalars = new ScalarField[2];

                    LoadVelocity:

                    loader.Range.SetMember(RedSea.Dimension.GRID_Z, _currentSetting.SliceHeight);
                    //_variableRanges[(int)RedSea.Variable.VELOCITY_X].SetMember(RedSea.Dimension.MEMBER, member);
                    //_variableRanges[(int)RedSea.Variable.VELOCITY_Y].SetMember(RedSea.Dimension.MEMBER, member);
                    //_variableRanges[(int)RedSea.Variable.VELOCITY_X].SetMember(RedSea.Dimension.CENTER_Z, _currentSetting.SliceHeight);
                    //_variableRanges[(int)RedSea.Variable.VELOCITY_Y].SetMember(RedSea.Dimension.CENTER_Z, _currentSetting.SliceHeight);

                    scalars[0] = loader.LoadFieldSlice(RedSea.Variable.VELOCITY_X);
                    scalars[1] = loader.LoadFieldSlice(RedSea.Variable.VELOCITY_Y);
                    //scalars[0] = ncFile.LoadFieldSlice( _variableRanges[(int)RedSea.Variable.VELOCITY_X]);
                    //scalars[1] = ncFile.LoadFieldSlice(_variableRanges[(int)RedSea.Variable.VELOCITY_Y]);
                    break;

                default:
                    RedSea.Measure var = _currentSetting.Measure;

                    //_variableRanges[(int)var].SetMember(RedSea.Dimension.MEMBER, member);
                    int sliceHeight = (var == RedSea.Measure.SURFACE_HEIGHT) ? 0 : _currentSetting.SliceHeight;
                    loader.Range.SetMember(RedSea.Dimension.GRID_Z, sliceHeight);
                    //_variableRanges[(int)var].SetMember(RedSea.Dimension.CENTER_Z, _currentSetting.SliceHeight);

                    // Maybe load vector field too.
                    bool addVelocity = (_currentSetting.Shader == FieldPlane.RenderEffect.LIC || _currentSetting.Shader == FieldPlane.RenderEffect.LIC_LENGTH);
                    scalars = new ScalarField[addVelocity ? 3 : 1];
                    scalars[scalars.Length - 1] = loader.LoadFieldSlice((RedSea.Variable)var); //ncFile.LoadFieldSlice(_variableRanges[(int)var]);
                    if (addVelocity)
                        goto LoadVelocity;

                    break;
            }
            //ncFile.Close();

            VectorField field;
            switch (_currentSetting.Measure)
            {
                case RedSea.Measure.DIVERGENCE:
                    {
                        VectorField vel = new VectorField(scalars);

                        bool keepField = _currentSetting.Shader == FieldPlane.RenderEffect.LIC;
                        scalars = new ScalarField[keepField ? 3 : 1];
                        scalars[scalars.Length - 1] = new VectorField(vel, FieldAnalysis.Divergence, 1, true).Scalars[0] as ScalarField;

                        if (keepField)
                        {
                            scalars[0] = vel.Scalars[0] as ScalarField;
                            scalars[1] = vel.Scalars[1] as ScalarField;
                        }
                        break;
                    }
                case RedSea.Measure.DIVERGENCE_2D:
                    {
                        VectorField vel = new VectorField(scalars);
                        scalars = new VectorField(vel, FieldAnalysis.Div2D, 2, true).Scalars as ScalarField[];
                        break;
                    }
                case RedSea.Measure.VORTICITY:
                    {
                        VectorField vel = new VectorField(scalars);

                        bool keepField = _currentSetting.Shader == FieldPlane.RenderEffect.LIC;
                        scalars = new ScalarField[keepField ? 3 : 1];
                        scalars[scalars.Length - 1] = new VectorField(vel, FieldAnalysis.Vorticity, 1, true).Scalars[0] as ScalarField;

                        if (keepField)
                        {
                            scalars[0] = vel.Scalars[0] as ScalarField;
                            scalars[1] = vel.Scalars[1] as ScalarField;
                        }
                        break;
                    }
                case RedSea.Measure.SHEAR:
                    {
                        VectorField vel = new VectorField(scalars);

                        bool keepField = _currentSetting.Shader == FieldPlane.RenderEffect.LIC;
                        scalars = new ScalarField[keepField ? 3 : 1];
                        scalars[scalars.Length - 1] = new VectorField(vel, FieldAnalysis.Shear, 1, true).Scalars[0] as ScalarField;

                        if (keepField)
                        {
                            scalars[0] = vel.Scalars[0] as ScalarField;
                            scalars[1] = vel.Scalars[1] as ScalarField;
                        }
                        break;
                    }
                default:
                    break;
            }
            field = new VectorField(scalars);

            //loader.Range.SetMember(RedSea.Dimension.TIME, time+1);
            //var x = loader.LoadFieldSlice(RedSea.Variable.VELOCITY_X);
            //var y = loader.LoadFieldSlice(RedSea.Variable.VELOCITY_Y);
            //ScalarFieldUnsteady xS = new ScalarFieldUnsteady(new ScalarField[] { scalars[0], x });
            //xS.DoNotScale();
            //ScalarFieldUnsteady yS = new ScalarFieldUnsteady(new ScalarField[] { scalars[0], y });
            //yS.DoNotScale();
            //VectorFieldUnsteady twoSlices = new VectorFieldUnsteady(new ScalarFieldUnsteady[] { xS, yS });
            //Console.WriteLine("Remooove meeeeee!");
            //VectorFieldUnsteady awriuwergioaheosiohlbyuygowgfuyvbui = new VectorFieldUnsteady(twoSlices, FieldAnalysis.Acceleration, 2);
            field.TimeSlice = timeOffset ? time * RedSea.Singleton.NumSubsteps + subtime/*time + (float)subtime / RedSea.Singleton.NumSubsteps*/ : 0;
            // field = new VectorField(velocity, FieldAnalysis.StableFFF, 3, true);
            RectlinearGrid grid = field.Grid as RectlinearGrid;

            return new Tuple<FieldPlane, RectlinearGrid>(new FieldPlane(Plane, field, _currentSetting.Shader, _currentSetting.Colormap), grid);
        }