/// <summary> /// Calculates the DG-projection (with respect to the DG-basis /// of this field, <see cref="Basis"/>) of /// <paramref name="alpha"/>*<paramref name="a"/>*<paramref name="b"/> /// and, depending on the value of <paramref name="accumulateResult"/>, /// either adds or assigns it to this field. /// </summary> /// <param name="a">1st multiplicand</param> /// <param name="b">2nd multiplicand</param> /// <param name="alpha">scaling for <paramref name="a"/>*<paramref name="b"/></param> /// <param name="em"> /// An optional restriction to the domain in which the projection is /// computed (it may, e.g. be only required in boundary cells, so a /// computation over the whole domain would be a waste of computational /// power. A proper execution mask would be see e.g. /// <see cref="GridData.BoundaryCells"/>.)<br/> /// if null, the computation is carried out in the whole domain; /// </param> /// <param name="accumulateResult"> /// Tells this method whether to accumulate (true) or not (false) /// </param> virtual public void ProjectProduct(double alpha, DGField a, DGField b, CellMask em, bool accumulateResult) { if (!object.ReferenceEquals(a.Basis.GridDat, this.Basis.GridDat)) { throw new ArgumentException("field is associated to another grid.", "a"); } if (!object.ReferenceEquals(b.Basis.GridDat, this.Basis.GridDat)) { throw new ArgumentException("field is associated to another grid.", "b"); } if (!accumulateResult) { if (a == this) { a = (DGField)a.Clone(); if (b == this) { b = a; } } else if (b == this) { b = (DGField)b.Clone(); } this.Clear(); } SpatialOperator multOp = new SpatialOperator(new string[] { "a", "b" }, new string[] { "res" }, QuadOrderFunc.NonLinear(2)); multOp.EquationComponents["res"].Add(new MultiplySource()); multOp.Commit(); var ev = multOp.GetEvaluatorEx( new CoordinateMapping(a, b), null, this.Mapping, edgeQrCtx: new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(this.Basis.GridDat)), volQrCtx: new CellQuadratureScheme(true, em)); ev.Evaluate <CoordinateVector>(alpha, 1.0, this.CoordinateVector); }
public IBMAdamsBashforthLTS(SpatialOperator standardOperator, SpatialOperator boundaryOperator, CoordinateMapping fieldsMap, CoordinateMapping boundaryParameterMap, ISpeciesMap ibmSpeciesMap, IBMControl control, IList <TimeStepConstraint> timeStepConstraints, int reclusteringInterval, bool fluxCorrection, bool forceReclustering, int maxNumOfSubSteps = 0, bool logging = false, bool consoleOutput = false) : base(standardOperator, fieldsMap, boundaryParameterMap, control.ExplicitOrder, control.NumberOfSubGrids, true, timeStepConstraints, reclusteringInterval: reclusteringInterval, fluxCorrection: fluxCorrection, subGrid: ibmSpeciesMap.SubGrid, forceReclustering: forceReclustering, logging: logging, consoleOutput: consoleOutput) { this.speciesMap = ibmSpeciesMap as ImmersedSpeciesMap; if (this.speciesMap == null) { throw new ArgumentException( "Only supported for species maps of type 'ImmersedSpeciesMap'", "speciesMap"); } this.standardOperator = standardOperator; this.boundaryOperator = boundaryOperator; this.boundaryParameterMap = boundaryParameterMap; this.fieldsMap = fieldsMap; this.control = control; agglomerationPatternHasChanged = true; cutCells = speciesMap.Tracker.Regions.GetCutCellMask(); cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells); if (consoleOutput) { Console.WriteLine("### This is IBM ABLTS ctor ###"); } // Normal LTS constructor clusterer = new Clusterer(this.gridData, maxNumOfSubSteps); CurrentClustering = clusterer.CreateClustering(control.NumberOfSubGrids, this.TimeStepConstraints, speciesMap.SubGrid); CurrentClustering = clusterer.TuneClustering(CurrentClustering, Time, this.TimeStepConstraints); // Might remove sub-grids when time step sizes are too similar ABevolver = new IBMABevolve[CurrentClustering.NumberOfClusters]; for (int i = 0; i < ABevolver.Length; i++) { ABevolver[i] = new IBMABevolve(standardOperator, boundaryOperator, fieldsMap, boundaryParameterMap, speciesMap, control.ExplicitOrder, control.LevelSetQuadratureOrder, control.CutCellQuadratureType, sgrd: CurrentClustering.Clusters[i], adaptive: this.adaptive); ABevolver[i].OnBeforeComputeChangeRate += (t1, t2) => this.RaiseOnBeforeComputechangeRate(t1, t2); } GetBoundaryTopology(); // Start-up phase needs an IBM Runge-Kutta time stepper RungeKuttaScheme = new IBMSplitRungeKutta(standardOperator, boundaryOperator, fieldsMap, boundaryParameterMap, speciesMap, timeStepConstraints); }
/// <summary> /// ctor. /// </summary> public LinearSolver(ISparseSolver solver, SpatialOperator spatialOp, CoordinateMapping UnknownsMap) { // verify input // ------------ if (!spatialOp.IsCommited) { throw new ArgumentException("operator must be committed first.", "spatialOp"); } if (spatialOp.ContainsNonlinear) { throw new ArgumentException("spatial differential operator cannot contain nonlinear components for linear solver.", "spatialOp"); } if (!spatialOp.ContainsLinear()) { throw new ArgumentException("spatial differential operator seems to contain no components.", "spatialOp"); } if (spatialOp.DomainVar.Count != spatialOp.CodomainVar.Count) { throw new ArgumentException("spatial differential operator must have the same number of domain and codomain variables.", "spatialOp"); } if (UnknownsMap.Fields.Count != spatialOp.CodomainVar.Count) { throw new ArgumentException("the number of fields in the coordinate mapping must be equal to the number of domain/codomain variables of the spatial differential operator", "fields"); } m_Mapping = UnknownsMap; m_Solver = solver; // matrix assembly // --------------- MsrMatrix eM; { eM = new MsrMatrix(m_Mapping); m_AffineOffset = new double[m_Mapping.LocalLength]; //spatialOp.ComputeMatrixEx(m_Mapping, null, m_Mapping, eM, m_AffineOffset); spatialOp.GetMatrixBuilder(m_Mapping, null, m_Mapping).ComputeMatrix(eM, m_AffineOffset); } ConstructorCommon(eM); }
//################# Hack for saving to database in every (A)LTS sub-step /// <summary> /// Standard constructor for the (adaptive) local time stepping algorithm /// </summary> /// <param name="spatialOp">Spatial operator</param> /// <param name="Fieldsmap">Coordinate mapping for the variable fields</param> /// <param name="Parameters">optional parameter fields, can be null if <paramref name="spatialOp"/> contains no parameters; must match the parameter field list of <paramref name="spatialOp"/>, see <see cref="BoSSS.Foundation.SpatialOperator.ParameterVar"/></param> /// <param name="order">LTS/AB order</param> /// <param name="numOfClusters">Amount of sub-grids/clusters to be used for LTS</param> /// <param name="timeStepConstraints">Time step constraints for later usage as metric</param> /// <param name="subGrid">Sub-grids, e.g., from previous time steps</param> /// <param name="fluxCorrection">Bool for triggering the fluss correction</param> /// <param name="reclusteringInterval">Interval for potential reclustering</param> /// <param name="saveToDBCallback">Hack for plotting all sub-steps</param> /// <remarks>Uses the k-Mean clustering, see <see cref="BoSSS.Solution.Utils.Kmeans"/>, to generate the element groups</remarks> public AdamsBashforthLTS(SpatialOperator spatialOp, CoordinateMapping Fieldsmap, CoordinateMapping Parameters, int order, int numOfClusters, IList <TimeStepConstraint> timeStepConstraints = null, SubGrid subGrid = null, bool fluxCorrection = true, int reclusteringInterval = 0, Action <TimestepNumber, double> saveToDBCallback = null, int initialTimestepNumber = 1) : base(spatialOp, Fieldsmap, Parameters, order, timeStepConstraints, subGrid) { if (reclusteringInterval != 0) { numberOfClustersInitial = numOfClusters; this.timestepNumber = initialTimestepNumber; this.adaptive = true; } // Add OnBeforeComputeChangeRate (AV) to start-up phase time stepper RungeKuttaScheme.OnBeforeComputeChangeRate += (t1, t2) => this.RaiseOnBeforeComputechangeRate(t1, t2); this.reclusteringInterval = reclusteringInterval; this.gridData = Fieldsmap.Fields.First().GridDat; this.fluxCorrection = fluxCorrection; NumberOfLocalTimeSteps = new List <int>(numOfClusters); clusterer = new Clusterer(this.gridData, this.TimeStepConstraints); CurrentClustering = clusterer.CreateClustering(numOfClusters, this.SubGrid); // Might remove clusters when their centres are too close CurrentClustering = CalculateNumberOfLocalTS(CurrentClustering); // Might remove clusters when time step sizes are too similar ABevolver = new ABevolve[CurrentClustering.NumberOfClusters]; for (int i = 0; i < ABevolver.Length; i++) { ABevolver[i] = new ABevolve(spatialOp, Fieldsmap, Parameters, order, adaptive: this.adaptive, sgrd: CurrentClustering.Clusters[i]); ABevolver[i].OnBeforeComputeChangeRate += (t1, t2) => this.RaiseOnBeforeComputechangeRate(t1, t2); } GetBoundaryTopology(); #if DEBUG for (int i = 0; i < CurrentClustering.NumberOfClusters; i++) { Console.WriteLine("AB LTS Ctor: id=" + i + " -> sub-steps=" + NumberOfLocalTimeSteps[i] + " and elements=" + CurrentClustering.Clusters[i].GlobalNoOfCells); } #endif // Saving time steps in subgrids //this.saveToDBCallback = saveToDBCallback; }
/// <summary> /// Constructor for (A)LTS with IBM /// </summary> public AdamsBashforthLTS(SpatialOperator spatialOp, CoordinateMapping Fieldsmap, CoordinateMapping Parameters, int order, int numOfClusters, bool IBM, IList <TimeStepConstraint> timeStepConstraints = null, SubGrid subGrid = null, bool fluxCorrection = true, int reclusteringInterval = 0, bool forceReclustering = false, bool logging = false, bool consoleOutput = false) : base(spatialOp, Fieldsmap, Parameters, order, timeStepConstraints, subGrid) { this.forceReclustering = forceReclustering; this.Logging = logging; this.ConsoleOutput = consoleOutput; this.gridData = Fieldsmap.Fields.First().GridDat; this.fluxCorrection = fluxCorrection; if (reclusteringInterval != 0) { NumberOfClustersInitial = numOfClusters; this.adaptive = true; } this.reclusteringInterval = reclusteringInterval; // Add OnBeforeComputeChangeRate (AV) to start-up phase time stepper RungeKuttaScheme.OnBeforeComputeChangeRate += (t1, t2) => this.RaiseOnBeforeComputechangeRate(t1, t2); }
/// <summary> /// /// </summary> /// <param name="spatialOp"></param> /// <param name="fields"></param> /// <param name="matrix"></param> /// <param name="affineOffset"></param> /// <param name="OnlyAffine"> /// if true, only the <paramref name="affineOffset"/> /// is computed and <paramref name="matrix"/> is null on exit. /// </param> public static void ComputeMatrix(SpatialOperator spatialOp, CoordinateMapping fields, bool OnlyAffine, out MsrMatrix matrix, out double[] affineOffset) { // Check operator and arguments if (!spatialOp.IsCommited) { throw new ArgumentException("operator must be committed first.", "spatialOp"); } if (spatialOp.ContainsNonlinear) { throw new ArgumentException("spatial differential operator cannot contain nonlinear components for implicit euler.", "spatialOp"); } if (!spatialOp.ContainsLinear()) { throw new ArgumentException("spatial differential operator seems to contain no components.", "spatialOp"); } if (spatialOp.DomainVar.Count != spatialOp.CodomainVar.Count) { throw new ArgumentException("spatial differential operator must have the same number of domain and codomain variables.", "spatialOp"); } if (fields.Fields.Count != spatialOp.CodomainVar.Count) { throw new ArgumentException("the number of fields in the coordinate mapping must be equal to the number of domain/codomain variables of the spatial differential operator", "fields"); } // Assemble matrix and affine offset IPartitioning matrixPartition = fields; if (!OnlyAffine) { matrix = new MsrMatrix(matrixPartition); } else { matrix = null; } affineOffset = new double[fields.LocalLength]; spatialOp.ComputeMatrixEx( fields, null, fields, matrix, affineOffset, OnlyAffine); }
////################# Hack for saving to database in every (A)LTS sub-step //private Action<TimestepNumber, double> saveToDBCallback; ////################# Hack for saving to database in every (A)LTS sub-step /// <summary> /// Standard constructor for the (adaptive) local time stepping algorithm /// </summary> /// <param name="spatialOp">Spatial operator</param> /// <param name="Fieldsmap">Coordinate mapping for the variable fields</param> /// <param name="Parameters">optional parameter fields, can be null if <paramref name="spatialOp"/> contains no parameters; must match the parameter field list of <paramref name="spatialOp"/>, see <see cref="BoSSS.Foundation.SpatialOperator.ParameterVar"/></param> /// <param name="order">LTS/AB order</param> /// <param name="numOfClusters">Amount of sub-grids/clusters to be used for LTS</param> /// <param name="timeStepConstraints">Time step constraints for later usage as metric</param> /// <param name="subGrid">Sub-grids, e.g., from previous time steps</param> /// <param name="fluxCorrection">Bool for triggering the fluss correction</param> /// <param name="reclusteringInterval">Interval for potential reclustering</param> /// <param name="saveToDBCallback">Hack for plotting all sub-steps</param> /// <remarks>Uses the k-Mean clustering, see <see cref="BoSSS.Solution.Utils.Kmeans"/>, to generate the element groups</remarks> public AdamsBashforthLTS(SpatialOperator spatialOp, CoordinateMapping Fieldsmap, CoordinateMapping Parameters, int order, int numOfClusters, IList <TimeStepConstraint> timeStepConstraints = null, SubGrid subGrid = null, bool fluxCorrection = true, int reclusteringInterval = 0, Action <TimestepNumber, double> saveToDBCallback = null, int maxNumOfSubSteps = 0, bool forceReclustering = false, bool logging = false, bool consoleOutput = false) : base(spatialOp, Fieldsmap, Parameters, order, timeStepConstraints, subGrid) { this.forceReclustering = forceReclustering; this.Logging = logging; this.ConsoleOutput = consoleOutput; if (reclusteringInterval != 0) { NumberOfClustersInitial = numOfClusters; this.adaptive = true; } // Add OnBeforeComputeChangeRate (AV) to start-up phase time stepper RungeKuttaScheme.OnBeforeComputeChangeRate += (t1, t2) => this.RaiseOnBeforeComputechangeRate(t1, t2); this.reclusteringInterval = reclusteringInterval; this.gridData = Fieldsmap.Fields.First().GridDat; this.fluxCorrection = fluxCorrection; if (ConsoleOutput) { Console.WriteLine("### This is ABLTS ctor ###"); } clusterer = new Clusterer(this.gridData, maxNumOfSubSteps); CurrentClustering = clusterer.CreateClustering(numOfClusters, this.TimeStepConstraints, this.SubGrid); // Might remove clusters when their centres are too close CurrentClustering = clusterer.TuneClustering(CurrentClustering, Time, this.TimeStepConstraints); // Might remove clusters when their time step sizes are too similar ABevolver = new ABevolve[CurrentClustering.NumberOfClusters]; for (int i = 0; i < ABevolver.Length; i++) { ABevolver[i] = new ABevolve(spatialOp, Fieldsmap, Parameters, order, adaptive: this.adaptive, sgrd: CurrentClustering.Clusters[i]); ABevolver[i].OnBeforeComputeChangeRate += (t1, t2) => this.RaiseOnBeforeComputechangeRate(t1, t2); } GetBoundaryTopology(); // Saving time steps in subgrids //this.saveToDBCallback = saveToDBCallback; }
public ExplicitConvection(Context context, string variablename, SubGrid subgrid, int basisdegree , SubgridCoordinateMapping v) { m_Context = context; name = variablename; convectionop = new SpatialOperator(1, 3, 1, name, "u", "v", "w"); convectionop.EquationComponents["Density"].Add(new SurfaceConvectionUpwinding(new string[] { "u", "v", "w" }, subgrid, new string[] { name }, 0)); convectionop.Commit(); CreepingFlowFactory fact = new CreepingFlowFactory(m_Context, basisdegree); fact.CreateFlowFields(out creepingFlow); Partition part = new Partition(v.NUpdate); double[] affine = new double[v.NUpdate]; MsrMatrix opmatr = new MsrMatrix(part, v.MaxTotalNoOfCoordinatesPerCell * (int)m_Context.GridDat.GlobalNoOfCells); convectionop.ComputeMatrixEx(m_Context, v, new Field[] { creepingFlow[0], creepingFlow[1], creepingFlow[2] }, v, opmatr, affine, false, subgrid); v.SetupSubmatrix(affine, opmatr, out SubgridAffine, out SubgridOperatorMatr); }
public void Evaluate2(SubGrid S, SinglePhaseField inp_LevSet, SinglePhaseField outp_Result) { var Op = new SpatialOperator(1, 0, 1, QuadOrderFunc.Linear(), "Phi", "c1"); Op.EquationComponents["c1"].Add(new JumpForm()); //Op.EquationComponents["c1"].Add(new GradientJumpForm() { BTerm = true }); Op.EquationComponents["c1"].Add(new GradientJumpForm2()); Op.Commit(); var inp_LevSet_Mapping = inp_LevSet.Mapping; var outp_Result_Mapping = outp_Result.Mapping; Op.Evaluate(1.0, 1.0, inp_LevSet_Mapping, new DGField[0], outp_Result_Mapping);//, //qInsEdge: new EdgeQuadratureScheme(true, S.InnerEdgesMask), //qInsVol: new CellQuadratureScheme(true, CellMask.GetEmptyMask(S._GridData)), //bndMode: SpatialOperator.SubGridBoundaryModes.InnerEdge, //sgrd: S); }
/// <summary> /// /// </summary> protected override void CreateEquationsAndSolvers() { SpatialOperator diffOp = new SpatialOperator(1, 0, 1, "u", "codom1"); switch (base.GridDat.Grid.SpatialDimension) { case 2: diffOp.EquationComponents["codom1"].Add(new ScalarTransportFlux()); break; case 3: diffOp.EquationComponents["codom1"].Add(new ScalarTransportFlux3D()); break; default: throw new NotImplementedException("spatial dim. not supported."); } diffOp.Commit(); eEule = new RungeKutta( RungeKutta.RungeKuttaScheme.TVD3, diffOp, new CoordinateMapping(u), null); }
/// <summary> /// accumulates /// <paramref name="alpha"/>*<paramref name="f"/>(<paramref name="U"/>) /// to this field; /// </summary> /// <param name="alpha">scaling</param> /// <param name="f"> /// some function /// - 1st argument: position in physical space /// - 2nd argument: values of fields in <paramref name="U"/> at respective position /// - 3rd argument: cell index /// - return value: value of function that should be projected at the respective position /// </param> /// <param name="cqs"> /// cell quadrature scheme: domain and quadrature rule /// </param> /// <param name="U"> /// arguments for <paramref name="f"/> /// </param> public void ProjectFunction(double alpha, Func <Vector, double[], int, double> f, CellQuadratureScheme cqs, params DGField[] U) { string[] Dom = new string[U.Length]; for (int i = 0; i < Dom.Length; i++) { Dom[i] = "_" + i; } string[] Cod = new string[] { "res" }; SpatialOperator src = new SpatialOperator(Dom, Cod, QuadOrderFunc.NonLinear(3)); src.EquationComponents[Cod[0]].Add(new ProjectFunctionSource(Dom, f)); src.EdgeQuadraturSchemeProvider = g => new EdgeQuadratureScheme(false, EdgeMask.GetEmptyMask(this.Basis.GridDat)); src.VolumeQuadraturSchemeProvider = g => cqs; src.Commit(); var ev = src.GetEvaluatorEx( new CoordinateMapping(U), null, this.Mapping); ev.Evaluate(alpha, 1.0, this.CoordinateVector); }
/// <summary> /// creates the spatial operator that consists only of component <paramref name="c"/> /// </summary> public static SpatialOperator Operator(this IEquationComponent c, Func <int[], int[], int[], int> quadOrderFunc, Func <IGridData, EdgeQuadratureScheme> edgeSchemeProvider = null, Func <IGridData, CellQuadratureScheme> cellSchemeProvider = null) { string[] Codomain = new string[] { "v1" }; string[] Domain = c.ArgumentOrdering.ToArray(); string[] Param = (c.ParameterOrdering != null) ? c.ParameterOrdering.ToArray() : new string[0]; SpatialOperator ret = new SpatialOperator(Domain, Param, Codomain, quadOrderFunc); if (edgeSchemeProvider != null) { ret.EdgeQuadraturSchemeProvider = edgeSchemeProvider; } if (cellSchemeProvider != null) { ret.VolumeQuadraturSchemeProvider = cellSchemeProvider; } ret.EquationComponents[Codomain[0]].Add(c); ret.Commit(); return(ret); }
SpatialOperator CreateAdvectionSpatialOperator(IncompressibleBoundaryCondMap bcMap) { Func <int[], int[], int[], int> QuadOrderFunction = QuadOrderFunc.SumOfMaxDegrees(); string[] parameterList; parameterList = ArrayTools.Cat( VariableNames.Velocity0Vector(D), VariableNames.Velocity0MeanVector(D), "div(U)"); SpatialOperator SO = new SpatialOperator(new string[] { "LevelSet" }, parameterList, new string[] { "Phi-Evo" }, QuadOrderFunc.NonLinear(2)); //div(u*phi) SO.EquationComponents["Phi-Evo"].Add(new LevelSetLLFFlux(GridDat, bcMap)); //-phi*div(u) SO.EquationComponents["Phi-Evo"].Add(new FextSource()); SO.Commit(); return(SO); }
/// <summary> /// Creating the time integrated DG-FEM discretization of the level set advection equation /// </summary> /// <param name="LevelSet"></param> /// <param name="ExtensionVelocity"></param> /// <param name="e"></param> void CreateAdvectionSpatialOperator(SinglePhaseField LevelSet, SinglePhaseField ExtensionVelocity, ExplicitEuler.ChangeRateCallback e, SubGrid subGrid) { SpatialOperator SO; Func <int[], int[], int[], int> QuadOrderFunction = QuadOrderFunc.Linear(); int D = LevelSet.GridDat.SpatialDimension; //FieldFactory<SinglePhaseField> fac = new FieldFactory<SinglePhaseField>(SinglePhaseField.Factory); //VectorField<SinglePhaseField> LevelSetGradient = new VectorField<SinglePhaseField>(D, // LevelSet.Basis,fac); SO = new SpatialOperator(1, 1, 1, QuadOrderFunction, new string[] { "LS", "S", "Result" }); double PenaltyBase = ((double)((LevelSet.Basis.Degree + 1) * (LevelSet.Basis.Degree + D))) / ((double)D); SO.EquationComponents["Result"].Add(new ScalarVelocityAdvectionFlux(GridDat, PenaltyBase)); SO.Commit(); this.TimeIntegrator = new RungeKutta(RungeKuttaScheme.ExplicitEuler, SO, new CoordinateMapping(LevelSet), new CoordinateMapping(ExtensionVelocity), subGrid); // Performing the task e if (e != null) { this.TimeIntegrator.OnBeforeComputeChangeRate += e; } }
/// <summary> /// Accumulates the DG-projection (with respect to the DG-basis /// of this field, <see cref="Basis"/>) of /// <paramref name="alpha"/>*<paramref name="f"/>^<paramref name="pow"/> to this field; /// </summary> /// <param name="alpha">scaling for accumulation</param> /// <param name="f">operand</param> /// <param name="pow">exponent</param> /// <param name="em"> /// An optional restriction to the domain in which the projection is /// computed (it may, e.g. be only required in boundary cells, so a /// computation over the whole domain would be a waste of computation /// power. A proper execution mask would be see e.g. /// <see cref="GridData.BoundaryCells"/>.) /// if null, the computation is carried out in the whole domain; /// </param> virtual public void ProjectPow(double alpha, DGField f, double pow, CellMask em) { if (!object.ReferenceEquals(f.Basis.GridDat, this.Basis.GridDat)) { throw new ArgumentException("field is associated to another context.", "a"); } SpatialOperator powOp = new SpatialOperator(new string[] { "f" }, new string[] { "res" }, QuadOrderFunc.SumOfMaxDegrees()); powOp.EquationComponents["res"].Add(new PowSource(pow)); powOp.Commit(); CoordinateVector coDom = this.CoordinateVector; var ev = powOp.GetEvaluatorEx( new CoordinateMapping(f), null, coDom.Mapping, edgeQrCtx: new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(this.Basis.GridDat)), volQrCtx: new CellQuadratureScheme(true, em)); ev.Evaluate <CoordinateVector>(alpha, 1.0, coDom); // only sources, no edge integrals required }
unsafe public static void Laplacian(ref int GridRef, ref int DgDegree, out int ierr) { try { // grid, etc // ========= GridData grd = null;// (GridData)(Infrastructure.GetObject(GridRef)); var b = new Basis(grd, DgDegree); var map = new UnsetteledCoordinateMapping(b); var L = new Laplace(1.3, grd.Cells.cj); var op = new SpatialOperator(1, 0, 1, QuadOrderFunc.Linear(), "T", "c1"); op.EquationComponents["c1"].Add(L); op.Commit(); // evaluate operator // ================= var Mtx = new BlockMsrMatrix(map, map); double[] B = new double[map.LocalLength]; var eval = op.GetMatrixBuilder(map, null, map); eval.ComputeMatrix(Mtx, B); // return data // =========== throw new NotImplementedException("todo"); } catch (Exception e) { ierr = Infrastructure.ErrorHandler(e); } ierr = 0; }
public static SpatialOperator BuildEulerOperator(IGridData gridData, CompressibleControl control) { // Boundary condition map Material material = control.GetMaterial(); IBoundaryConditionMap boundaryMap = new CompressibleBoundaryCondMap(gridData, control, material); // Initialize operator SpatialOperator EulerOperator = new SpatialOperator( new string[] { CompressibleVariables.Density, CompressibleVariables.Momentum.xComponent, CompressibleVariables.Momentum.yComponent, CompressibleVariables.Energy }, new string[] { }, new string[] { CompressibleVariables.Density, CompressibleVariables.Momentum.xComponent, CompressibleVariables.Momentum.yComponent, CompressibleVariables.Energy }, QuadOrderFunc.NonLinearWithoutParameters(2) ); // Map fluxes EulerOperator.EquationComponents[CompressibleVariables.Density].Add(new OptimizedHLLCDensityFlux(boundaryMap, material)); EulerOperator.EquationComponents[CompressibleVariables.Momentum.xComponent].Add(new OptimizedHLLCMomentumFlux(boundaryMap, 0, material)); EulerOperator.EquationComponents[CompressibleVariables.Momentum.yComponent].Add(new OptimizedHLLCMomentumFlux(boundaryMap, 1, material)); EulerOperator.EquationComponents[CompressibleVariables.Energy].Add(new OptimizedHLLCEnergyFlux(boundaryMap, material)); EulerOperator.Commit(); return(EulerOperator); }
/// <summary> /// Adams-Bashforth Constructor /// </summary> /// <param name="spatialOp">Spatial operator</param> /// <param name="Fieldsmap"></param> /// <param name="Parameters"> /// optional parameter fields, can be null if /// <paramref name="spatialOp"/> contains no parameters; must match the /// parameter field list of <paramref name="spatialOp"/>, see /// <see cref="BoSSS.Foundation.SpatialOperator.ParameterVar"/> /// </param> /// <param name="order">Adams-Bashforth order</param> /// <param name="timeStepConstraints"> /// optional list of time step constraints <see cref="TimeStepConstraint"/> /// </param> /// <param name="sgrd"> /// optional restriction to computational domain /// </param> public AdamsBashforth(SpatialOperator spatialOp, CoordinateMapping Fieldsmap, CoordinateMapping Parameters, int order, IList <TimeStepConstraint> timeStepConstraints = null, SubGrid sgrd = null) : base(spatialOp, Fieldsmap, Parameters, SubGridBoundaryModes.InnerEdgeLTS, timeStepConstraints, sgrd) { if (order > 3 || order == 0) { throw new ArgumentException("Order not supported. Order must be between 1 and 3, but was " + order, "order"); } this.order = order; HistoryChangeRate = new Queue <double[]>(order); RungeKuttaScheme = new RungeKutta( RungeKutta.SchemeFactory(RungeKutta.GetDefaultScheme(order)), spatialOp, Fieldsmap, Parameters, timeStepConstraints, sgrd); CurrentChangeRate = new double[Mapping.LocalLength]; CompleteChangeRate = new double[Mapping.LocalLength]; HistoryTime = new Queue <double>(order); ABCoefficients = new double[order]; }
/// <summary> /// Includes assembly of the matrix. /// </summary> /// <param name="L"></param> protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { using (FuncTrace tr = new FuncTrace()) { // create operator // =============== { double D = this.GridData.SpatialDimension; double penalty_base = (T.Basis.Degree + 1) * (T.Basis.Degree + D) / D; double penalty_factor = base.Control.penalty_poisson; BoundaryCondMap <BoundaryType> PoissonBcMap = new BoundaryCondMap <BoundaryType>(this.GridData, this.Control.BoundaryValues, "T"); LapaceIp = new SpatialOperator(1, 1, QuadOrderFunc.SumOfMaxDegrees(), "T", "T"); MultidimensionalArray LengthScales; if (this.GridData is GridData) { LengthScales = ((GridData)GridData).Cells.cj; } else if (this.GridData is AggregationGridData) { LengthScales = ((AggregationGridData)GridData).AncestorGrid.Cells.cj; } else { throw new NotImplementedException(); } var flux = new ipFlux(penalty_base * base.Control.penalty_poisson, LengthScales, PoissonBcMap); LapaceIp.EquationComponents["T"].Add(flux); LapaceIp.Commit(); } } }
/// <summary> /// See <see cref="ImplicitTimeStepper"/> /// </summary> public CrankNicolson(ISparseSolverExt solver, bool[] temporalOp, SpatialOperator spatialOp, params DGField[] fields) : this(solver, temporalOp, spatialOp, new CoordinateMapping(fields)) { }
/// <summary> /// See <see cref="ImplicitTimeStepper"/> /// </summary> public CrankNicolson(ISparseSolverExt solver, SpatialOperator spatialOp, params DGField[] fields) : this(solver, AllTrue(fields.Length), spatialOp, fields) { }
/// <summary> /// See <see cref="ImplicitTimeStepper"/> /// </summary> public CrankNicolson(ISparseSolverExt solver, bool[] temporalOp, SpatialOperator spatialOp, CoordinateMapping fields) : base(solver, temporalOp, spatialOp, fields) { }
/// <summary> /// See <see cref="ImplicitTimeStepper"/> /// </summary> public CrankNicolson(ISparseSolverExt solver, SpatialOperator spatialOp, CoordinateMapping fields) : this(solver, AllTrue(fields.Fields.Count), spatialOp, fields) { }
/// <summary> /// /// </summary> /// <param name="DiffOp"></param> /// <param name="CoDomVarName"> /// the name of the variable in the codomain (<see cref="SpatialOperator.CodomainVar"/>-member /// of <paramref name="DiffOp"/>, for which this object should be defined; /// </param> /// <param name="_fieldList"> /// list of domain variable names /// </param> /// <param name="_fieldList2"> /// optional (i.e. can be null) /// list of parameter variable names; /// will be concatenated with <paramref name="_fieldList"/> /// </param> /// <param name="F">optional filter, can be null.</param> /// <param name="vectorizer"> /// Function for the vectorization of the evaluation of <paramref name="F"/> /// </param> internal EquationComponentArgMapping(SpatialOperator DiffOp, string CoDomVarName, IList <string> _fieldList, IList <string> _fieldList2, Func <T, bool> F, Func <IEquationComponent, IEquationComponent> vectorizer) { m_CoDomVarName = CoDomVarName; //m_DomainFields = DomainMapping.Fields; // ================= // concat field list // ================= IList <string> fieldList; if (_fieldList2 != null) { fieldList = Enumerable.Concat(_fieldList, _fieldList2).ToList(); } else { fieldList = _fieldList; } // ========================================= // collect all equation components of type T // ========================================= ICollection <IEquationComponent> eqCompS = DiffOp.EquationComponents[CoDomVarName]; List <T> AllComponentsofMyType = new List <T>(); foreach (IEquationComponent eqComp in eqCompS) { if (eqComp is T) { T _eqComp = (T)eqComp; if (F == null || F(_eqComp)) { AllComponentsofMyType.Add(_eqComp); } } else if (vectorizer != null) { IEquationComponent VeqComp = vectorizer(eqComp); if (VeqComp != null && VeqComp is T) { T _VeqComp = (T)VeqComp; if (F == null || F(_VeqComp)) { AllComponentsofMyType.Add(_VeqComp); } } } } m_AllComponentsOfMyType = AllComponentsofMyType.ToArray(); // ====================== // build argument mapping // ====================== int argMapMaxCount = 0; foreach (var w in m_AllComponentsOfMyType) { int c = w.ArgumentOrdering.Count; if (w.ParameterOrdering != null) { c += w.ParameterOrdering.Count; } argMapMaxCount = Math.Max(argMapMaxCount, c); } AllToSub = new int[m_AllComponentsOfMyType.Length, argMapMaxCount]; NoOfArguments = new int[m_AllComponentsOfMyType.Length]; NoOfParameters = new int[m_AllComponentsOfMyType.Length]; //ArrayTools.SetAll(AllToSub, int.MinValue); AllToSub.SetAll(int.MinValue); //IList<string> fieldList = DiffOp.DomainVar; for (int i = 0; i < AllToSub.GetLength(0); i++) { // arguments... IList <string> argMap = m_AllComponentsOfMyType[i].ArgumentOrdering; NoOfArguments[i] = argMap.Count; for (int j = 0; j < NoOfArguments[i]; j++) { int ifound = fieldList.IndexOf(argMap[j]); AllToSub[i, j] = ifound; Debug.Assert(AllToSub[i, j] >= 0); } // parameters... IList <string> paramMap = m_AllComponentsOfMyType[i].ParameterOrdering; if (paramMap != null) { NoOfParameters[i] = paramMap.Count; for (int j = 0; j < NoOfParameters[i]; j++) { AllToSub[i, j + NoOfArguments[i]] = fieldList.IndexOf(paramMap[j]); Debug.Assert(AllToSub[i, j + NoOfArguments[i]] >= 0); } } } }
/// <summary> /// Based on the Ideas by /// C. Basting and D. Kuzmin, /// “A minimization-based finite element formulation for interface-preserving level set reinitialization”, /// Computing, vol. 95, no. 1, pp. 13–25, Dec. 2012. /// Create Spatial Operators and build the corresponding Matrices /// For the Left-Hand Side of the ReInitProblem /// RHS is computed on the fly in <see cref="ReInitSingleStep"/> /// The Bulk component is constant unless the grid changes, thus it is computed in <see cref="BuildOperators(CellQuadratureScheme)"/>. /// The Interface component changes with its motion. /// This component is calculated in <see cref="UpdateOperators(CellQuadratureScheme)"/>. /// </summary> /// <param name="LSTrck"></param> /// <param name="Control">various parameters <paramref name="EllipticReinitControl"/></param> /// <param name="HMFOrder">order of tghe interface quadrature</param> public EllipticReInit(LevelSetTracker LSTrck, EllipticReInitAlgoControl Control, SinglePhaseField LevelSetForReInit = null) { this.Control = Control; this.LevelSetTracker = LSTrck; if (LevelSetForReInit == null) { Phi = LevelSetTracker.LevelSets[0] as SinglePhaseField; } else { Phi = LevelSetForReInit; } this.underrelaxation = Control.underrelaxation; Residual = new SinglePhaseField(Phi.Basis); OldPhi = new SinglePhaseField(Phi.Basis); NewPhi = new SinglePhaseField(Phi.Basis); foreach (SinglePhaseField f in new List <SinglePhaseField> { Residual, OldPhi, NewPhi }) { f.Clear(); f.Acc(1.0, Phi); } this.D = LevelSetTracker.GridDat.SpatialDimension; this.ConvergenceCriterion = Control.ConvergenceCriterion; this.MaxIteration = Control.MaxIt; double PenaltyBase = ((double)((Phi.Basis.Degree + 1) * (Phi.Basis.Degree + D))) / ((double)D); // Choose Forms according to Upwinding or Central Fluxes string[] paramNames; int noOfParamFields; IEquationComponent BulkForm; RHSForm myRHSForm; LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, "LevelSetGradient", SinglePhaseField.Factory); MeanLevelSetGradient = new VectorField <SinglePhaseField>(D, new Basis(Phi.GridDat, 0), "MeanLevelSetGradient", SinglePhaseField.Factory); if (Control.Upwinding) { paramNames = new string[] { "OldLevelSet", "MeanLevelSetGradient[0]", "MeanLevelSetGradient[1]" }; noOfParamFields = D; LevelSetGradient.Clear(); LevelSetGradient.Gradient(1.0, Phi); //LevelSetGradient.GradientByFlux(1.0, Phi); MeanLevelSetGradient.Clear(); MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient); parameterFields = ArrayTools.Cat(new SinglePhaseField[] { OldPhi }, MeanLevelSetGradient.ToArray()); //throw new NotImplementedException("ToDO"); BulkForm = new EllipticReInitUpwindForm_Laplace(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck); myRHSForm = new EllipticReInitUpwindForm_RHS(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck); OldDirection = new double[MeanLevelSetGradient.CoordinateVector.ToArray().Length]; for (int i = 0; i < MeanLevelSetGradient.CoordinateVector.Length; i++) { OldDirection[i] = Math.Sign(MeanLevelSetGradient.CoordinateVector[i]); } NewDirection = OldDirection.CloneAs(); } else { paramNames = new string[] { }; noOfParamFields = 0; parameterFields = new SinglePhaseField[] { }; BulkForm = new CentralDifferencesLHSForm(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck.GridDat.Cells.cj); myRHSForm = new CentralDifferencesRHSForm(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck); } // SIP for the bulk Phase //this.Operator_bulk = new SpatialOperator(1, noOfParamFields, 1, QuadOrderFunc.SumOfMaxDegrees(1, RoundUp: false), variableNames); this.Operator_bulk = BulkForm.Operator(); // Zero at the Interface // Calculate Quadrature Order Func <int[], int[], int[], int> InterfaceQuadOrder; InterfaceQuadOrder = QuadOrderFunc.FixedOrder(Phi.Basis.Degree * 2 + 2); // Generate Interface Operator this.Operator_interface = (new EllipticReInitInterfaceForm(Control.PenaltyMultiplierInterface * PenaltyBase, LSTrck)).XOperator(new[] { "A" }, InterfaceQuadOrder); // Nonlinear Part on the RHS // switch for the potential functions switch (Control.Potential) { case ReInitPotential.BastingDoubleWell: { myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.DoubleWell(d, b)); break; }; case ReInitPotential.BastingSingleWell: { myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWell(d, b)); break; }; case ReInitPotential.SingleWellNear: { myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWellNear(d, b)); break; }; case ReInitPotential.P4DoubleWell: { Console.WriteLine("Warning - This Option for Elliptic ReInit does not work well"); myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.DoubleWellAlternative(d, b)); break; }; case ReInitPotential.SingleWellOnCutDoubleWellElse: { myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWellOnCutDoubleWellElse(d, b)); break; } } Operator_RHS = myRHSForm.Operator(QuadOrderFunc.SumOfMaxDegrees(2, RoundUp: true)); // The result of the nonlinear part on the rhs is projected on a single-phase field RHSField = new SinglePhaseField(Phi.Basis, "RHS"); OpMatrix = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping); OpAffine = new double[OpMatrix.RowPartitioning.LocalLength]; // Matrix and RHS for the Bulk component OpMatrix_bulk = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping); OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength]; // Matrix and RHS for the Interface Penalty OpMatrix_interface = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping); OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength]; // Init Parameter Fields OldPhi.Clear(); OldPhi.Acc(1.0, Phi); // Compute Matrices UpdateBulkMatrix(); }
/// <summary> /// <see cref="ResidualLogger"/> /// </summary> /// <param name="program"></param> /// <param name="residualInterval"> /// <see cref="ResidualLogger"/> /// </param> /// <param name="differentialOperator"> /// The spatial differential operator defining (the spatial part of) /// the system of equations that are solved. /// </param> public RigorousResidualLogger(Application <T> program, DGField[] consVars, CoordinateMapping paramMap, int residualInterval, SpatialOperator differentialOperator) : base(program.ResLogger, program.CurrentSessionInfo, consVars, residualInterval) { CoordinateMapping domainMapping = new CoordinateMapping(consVars); UnsetteledCoordinateMapping codomainMapping = new UnsetteledCoordinateMapping( consVars.Select((field) => field.Basis).ToArray()); evaluator = differentialOperator.GetEvaluatorEx( domainMapping, paramMap, codomainMapping); }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { using (FuncTrace tr = new FuncTrace()) { this.BcMap = new IncompressibleBoundaryCondMap(this.GridData, grid.GetBoundaryConfig(), PhysicsMode.Incompressible); // assemble system, create matrix // ------------------------------ int D = GridData.SpatialDimension; //double penalty_base = ((double)((U[0].Basis.Degree + 1) * (U[0].Basis.Degree + D))) / ((double)D); double penalty_base = 1.0; double penalty_factor = 1.2; // equation assembly // ----------------- string[] CodNames = D.ForLoop(i => "C" + i); Operator = new SpatialOperator(VariableNames.VelocityVector(D), new string[] { VariableNames.ViscosityMolecular }, CodNames, QuadOrderFunc.Linear()); for (int d = 0; d < D; d++) { if ((this.whichTerms & Terms.T1) != 0) { var flx1 = new swipViscosity_Term1(penalty_base * penalty_factor, d, D, BcMap, ViscosityOption.VariableViscosity); flx1.g_Diri_Override = this.solution.U; flx1.g_Neu_Override = this.solution.dU; Operator.EquationComponents[CodNames[d]].Add(flx1); } if ((this.whichTerms & Terms.T2) != 0) { var flx2 = new swipViscosity_Term2(penalty_base * penalty_factor, d, D, BcMap, ViscosityOption.VariableViscosity); flx2.g_Diri_Override = this.solution.U; flx2.g_Neu_Override = this.solution.dU; Operator.EquationComponents[CodNames[d]].Add(flx2); } if ((this.whichTerms & Terms.T3) != 0) { var flx3 = new swipViscosity_Term3(penalty_base * penalty_factor, d, D, BcMap, ViscosityOption.VariableViscosity); flx3.g_Diri_Override = this.solution.U; flx3.g_Neu_Override = this.solution.dU; Operator.EquationComponents[CodNames[d]].Add(flx3); } } // */ Operator.Commit(); var map = this.U.Mapping; OperatorMtx = new MsrMatrix(map, map); Operator.ComputeMatrixEx(map, new DGField[] { this.mu }, map, OperatorMtx, this.bnd.CoordinateVector, volQuadScheme: null, edgeQuadScheme: null); // test for matrix symmetry // ======================== if (base.MPISize == 1) { double MatrixAssymmetry = OperatorMtx.SymmetryDeviation(); Console.WriteLine("Matrix asymmetry: " + MatrixAssymmetry); Assert.LessOrEqual(Math.Abs(MatrixAssymmetry), 1.0e-10); } } }
/// <summary> /// /// </summary> /// <param name="spatialOp"></param> /// <param name="Fieldsmap"></param> /// <param name="Parameters"></param> /// <param name="timeStepConstraints"> /// optional list of time step constraints <see cref="TimeStepConstraint"/> /// </param> /// <param name="sgrd"></param> /// <remarks> /// This constructor sets /// <see cref="SubGridBoundaryModes"/> to default value /// BoundaryEdge /// </remarks> public ExplicitEuler(SpatialOperator spatialOp, CoordinateMapping Fieldsmap, CoordinateMapping Parameters, IList <TimeStepConstraint> timeStepConstraints = null, SubGrid sgrd = null) : this(spatialOp, Fieldsmap, Parameters, SubGridBoundaryModes.BoundaryEdge, timeStepConstraints, sgrd) { }
/// <summary> /// /// </summary> /// <param name="spatialOp"></param> /// <param name="Fields"></param> /// <remarks> /// This constructor does not support parameter fields; /// </remarks> public ExplicitEuler(SpatialOperator spatialOp, params DGField[] Fields) : this(spatialOp, new CoordinateMapping(Fields), null) { }
/// <summary> /// Obtaining the time integrated spatial discretization of the reinitialization equation in a narrow band around the zero level set, based on a Godunov's numerical Hamiltonian calculation /// </summary> /// <param name="LS"> The level set function </param> /// <param name="Restriction"> The narrow band around the zero level set </param> /// <param name="NumberOfTimesteps"> /// maximum number of pseudo-timesteps /// </param> /// <param name="thickness"> /// The smoothing width of the signum function. /// This is the main stabilization parameter for re-initialization. /// It should be set to approximately 3 cells. /// </param> /// <param name="TimestepSize"> /// size of the pseudo-timestep /// </param> public void ReInitialize(LevelSet LS, SubGrid Restriction, double thickness, double TimestepSize, int NumberOfTimesteps) { using (var tr = new FuncTrace()) { // log parameters: tr.Info("thickness: " + thickness.ToString(NumberFormatInfo.InvariantInfo)); tr.Info("TimestepSize: " + TimestepSize.ToString(NumberFormatInfo.InvariantInfo)); tr.Info("NumberOfTimesteps: " + NumberOfTimesteps); ExplicitEuler TimeIntegrator; SpatialOperator SO; Func <int[], int[], int[], int> QuadratureOrder = QuadOrderFunc.NonLinear(3); if (m_ctx.SpatialDimension == 2) { SO = new SpatialOperator(1, 5, 1, QuadratureOrder, new string[] { "LS", "LSCGV", "LSDG[0]", "LSUG[0]", "LSDG[1]", "LSUG[1]", "Result" }); SO.EquationComponents["Result"].Add(new GodunovHamiltonian(m_ctx, thickness)); SO.Commit(); TimeIntegrator = new RungeKutta(m_Scheme, SO, new CoordinateMapping(LS), new CoordinateMapping(LSCGV, LSDG[0], LSUG[0], LSDG[1], LSUG[1]), sgrd: Restriction); } else { SO = new SpatialOperator(1, 7, 1, QuadratureOrder, new string[] { "LS", "LSCGV", "LSDG[0]", "LSUG[0]", "LSDG[1]", "LSUG[1]", "LSDG[2]", "LSUG[2]", "Result" }); SO.EquationComponents["Result"].Add(new GodunovHamiltonian(m_ctx, thickness)); SO.Commit(); TimeIntegrator = new RungeKutta(m_Scheme, SO, new CoordinateMapping(LS), new CoordinateMapping(LSCGV, LSDG[0], LSUG[0], LSDG[1], LSUG[1], LSDG[2], LSUG[2]), sgrd: Restriction); } // Calculating the gradients in each sub-stage of a Runge-Kutta integration procedure ExplicitEuler.ChangeRateCallback EvalGradients = delegate(double t1, double t2) { LSUG.Clear(); CalculateLevelSetGradient(LS, LSUG, "Upwind", Restriction); LSDG.Clear(); CalculateLevelSetGradient(LS, LSDG, "Downwind", Restriction); LSCG.Clear(); CalculateLevelSetGradient(LS, LSCG, "Central", Restriction); LSCGV.Clear(); var VolMask = (Restriction != null) ? Restriction.VolumeMask : null; LSCGV.ProjectAbs(1.0, VolMask, LSCG.ToArray()); }; TimeIntegrator.OnBeforeComputeChangeRate += EvalGradients; { EvalGradients(0, 0); var GodunovResi = new SinglePhaseField(LS.Basis, "Residual"); SO.Evaluate(1.0, 0.0, LS.Mapping, TimeIntegrator.ParameterMapping.Fields, GodunovResi.Mapping, Restriction); //Tecplot.Tecplot.PlotFields(ArrayTools.Cat<DGField>( LSUG, LSDG, LS, GodunovResi), "Residual", 0, 3); } // pseudo-timestepping // =================== double factor = 1.0; double time = 0; LevelSet prevLevSet = new LevelSet(LS.Basis, "prevLevSet"); CellMask RestrictionMask = (Restriction == null) ? null : Restriction.VolumeMask; for (int i = 0; (i < NumberOfTimesteps); i++) { tr.Info("Level set reinitialization pseudo-timestepping, timestep " + i); // backup old Levelset // ------------------- prevLevSet.Clear(); prevLevSet.Acc(1.0, LS, RestrictionMask); // time integration // ---------------- double dt = TimestepSize * factor; tr.Info("dt = " + dt.ToString(NumberFormatInfo.InvariantInfo) + " (factor = " + factor.ToString(NumberFormatInfo.InvariantInfo) + ")"); TimeIntegrator.Perform(dt); time += dt; // change norm // ------ prevLevSet.Acc(-1.0, LS, RestrictionMask); double ChangeNorm = prevLevSet.L2Norm(RestrictionMask); Console.WriteLine("Reinit: PseudoTime: {0} - Changenorm: {1}", i, ChangeNorm); //Tecplot.Tecplot.PlotFields(new SinglePhaseField[] { LS }, m_ctx, "Reinit-" + i, "Reinit-" + i, i, 3); } //*/ } }