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); }
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); }
/// <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)); }
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); }
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; //} }
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; //} }
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]; } } }
/// <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); }
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)); }
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); }
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) })); }
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)); }
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); } }
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)); }
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; }
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)); }
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]; } } }
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); }
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); }
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); } } }
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; }
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]; } } }
/// <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]); }
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; }
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); }
/// <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); }
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); }
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; }
/// <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])); }
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); }
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); }
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) }); }
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; }
/// <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(); }
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); }
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); }