Esempio n. 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);
        }
Esempio n. 2
0
        /// <summary>
        /// Append a time dimension.
        /// </summary>
        /// <param name="numTimeSlices"></param>
        /// <param name="timeStart"></param>
        /// <param name="timeStep"></param>
        /// <returns></returns>
        public override FieldGrid GetAsTimeGrid(int numTimeSlices, float timeStart, float timeStep)
        {
            Index timeSize = new Index(Size.Length + 1);

            Array.Copy(Size.Data, timeSize.Data, Size.Length);
            timeSize[Size.Length] = numTimeSlices;
            Vector         origin   = Origin.ToVec(Origin.Length + 1);
            RectlinearGrid timeGrid = new RectlinearGrid(timeSize, origin, timeStart);

            //_timeDependent = true;
            //TimeOrigin = timeStart;
            return(timeGrid);
        }
Esempio n. 3
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);
            }
        }
Esempio n. 4
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));
        }
Esempio n. 5
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));
        }
Esempio n. 6
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);
        }
Esempio n. 7
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);
        }
Esempio n. 8
0
 /// <summary>
 /// Append a time dimension.
 /// </summary>
 /// <param name="numTimeSlices"></param>
 /// <param name="timeStart"></param>
 /// <param name="timeStep"></param>
 /// <returns></returns>
 public override FieldGrid GetAsTimeGrid(int numTimeSlices, float timeStart, float timeStep)
 {
     Index timeSize = new Index(Size.Length + 1);
     Array.Copy(Size.Data, timeSize.Data, Size.Length);
     timeSize[Size.Length] = numTimeSlices;
     Vector origin = Origin.ToVec(Origin.Length + 1);
     RectlinearGrid timeGrid = new RectlinearGrid(timeSize, origin, timeStart);
     //_timeDependent = true;
     //TimeOrigin = timeStart;
     return timeGrid;
 }
Esempio n. 9
0
 protected FieldPlane LoadPlane(int member, int time, out RectlinearGrid grid, int subtime = 0)
 {
     var result = LoadPlaneAndGrid(member, time, subtime);
     grid = result.Item2;
     return result.Item1;
 }
Esempio n. 10
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);
        }
Esempio n. 11
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]));
        }
Esempio n. 12
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);
            }
        }
Esempio n. 13
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();
        }
Esempio n. 14
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]);
        }
Esempio n. 15
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;
        }