/// <summary> /// accumulates the projection of some vector field to this field, i.e. /// \f[ /// this = this + \alpha \cdot \| \vec{vec} \|. /// \f] /// </summary> /// <param name="alpha">factor \f$ \alpha \f$ </param> /// <param name="vec">vector field \f$ \vec{vec} \f$ </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. If null, the computation is carried out in the whole domain; /// </param> virtual public void ProjectAbs(double alpha, CellMask em, params DGField[] vec) { int K = vec.Length; string[] args = new string[K]; for (int k = 0; k < K; k++) { args[k] = "_" + k; } SpatialOperator powOp = new SpatialOperator(args, new string[] { "res" }, QuadOrderFunc.SumOfMaxDegrees()); powOp.EquationComponents["res"].Add(new AbsSource(args)); powOp.EdgeQuadraturSchemeProvider = g => new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(this.Basis.GridDat)); powOp.VolumeQuadraturSchemeProvider = g => new CellQuadratureScheme(true, em); powOp.Commit(); CoordinateVector coDom = new CoordinateVector(this); var ev = powOp.GetEvaluatorEx( new CoordinateMapping(vec), null, coDom.Mapping); ev.Evaluate <CoordinateVector>(alpha, 1.0, coDom); // only sources, no edge integrals required }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { using (FuncTrace tr = new FuncTrace()) { // assemble system, create matrix // ------------------------------ var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData)); var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData)); double D = this.GridData.SpatialDimension; double penalty_base = (T.Basis.Degree + 1) * (T.Basis.Degree + D) / D; double penalty_factor = base.Control.penalty_poisson; { // equation assembly // ----------------- tr.Info("creating sparse system..."); Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal); Stopwatch stw = new Stopwatch(); stw.Start(); SpatialOperator LapaceIp = new SpatialOperator(1, 1, QuadOrderFunc.SumOfMaxDegrees(), "T", "T"); var flux = new ipFlux(penalty_base * base.Control.penalty_poisson, this.GridData.Cells.cj, base.Control); LapaceIp.EquationComponents["T"].Add(flux); LapaceIp.Commit(); #if DEBUG var RefLaplaceMtx = new MsrMatrix(T.Mapping); #endif LaplaceMtx = new BlockMsrMatrix(T.Mapping); LaplaceAffine = new double[T.Mapping.LocalLength]; LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, LaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); #if DEBUG LaplaceAffine.ClearEntries(); LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, RefLaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); MsrMatrix ErrMtx = RefLaplaceMtx.CloneAs(); ErrMtx.Acc(-1.0, LaplaceMtx); double err = ErrMtx.InfNorm(); double infNrm = LaplaceMtx.InfNorm(); Console.WriteLine("Matrix comparison error: " + err + ", matrix norm is: " + infNrm); Assert.Less(err, infNrm * 1e-10, "MsrMatrix2 comparison failed."); #endif //int q = LaplaceMtx._GetTotalNoOfNonZeros(); //tr.Info("finished: Number of non-zeros: " + q); stw.Stop(); Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds); //double condNo = LaplaceMtx.condest(BatchmodeConnector.Flavor.Octave); //Console.WriteLine("condition number: {0:0.####E-00} ",condNo); } } }
/// <summary> /// accumulates the derivative of DG field <paramref name="f"/> /// (along the <paramref name="d"/>-th axis) times <paramref name="alpha"/> /// to this field, i.e. <br/> /// this = this + <paramref name="alpha"/>* \f$ \frac{\partial}{\partial x_d} \f$ <paramref name="f"/>; /// </summary> /// <param name="f"></param> /// <param name="d"> /// 0 for the x-derivative, 1 for the y-derivative, 2 for the /// z-derivative /// </param> /// <param name="alpha"> /// scaling of <paramref name="f"/>; /// </param> /// <param name="optionalSubGrid"> /// An optional restriction to the domain in which the derivative 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="bndMode"> /// if a sub-grid is provided, this determines how the sub-grid /// boundary should be treated. /// </param> /// <remarks> /// The derivative is calculated using Riemann flux functions /// (central difference);<br/> /// In comparison to /// <see cref="Derivative(double, DGField, int, CellMask)"/>, this method /// should be slower, but produce more sane results, especially for /// fields of low polynomial degree (0 or 1); /// </remarks> virtual public void DerivativeByFlux(double alpha, DGField f, int d, SubGrid optionalSubGrid = null, SubGridBoundaryModes bndMode = SubGridBoundaryModes.OpenBoundary) { int D = this.Basis.GridDat.SpatialDimension; if (d < 0 || d >= D) { throw new ArgumentException("spatial dimension out of range.", "d"); } MPICollectiveWatchDog.Watch(csMPI.Raw._COMM.WORLD); EdgeMask emEdge = (optionalSubGrid != null) ? optionalSubGrid.AllEdgesMask : null; CellMask emVol = (optionalSubGrid != null) ? optionalSubGrid.VolumeMask : null; SpatialOperator d_dx = new SpatialOperator(1, 1, QuadOrderFunc.Linear(), "in", "out"); d_dx.EdgeQuadraturSchemeProvider = g => new Quadrature.EdgeQuadratureScheme(true, emEdge); d_dx.VolumeQuadraturSchemeProvider = g => new Quadrature.CellQuadratureScheme(true, emVol); var flux = CreateDerivativeFlux(d, f.Identification); d_dx.EquationComponents["out"].Add(flux); d_dx.Commit(); var ev = d_dx.GetEvaluatorEx( new CoordinateMapping(f), null, this.Mapping); if (optionalSubGrid != null) { ev.ActivateSubgridBoundary(optionalSubGrid.VolumeMask, bndMode); } ev.Evaluate <CoordinateVector>(alpha, 1.0, this.CoordinateVector); }
/// <summary> /// Update of level-set gradient in 'upwind'-direction, i.e. at boundaries towards accepted cells, /// the outer value is taken. /// </summary> /// <param name="jCell">Cell index to update.</param> /// <param name="AcceptedMask"></param> /// <param name="Phi">Input: the level-set</param> /// <param name="gradPhi">Output: gradient of <paramref name="Phi"/> in cell <paramref name="jCell"/>.</param> public void GradientUpdate(int jCell, BitArray AcceptedMask, SinglePhaseField Phi, VectorField <SinglePhaseField> gradPhi) { var GridDat = Phi.GridDat; if (m_gradEvo == null || jCell != m_gradEvo_jCell) { var Sgrd = new SubGrid(new CellMask(GridDat, Chunk.GetSingleElementChunk(jCell))); SpatialOperator op = new SpatialOperator(1, 2, QuadOrderFunc.Linear(), "Phi", "g0", "g1"); op.EquationComponents["g0"].Add(new Gradient(0, jCell, AcceptedMask)); op.EquationComponents["g1"].Add(new Gradient(1, jCell, AcceptedMask)); op.EdgeQuadraturSchemeProvider = g => new EdgeQuadratureScheme(domain: Sgrd.AllEdgesMask); op.VolumeQuadraturSchemeProvider = g => new CellQuadratureScheme(domain: Sgrd.VolumeMask); op.Commit(); m_gradEvo = op.GetEvaluatorEx( Phi.Mapping, null, gradPhi.Mapping); m_gradEvo.ActivateSubgridBoundary(subGridBoundaryTreatment: SubGridBoundaryModes.BoundaryEdge, sgrd: Sgrd.VolumeMask); m_gradEvo_jCell = jCell; } foreach (var f in gradPhi) { f.Coordinates.ClearRow(jCell); } m_gradEvo.MPITtransceive = false; m_gradEvo.Evaluate(1.0, 1.0, gradPhi.CoordinateVector); }
/// <summary> /// /// </summary> protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { diffOp = new SpatialOperator(new string[] { "u" }, Solution.NSECommon.VariableNames.VelocityVector(this.GridData.SpatialDimension), new string[] { "codom1" }, QuadOrderFunc.Linear()); switch (this.GridData.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(); Timestepper = new RungeKutta(RungeKuttaScheme.TVD3, diffOp, new CoordinateMapping(u), Velocity.Mapping); //Timestepper = new ROCK4(diffOp, u.CoordinateVector, Velocity.Mapping); }
/// <summary> /// Spatial Operators and Matrices /// </summary> /// with /// <param name="bcMap">Boundary Conditions</param> public SpatialOperator CreateAdvectionSpatialOperator(IncompressibleBoundaryCondMap bcMap) { Func <int[], int[], int[], int> QuadOrderFunction = QuadOrderFunc.SumOfMaxDegrees(); string[] parameterList; parameterList = ArrayTools.Cat(VariableNames.Velocity0Vector(D), VariableNames.Velocity0MeanVector(D)); if (!divUzero) { parameterList = ArrayTools.Cat(parameterList, "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 LevelSetUpwindFlux(GridDat, bcMap)); SO.EquationComponents["Phi-Evo"].Add(new LevelSetLLFFlux(GridDat, bcMap)); //bcMap.PhysMode = PhysicsMode.Multiphase; //SO.EquationComponents["Phi-Evo"].Add(new LinearizedScalarConvection(D, bcMap,null)); //SO.EquationComponents["Phi-Evo"].Add(new LevelSetAdvectionCentralFlux(D)); //-phi*div(u) if (!divUzero) { SO.EquationComponents["Phi-Evo"].Add(new FextSource()); } //penalization //Lsevo.EquationComponents["Phi-Evo"].Add(new JumpPenalization.GradientJumpForm2()); SO.Commit(); return(SO); }
/// <summary> /// Calculating the level set gradient using the specified scheme in a narrow band around the zero level set, therein the calculions are performed /// </summary> /// <param name="LS"> The level set function </param> /// <param name="LSG"> Gradient of the level set function </param> /// <param name="f"> Specifying the method of flux calculation </param> /// <param name="Restriction"> The narrow band around the zero level set wherein the calculations are performed </param> void CalculateLevelSetGradient(LevelSet LS, VectorField <SinglePhaseField> LSG, string f, SubGrid Restriction) { SpatialOperator SO; CoordinateMapping CoDom; if (m_ctx.SpatialDimension == 2) { SO = new SpatialOperator(1, 2, QuadOrderFunc.Linear(), new string[] { "LS", "LSG[0]", "LSG[1]" }); SO.EquationComponents["LSG[0]"].Add(CreateFlux(m_ctx, f, 0)); SO.EquationComponents["LSG[1]"].Add(CreateFlux(m_ctx, f, 1)); SO.Commit(); CoDom = new CoordinateMapping(LSG[0], LSG[1]); } else if (m_ctx.SpatialDimension == 3) { SO = new SpatialOperator(1, 3, QuadOrderFunc.Linear(), new string[] { "LS", "LSG[0]", "LSG[1]", "LSG[2]" }); SO.EquationComponents["LSG[0]"].Add(CreateFlux(m_ctx, f, 0)); SO.EquationComponents["LSG[1]"].Add(CreateFlux(m_ctx, f, 1)); SO.EquationComponents["LSG[2]"].Add(CreateFlux(m_ctx, f, 2)); SO.Commit(); CoDom = new CoordinateMapping(LSG[0], LSG[1], LSG[2]); } else { throw new NotSupportedException(); } SO.Evaluate(1.0, 0.0, LS.Mapping, null, CoDom, sgrd: Restriction, bndMode: SubGridBoundaryModes.OpenBoundary); }
/// <summary> /// /// </summary> public void GradientUpdate(SubGrid Sgrd, double[] PhiMean, SinglePhaseField Phi, VectorField <SinglePhaseField> gradPhi) { var GridDat = Phi.GridDat; gradPhi.Clear(Sgrd.VolumeMask); SpatialOperator op = new SpatialOperator(1, 2, QuadOrderFunc.Linear(), "Phi", "g0", "g1"); op.EquationComponents["g0"].Add(new Gradient2(0, PhiMean)); op.EquationComponents["g1"].Add(new Gradient2(1, PhiMean)); op.EdgeQuadraturSchemeProvider = g => (new EdgeQuadratureScheme(domain: Sgrd.AllEdgesMask)); op.VolumeQuadraturSchemeProvider = g => (new CellQuadratureScheme(domain: Sgrd.VolumeMask)); op.Commit(); var gradEvo = op.GetEvaluatorEx(Phi.Mapping, null, gradPhi.Mapping); gradEvo.ActivateSubgridBoundary(Sgrd.VolumeMask, SubGridBoundaryModes.BoundaryEdge); //Sgrd.VolumeMask.ToTxtFile("nar.csv", false); gradPhi.Clear(Sgrd.VolumeMask); gradEvo.time = 0.0; gradEvo.MPITtransceive = false; gradEvo.Evaluate(1.0, 0.0, gradPhi.CoordinateVector); //gradPhi.GradientByFlux(1.0, Phi, optionalSubGrid:Sgrd , bndMode: SubGridBoundaryModes.BoundaryEdge); }
/// <summary> /// /// </summary> public void GradientUpdate(SubGrid Sgrd, double[] PhiMean, SinglePhaseField Phi, VectorField <SinglePhaseField> gradPhi) { var GridDat = Phi.GridDat; gradPhi.Clear(Sgrd.VolumeMask); SpatialOperator op = new SpatialOperator(1, 2, QuadOrderFunc.Linear(), "Phi", "g0", "g1"); op.EquationComponents["g0"].Add(new Gradient2(0, PhiMean)); op.EquationComponents["g1"].Add(new Gradient2(1, PhiMean)); op.Commit(); var gradEvo = op.GetEvaluatorEx( Phi.Mapping, null, gradPhi.Mapping, edgeQrCtx: (new EdgeQuadratureScheme(domain: Sgrd.AllEdgesMask)), volQrCtx: (new CellQuadratureScheme(domain: Sgrd.VolumeMask)), subGridBoundaryTreatment: SpatialOperator.SubGridBoundaryModes.BoundaryEdge, sgrd: Sgrd); //Sgrd.VolumeMask.ToTxtFile("nar.csv", false); gradPhi.Clear(Sgrd.VolumeMask); gradEvo.Evaluate(1.0, 0.0, gradPhi.CoordinateVector, 0.0, MPIexchange: false); //gradPhi.GradientByFlux(1.0, Phi, optionalSubGrid:Sgrd , bndMode: SpatialOperator.SubGridBoundaryModes.BoundaryEdge); }
public void Laplacian(OpenFOAMGrid grid, int DgDegree) { // grid, etc // ========= GridData grd = grid.GridData; 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"); }
/// <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"); var flux = new ipFlux(penalty_base * base.Control.penalty_poisson, ((GridData)(this.GridData)).Cells.cj, PoissonBcMap); LapaceIp.EquationComponents["T"].Add(flux); LapaceIp.Commit(); } //double condNo = LaplaceMtx.condest(BatchmodeConnector.Flavor.Octave); //Console.WriteLine("condition number: {0:0.####E-00} ",condNo); } }
public void Init(MultigridOperator op) { int D = op.GridData.SpatialDimension; CodName = new string[] { "momX", "momY", "div", "constitutiveXX", "constitutiveXY", "constitutiveYY" }; Params = new string[] { "VelocityX_GradientX", "VelocityX_GradientY", "VelocityY_GradientX", "VelocityY_GradientY" }; DomName = new string[] { "VelocityX", "VelocityY", "Pressure", "StressXX", "StressXY", "StressYY" }; LocalOp = new SpatialOperator(DomName, Params, CodName, (A, B, C) => 4); LocalOp.EquationComponents["constitutiveXX"].Add(new LocalJacobiFlux() { m_component = 0, We = m_We }); LocalOp.EquationComponents["constitutiveXY"].Add(new LocalJacobiFlux() { m_component = 1, We = m_We }); LocalOp.EquationComponents["constitutiveYY"].Add(new LocalJacobiFlux() { m_component = 2, We = m_We }); LocalOp.Commit(); var U0 = ((BoSSS.Foundation.CoordinateMapping)op.Mapping.ProblemMapping).Fields.GetSubVector(0, 2); Basis U0Basis = new Basis(op.Mapping.GridData, 0); VectorField <SinglePhaseField> VelocityXGradient = new VectorField <SinglePhaseField>(D, U0Basis, "VelocityX_Gradient", SinglePhaseField.Factory); VectorField <SinglePhaseField> VelocityYGradient = new VectorField <SinglePhaseField>(D, U0Basis, "VelocityY_Gradient", SinglePhaseField.Factory); VelocityXGradient.Clear(); VelocityXGradient.GradientByFlux(1.0, U0[0]); VelocityYGradient.Clear(); VelocityYGradient.GradientByFlux(1.0, U0[1]); var Parameters = ArrayTools.Cat <DGField>(VelocityXGradient, VelocityYGradient); LocalMatrix = LocalOp.ComputeMatrix(op.BaseGridProblemMapping, Parameters, op.BaseGridProblemMapping); ConstEqIdx = op.Mapping.ProblemMapping.GetSubvectorIndices(true, 3, 4, 5); P = (BlockMsrMatrix)op.MassMatrix.Clone(); for (int i = ConstEqIdx[0]; i <= ConstEqIdx.Length; i++) { for (int j = ConstEqIdx[0]; j <= ConstEqIdx.Length; j++) { if (LocalMatrix[i, j] != 0) { P[i, j] = LocalMatrix[i, j]; } } } LocalMatrix.SaveToTextFileSparse("LocalMatrix"); op.MassMatrix.SaveToTextFileSparse("MassMatrix"); P.SaveToTextFileSparse("PrecondMatrix"); }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { diffOp = new SpatialOperator( new string[] { "c" }, new string[] { "viscosity", "VelocityX", "VelocityY" }, new string[] { "codom1" }, QuadOrderFunc.Linear()); diffOp.EquationComponents["codom1"].Add(new ScalarTransportFlux2D(inflowDirichletValue)); diffOp.Commit(); CoordinateMapping coordMap; coordMap = new CoordinateMapping(viscosity, Velocity[0], Velocity[1]); // 3 sub-grids MultidimensionalArray metricOne = MultidimensionalArray.Create(numOfCellsX); MultidimensionalArray metricTwo = MultidimensionalArray.Create(numOfCellsX); // 3 cells //metricOne[0] = 2; //metricOne[1] = 1; //metricOne[2] = 0.5; //metricTwo[0] = 1; //metricTwo[1] = 0.5; //metricTwo[2] = 2; // 4 cells metricOne[0] = 2; metricOne[1] = 1; metricOne[2] = 0.5; metricOne[3] = 0.25; metricTwo[0] = 0.5; metricTwo[1] = 2; metricTwo[2] = 0.25; metricTwo[3] = 1; CustomTimestepConstraint = new SurrogateConstraint(GridData, dtFixed, dtFixed, double.MaxValue, endTime, metricOne, metricTwo); timeStepper = new AdamsBashforthLTS( diffOp, new CoordinateMapping(c), coordMap, order: ABOrder, numOfClusters: this.numOfSubgrids, timeStepConstraints: new List <TimeStepConstraint>() { CustomTimestepConstraint }, fluxCorrection: false, reclusteringInterval: 1); // Sub-grid visualization //AdamsBashforthLTS timeStepper2 = timeStepper as AdamsBashforthLTS; //timeStepper2.SubGridField.Identification = "clusterLTS"; //m_IOFields.Add(timeStepper2.SubGridField); //timeStepper = timeStepper2; }
protected override SpatialOperator GetSpatialOperator(SolverConfiguration SolverConf, int SpatialComponent, int SpatialDirection) { SpatialOperator DivergenceOp = new SpatialOperator(new string[] { VariableNames.Velocity_d(SpatialComponent) }, new string[] { "div_d" }, QuadOrderFunc.Linear()); DivergenceOp.EquationComponents["div_d"].Add(new Divergence_DerivativeSource(SpatialComponent, SolverConf.SpatialDimension)); DivergenceOp.EquationComponents["div_d"].Add(new Divergence_DerivativeSource_Flux(SpatialComponent, SolverConf.BcMap)); DivergenceOp.Commit(); return(DivergenceOp); }
/// <summary> /// Creates a <see cref="SpatialOperator"/> with the equation /// components that have been assigned to this operator. /// </summary> /// <returns></returns> public SpatialOperator ToSpatialOperator(CNSFieldSet fieldSet) { SpatialOperator spatialOp = new SpatialOperator( CompressibleEnvironment.PrimalArgumentOrdering, GetParameterOrdering(fieldSet), CompressibleEnvironment.PrimalArgumentOrdering, QuadOrderFunc.NonLinearWithoutParameters(2)); MapComponents(spatialOp); spatialOp.Commit(); return(spatialOp); }
/// <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) { 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); ret.EquationComponents[Codomain[0]].Add(c); ret.Commit(); return(ret); }
private MsrMatrix PenaltyMatrix(EdgeMask em, Basis LevSetBasis, Basis JumpBasis) { var OpA = new SpatialOperator(1, 0, 1, QuadOrderFunc.Linear(), "Phi", "c1"); OpA.EquationComponents["c1"].Add(new JumpForm()); //OpA.EquationComponents["c1"].Add(new GradientJumpForm() { ATerm = true, BTerm = true }); OpA.EquationComponents["c1"].Add(new GradientJumpForm2()); OpA.Commit(); //var OpB = new SpatialOperator(1, 0, 1, "Phi", "c1"); //Op.EquationComponents["c1"].Add(new JumpForm()); //OpB.EquationComponents["c1"].Add(new GradientJumpForm() { BTerm = true }); //Op.EquationComponents["c1"].Add(new GradientJumpForm2()); //OpB.Commit(); var inp_LevSet_Mapping = new UnsetteledCoordinateMapping(LevSetBasis); var outp_Result_Mapping = new UnsetteledCoordinateMapping(JumpBasis); MsrMatrix MatrixA; MatrixA = new MsrMatrix(outp_Result_Mapping, inp_LevSet_Mapping); double[] AffineA = new double[inp_LevSet_Mapping.LocalLength]; OpA.ComputeMatrixEx(inp_LevSet_Mapping, null, outp_Result_Mapping, MatrixA, AffineA, OnlyAffine: false, edgeQuadScheme: new EdgeQuadratureScheme(true, em), volQuadScheme: new CellQuadratureScheme(true, CellMask.GetEmptyMask(em.GridData))); MatrixA.CheckForNanOrInfM(); //MsrMatrix MatrixB; //MatrixB = new MsrMatrix(outp_Result_Mapping, inp_LevSet_Mapping); //double[] AffineB = new double[inp_LevSet_Mapping.LocalLength]; //OpB.ComputeMatrixEx(inp_LevSet_Mapping, null, outp_Result_Mapping, // MatrixB, AffineB, OnlyAffine: false // );//, // //edgeQrCtx: new EdgeQuadratureScheme(true, em), // //volQrCtx: new CellQuadratureScheme(true, CellMask.GetEmptyMask(em.GridData))); //Debug.Assert(AffineB.L2Norm() == 0); //var Err = MatrixA.Transpose(); //Err.Acc(-1.0, MatrixB); //double errnorm = Err.InfNorm(); //Debug.Assert(errnorm < 1.0e-10); ////Console.WriteLine("Errnorm:" + errnorm); return(MatrixA); }
protected override SpatialOperator GetSpatialOperator(SolverConfiguration SolverConf, int SpatialComponent, int SpatialDirection) { SpatialOperator PressureOp = new SpatialOperator(new string[] { VariableNames.Pressure }, new string[] { "p1" }, QuadOrderFunc.Linear()); PressureOp.EquationComponents["p1"].Add(new PressureGradientLin_d(SpatialDirection, SolverConf.BcMap)); if (SolverConf.Control.PressureGradientSource != null) { PressureOp.EquationComponents["p1"].Add( new SrcPressureGradientLin_d(SolverConf.Control.PressureGradientSource[SpatialDirection])); } PressureOp.Commit(); return(PressureOp); }
/// <summary> /// locks the configuration of the operator /// </summary> public void Commit() { InternalRepresentation.OperatorCoefficientsProvider = owner.OperatorCoefficientsProvider; InternalRepresentation.LinearizationHint = LinearizationHint.AdHoc; InternalRepresentation.ParameterFactories.Clear(); InternalRepresentation.ParameterFactories.AddRange(owner.ParameterFactories); InternalRepresentation.ParameterUpdates.Clear(); InternalRepresentation.ParameterUpdates.AddRange(owner.ParameterUpdates); InternalRepresentation.EdgeQuadraturSchemeProvider = owner.EdgeQuadraturSchemeProvider; InternalRepresentation.VolumeQuadraturSchemeProvider = owner.VolumeQuadraturSchemeProvider; InternalRepresentation.m_UserDefinedValues = owner.m_UserDefinedValues; InternalRepresentation.Commit(); }
/// <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="accumulateResult"> /// Tells this method whether to accumulate (true) or not (false) /// </param> /// <param name="cm"> /// optional restriction to computational domain /// </param> virtual public void ProjectQuotient( double alpha, DGField a, DGField b, CellMask cm, 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 fracOp = new SpatialOperator(new string[] { "a", "b" }, new string[] { "res" }, QuadOrderFunc.Linear()); //QuadOrderFunc.NonLinear(2)); fracOp.EdgeQuadraturSchemeProvider = g => new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(g)); fracOp.VolumeQuadraturSchemeProvider = g => new CellQuadratureScheme(true, cm); fracOp.EquationComponents["res"].Add(new QuotientSource()); fracOp.Commit(); CoordinateVector coDom = this.CoordinateVector; var ev = fracOp.GetEvaluatorEx( new CoordinateMapping(a, b), null, coDom.Mapping); ev.Evaluate <CoordinateVector>(alpha, 1.0, coDom); }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { SpatialOperator diffOp = new SpatialOperator(1, 0, 1, QuadOrderFunc.MaxDegTimesTwo(), "u", "codom1"); diffOp.EquationComponents["codom1"].Add(new ScalarTransportFlux()); diffOp.Commit(); CustomTimestepConstraint = new SurrogateConstraint(GridData, dt_input, dt_input, double.MaxValue, endTime); if (LTS) { AdamsBashforthLTS ltsTimeStepper = new AdamsBashforthLTS( diffOp, new CoordinateMapping(u), null, ABorder, numOfSubgrids, fluxCorrection: true, reclusteringInterval: 0, timeStepConstraints: new List <TimeStepConstraint>() { CustomTimestepConstraint }); timeStepper = ltsTimeStepper; } else if (ALTS) { AdamsBashforthLTS ltsTimeStepper = new AdamsBashforthLTS( diffOp, new CoordinateMapping(u), null, ABorder, numOfSubgrids, fluxCorrection: false, reclusteringInterval: 1, timeStepConstraints: new List <TimeStepConstraint>() { CustomTimestepConstraint }); timeStepper = ltsTimeStepper; } else { timeStepper = new AdamsBashforth(diffOp, new CoordinateMapping(u), null, ABorder); //timeStepper = new RungeKutta(RungeKutta.RungeKuttaScheme.Heun, diffOp, new CoordinateMapping(u),null); //timeStepper = RungeKutta.Factory(ABorder, diffOp, new CoordinateMapping(u)); } }
/// <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 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 }