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); } } }
private double PerformSurfaceQuadrature(Modes mode, IQuadRuleFactory <QuadRule> volumeFactory, IQuadRuleFactory <QuadRule> edgeFactory, SubGrid cutCellGrid, int order, Stopwatch timer) { using (new FuncTrace()) { CellQuadratureScheme volInstr = new CellQuadratureScheme( volumeFactory, cutCellGrid.VolumeMask); CellBoundaryQuadratureScheme edgeInstr = new CellBoundaryQuadratureScheme( new CellBoundaryFromEdgeRuleFactory <CellBoundaryQuadRule>( GridData, Grid.RefElements[0], edgeFactory), cutCellGrid.VolumeMask); ScalarFieldLevelSetIntegrator quadrature = new ScalarFieldLevelSetIntegrator( levelSetTracker, SinglePhaseField, volInstr.Compile(GridData, order), edgeInstr.Compile(GridData, order), order, cutCellGrid, 0); timer.Start(); double result = quadrature.ExecuteA().Storage.Sum(); timer.Stop(); return(result); } }
/// <summary> /// integrates some arbitrary function <paramref name="f"/> (which /// depends on DG fields <paramref name="Fields"/>) over some domain /// implied by <paramref name="scheme"/> /// </summary> /// <param name="scheme"> /// specification of quadrature rule and integration domain /// </param> /// <param name="f"> /// integrand /// </param> /// <param name="Fields"> /// input arguments for function <paramref name="f"/> /// </param> /// <returns> /// the integral of <paramref name="f"/> over the domain implied by /// <paramref name="scheme"/> /// </returns> /// <param name="OverIntegrationMultiplier"> /// Multiplier for Quadrature Order /// </param> public static double IntegralOverEx(CellQuadratureScheme scheme, Func f, int OverIntegrationMultiplier = 2, params DGField[] Fields) { using (new FuncTrace()) { ilPSP.MPICollectiveWatchDog.Watch(MPI.Wrappers.csMPI.Raw._COMM.WORLD); var g = Fields[0].Basis.GridDat; int order = Fields.Max(x => x.Basis.Degree) * OverIntegrationMultiplier; for (int i = 1; i < Fields.Length; i++) { if (!Object.ReferenceEquals(g, Fields[i].Basis.GridDat)) { throw new ArgumentException("all fields must be defined on the same grid"); } } IntegralOverExQuadrature q = new IntegralOverExQuadrature(g, Fields, scheme.SaveCompile(g, order), f); q.Execute(); unsafe { double locRes = q.result, glRes = 0; csMPI.Raw.Allreduce((IntPtr)(&locRes), (IntPtr)(&glRes), 1, csMPI.Raw._DATATYPE.DOUBLE, csMPI.Raw._OP.SUM, csMPI.Raw._COMM.WORLD); return(glRes); } } }
/// <summary> /// L2 error with respect to given reference solution. The quadrature /// is determined from the settings in <see cref="IBMControl"/> /// </summary> /// <param name="fieldName"></param> /// <param name="referenceSolution"></param> /// <returns></returns> public static Query L2Error(string fieldName, Func <double[], double, double> referenceSolution) { return(delegate(IApplication <AppControl> app, double time) { IProgram <CNSControl> program = app as IProgram <CNSControl>; if (program == null) { throw new Exception(); } ImmersedSpeciesMap speciesMap = program.SpeciesMap as ImmersedSpeciesMap; IBMControl control = program.Control as IBMControl; if (speciesMap == null || control == null) { throw new Exception( "Query is only valid for immersed boundary runs"); } SpeciesId species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName); int order = control.LevelSetQuadratureOrder; CellQuadratureScheme scheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme( species, true, speciesMap.SubGrid.VolumeMask); DGField dgField = app.IOFields.Single(f => f.Identification == fieldName); return dgField.L2Error(referenceSolution.Vectorize(time), order, scheme); }); }
public static Query Integral(string fieldName) { return(delegate(IApplication <AppControl> app, double time) { IProgram <CNSControl> program = app as IProgram <CNSControl>; if (program == null) { throw new Exception(); } ImmersedSpeciesMap speciesMap = program.SpeciesMap as ImmersedSpeciesMap; IBMControl control = program.Control as IBMControl; if (speciesMap == null || control == null) { throw new Exception( "Query is only valid for immersed boundary runs"); } SpeciesId species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName); int order = control.LevelSetQuadratureOrder; CellQuadratureScheme scheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme( species, true, speciesMap.SubGrid.VolumeMask); DGField dgField = app.IOFields.Single(f => f.Identification == fieldName); return DGField.IntegralOverEx(scheme, new Func((X, U, j) => (U[0])), 2, dgField); }); }
public static double EnergyJumpAtInterface(LevelSetTracker LsTrk, VectorField <XDGField> Velocity, XDGField Pressure, double muA, double muB, bool Norm, int momentFittingorder) { double EnergyJump = 0.0; ScalarFunctionEx EnergyJumpFunc = GetEnergyJumpFunc(LsTrk, Velocity, Pressure, muA, muB, Norm); var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, momentFittingorder, 1).XQuadSchemeHelper; CellQuadratureScheme cqs = SchemeHelper.GetLevelSetquadScheme(0, LsTrk.Regions.GetCutCellMask()); CellQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat, cqs.Compile(LsTrk.GridDat, momentFittingorder), delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { EnergyJumpFunc(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0)); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { for (int i = 0; i < Length; i++) { EnergyJump += ResultsOfIntegration[i, 0]; } } ).Execute(); if (Norm) { EnergyJump.Sqrt(); } return(EnergyJump); }
public static double EnergyBalanceNormAtInterface(XDGField P, VectorField <XDGField> U, ConventionalDGField[] Umean, SinglePhaseField C, double muA, double muB, double sigma, int momentFittingOrder) { LevelSetTracker LsTrk = P.Basis.Tracker; double energyBal_Norm = 0.0; ScalarFunctionEx energyBalFunc = GetEnergyBalanceFunc(P, U, Umean, C, muA, muB, sigma, true); var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, momentFittingOrder, 1).XQuadSchemeHelper; CellQuadratureScheme cqs = SchemeHelper.GetLevelSetquadScheme(0, LsTrk.Regions.GetCutCellMask()); CellQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat, cqs.Compile(LsTrk.GridDat, momentFittingOrder), delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { energyBalFunc(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0)); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { for (int i = 0; i < Length; i++) { energyBal_Norm += ResultsOfIntegration[i, 0]; } } ).Execute(); return(energyBal_Norm.Sqrt()); }
public static double SurfaceEnergyChangerate(LevelSetTracker LsTrk, ConventionalDGField[] uI, double sigma, bool Norm, int momentFittingorder) { double Changerate_Surface = 0.0; var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, momentFittingorder, 1).XQuadSchemeHelper; CellQuadratureScheme cqs = SchemeHelper.GetLevelSetquadScheme(0, LsTrk.Regions.GetCutCellMask()); ScalarFunctionEx SurfaceChangerate = GetInterfaceDivergenceFunc(LsTrk, uI, Norm); CellQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat, cqs.Compile(LsTrk.GridDat, momentFittingorder), delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { SurfaceChangerate(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0)); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { for (int i = 0; i < Length; i++) { Changerate_Surface += ResultsOfIntegration[i, 0]; } } ).Execute(); double Changerate_Esurf; if (Norm) { Changerate_Esurf = sigma * Changerate_Surface.Sqrt(); } else { Changerate_Esurf = sigma * Changerate_Surface; } return(Changerate_Esurf); }
/// <summary> /// Interior quadrature for the surface elements, i.e. for each cut background-cell \f$ K_j \f$ a quadrature to approximate /// \f[ /// \oint_{K_j \cap \mathfrak{I} } \ldots \mathrm{dS} . /// \f] /// </summary> public CellQuadratureScheme Get_SurfaceElement_VolumeQuadScheme(SpeciesId sp) { if (!this.SpeciesList.Contains(sp)) { throw new ArgumentException("Given species (id = " + sp.cntnt + ") is not supported."); } var spdom = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(sp); var IntegrationDom = XDGSpaceMetrics.LevelSetRegions.GetCutCellMask().Intersect(spdom); var LevSetQrIns = new CellQuadratureScheme(false, IntegrationDom); foreach (var Kref in XDGSpaceMetrics.GridDat.Grid.RefElements) { for (int iLevSet = 0; iLevSet < XDGSpaceMetrics.NoOfLevelSets; iLevSet++) // loop over level sets... { var surfaceFactory = this.XDGSpaceMetrics.XQuadFactoryHelper.GetSurfaceFactory(iLevSet, Kref); LevSetQrIns = LevSetQrIns.AddFactory(surfaceFactory, XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet)); } } return(LevSetQrIns); }
public static double CurvatureEnergy(LevelSetTracker LsTrk, SinglePhaseField Curvature, double sigma, ConventionalDGField[] uI, bool ExtVel, bool Norm, int momentFittingorder) { double EnergyCurv = 0.0; var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, momentFittingorder, 1).XQuadSchemeHelper; CellQuadratureScheme cqs = SchemeHelper.GetLevelSetquadScheme(0, LsTrk.Regions.GetCutCellMask()); ScalarFunctionEx CurvEnergyFunc = GetCurvatureEnergyFunc(LsTrk, Curvature, sigma, uI, ExtVel, Norm); CellQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat, cqs.Compile(LsTrk.GridDat, momentFittingorder), delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { CurvEnergyFunc(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0)); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { for (int i = 0; i < Length; i++) { EnergyCurv += ResultsOfIntegration[i, 0]; } } ).Execute(); if (Norm) { EnergyCurv.Sqrt(); } return(EnergyCurv); }
/// <summary> /// computes <see cref="LaplaceMtx"/> and <see cref="LaplaceAffine"/> /// </summary> private void UpdateMatrices() { using (var tr = new FuncTrace()) { // time measurement for matrix assembly Stopwatch stw = new Stopwatch(); stw.Start(); // console Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal); // quadrature domain var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData, MaskType.Geometrical)); var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData, MaskType.Geometrical)); #if DEBUG // in DEBUG mode, we compare 'MsrMatrix' (old, reference implementation) and 'BlockMsrMatrix' (new standard) var RefLaplaceMtx = new MsrMatrix(T.Mapping); #endif using (new BlockTrace("SipMatrixAssembly", tr)) { 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 stw.Stop(); Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds); //var JB = LapaceIp.GetFDJacobianBuilder(T.Mapping.Fields, null, T.Mapping, edgQrSch, volQrSch); //var JacobiMtx = new BlockMsrMatrix(T.Mapping); //var JacobiAffine = new double[T.Mapping.LocalLength]; //JB.ComputeMatrix(JacobiMtx, JacobiAffine); //double L2ErrAffine = GenericBlas.L2Dist(JacobiAffine, LaplaceAffine); //var ErrMtx2 = LaplaceMtx.CloneAs(); //ErrMtx2.Acc(-1.0, JacobiMtx); //double LinfErrMtx2 = ErrMtx2.InfNorm(); //JacobiMtx.SaveToTextFileSparse("D:\\tmp\\Jac.txt"); //LaplaceMtx.SaveToTextFileSparse("D:\\tmp\\Lap.txt"); //Console.WriteLine("FD Jacobi Mtx: {0:e14}, Affine: {1:e14}", LinfErrMtx2, L2ErrAffine); } }
/// <summary> /// ctor /// </summary> /// <param name="a">1st field</param> /// <param name="b">2nd field</param> /// <param name="quaddegree"> /// for the quadrature rule to chose, the /// the degree of a polynomial that can be exactly integrated; /// </param> /// <param name="quadScheme"></param> public InnerProductQuadrature(DGField a, DGField b, CellQuadratureScheme quadScheme, int quaddegree) : base(new int[] { 1 }, a.GridDat, quadScheme.SaveCompile(a.GridDat, quaddegree)) { if (!object.ReferenceEquals(a.GridDat, b.GridDat)) { throw new ArgumentException("Fields cannot be assigned to different grids."); } m_FieldA = a; m_FieldB = b; }
/// <summary> /// Projects the given <paramref name="initialValues"/> onto the /// conservative variable fields <see cref="Density"/>, /// <see cref="Momentum"/> and <see cref="Energy"/>. Initial values /// may either be given in conservative (see /// <see cref="VariableTypes.ConservativeVariables"/>) or primitive /// (see <see cref="VariableTypes.PrimitiveVariables"/>) variables /// </summary> /// <param name="speciesMap"></param> /// <param name="initialValues"> /// The given initial value functions, where the dictionary keys /// represent variable names. /// </param> public virtual void ProjectInitialValues(ISpeciesMap speciesMap, IDictionary <string, Func <double[], double> > initialValues) { int numberOfDimensions = CNSEnvironment.NumberOfDimensions; CellQuadratureScheme scheme = new CellQuadratureScheme(true, speciesMap.SubGrid.VolumeMask); if (config.GetInitialValueVariables() == VariableTypes.ConservativeVariables) { Density.ProjectField(1.0, initialValues[Variables.Density], scheme); for (int d = 0; d < numberOfDimensions; d++) { Momentum[d].ProjectField(1.0, initialValues[Variables.Momentum[d]], scheme); } Energy.ProjectField(1.0, initialValues[Variables.Energy], scheme); } else if (config.GetInitialValueVariables() == VariableTypes.PrimitiveVariables) { var densityFunction = initialValues[Variables.Density]; Density.ProjectField(1.0, densityFunction, scheme); Func <double[], double>[] velocityFunctions = new Func <double[], double> [numberOfDimensions]; for (int d = 0; d < numberOfDimensions; d++) { velocityFunctions[d] = initialValues[Variables.Velocity[d]]; Momentum[d].ProjectField(1.0, X => densityFunction(X) * velocityFunctions[d](X), scheme); } var pressureFunction = initialValues[Variables.Pressure]; Energy.ProjectField( 1.0, delegate(double[] X) { double rho = densityFunction(X); double p = pressureFunction(X); Vector u = new Vector(numberOfDimensions); for (int d = 0; d < numberOfDimensions; d++) { u[d] = velocityFunctions[d](X); } StateVector state = StateVector.FromPrimitiveQuantities( speciesMap.GetMaterial(double.NaN), rho, u, p); return(state.Energy); }, scheme); } else { throw new ArgumentException( "Please specify initial values either in primitive or in conservative variables"); } }
/// <summary> /// Quadrature scheme for the integration over the level-set, i.e. for each cut background-cell \f$ K_j \f$ a quadrature to approximate /// \f[ /// \oint_{K_j \cap \mathfrak{I} } \ldots \mathrm{dS} . /// \f] /// </summary> /// <param name="iLevSet"></param> /// <param name="IntegrationDom"></param> /// <param name="fixedOrder"></param> /// <returns></returns> public CellQuadratureScheme GetLevelSetquadScheme(int iLevSet, CellMask IntegrationDom, int?fixedOrder = null) { CellQuadratureScheme LevSetQrIns = new CellQuadratureScheme(false, IntegrationDom); foreach (var Kref in XDGSpaceMetrics.GridDat.Grid.RefElements) { var surfaceFactory = this.XDGSpaceMetrics.XQuadFactoryHelper.GetSurfaceFactory(iLevSet, Kref); LevSetQrIns.AddFactoryDomainPair(surfaceFactory, (CellMask)null, fixedOrder); } return(LevSetQrIns); }
/// <summary> /// L1 - norm of this field; /// This is a collective call, it must be invoked by all /// MPI processes within the communicator; internally, it invokes MPI_Allreduce; /// </summary> /// <returns> /// on all invoking MPI processes, the L1 norm of /// this field; /// </returns> /// <param name="CM"> /// optional cell mask /// </param> virtual public double L1Norm(CellMask CM) { CellQuadratureScheme scheme = null; if (CM != null) { scheme = new CellQuadratureScheme(true, CM); } double r = LxError((ScalarFunction)null, (X, a, b) => a.Abs(), scheme.SaveCompile(this.GridDat, 2 * m_Basis.Degree)); return(r); }
/// <summary> /// another legacy interface /// </summary> static public void ComputeAffine <V>( this SpatialOperator op, UnsetteledCoordinateMapping DomainMap, IList <DGField> Parameters, UnsetteledCoordinateMapping CodomainMap, V AffineOffset, bool OnlyBoundaryEdges = true, double time = 0.0, EdgeQuadratureScheme edgeQr = null, CellQuadratureScheme volQr = null) where V : IList <double> { var GridDat = CodomainMap.GridDat; if (Parameters != null) { foreach (var prm in Parameters) { if (!object.ReferenceEquals(prm.GridDat, GridDat)) { throw new ArgumentException(string.Format("parameter field {0} is assigned to a different grid.", prm.Identification)); } } } //Using order zero for DomainMap will lead to inconsistent (and possibly insufficient) quadrature order!!! //UnsetteledCoordinateMapping DomainMap; //Basis b = new Basis(GridDat, 0); //Basis[] B = new Basis[this.DomainVar.Count]; //B.SetAll(b); //DomainMap = new UnsetteledCoordinateMapping(B); if (OnlyBoundaryEdges) { if (edgeQr != null) { throw new ArgumentException("If 'OnlyBoundaryEdges == true', 'edgeQr' must be null!", "edgeQr"); } if (volQr != null) { throw new ArgumentException("If 'OnlyBoundaryEdges == true', 'volQr' must be null!", "volQr"); } volQr = new CellQuadratureScheme(true, CellMask.GetEmptyMask(GridDat)); edgeQr = new EdgeQuadratureScheme(true, GridDat.GetBoundaryEdgeMask()); } op.ComputeMatrixEx( DomainMap, Parameters, CodomainMap, default(MsrMatrix), AffineOffset, OnlyAffine: true, time: time, volQuadScheme: volQr, edgeQuadScheme: edgeQr); }
/// <summary> /// Computes the Integral of a given function over the zero iso-contour of the Level-Set /// </summary> /// <param name="LsTrk">Level-Set tracker</param> /// <param name="func">function which is integrated</param> /// <param name="HMForder"></param> /// <param name="spc">species, over whose surface is integrated</param> /// <returns>Integral of <param name="func">func</param> over all MPI processors</returns> static public double GetIntegralOverZeroLevelSet(LevelSetTracker LsTrk, ScalarFunctionEx func, int HMForder, SpeciesId spc) { using (new FuncTrace()) { if (LsTrk.LevelSets.Count != 1) { throw new NotImplementedException(); } var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new SpeciesId[] { spc }, HMForder, 1).XQuadSchemeHelper; // new XQuadSchemeHelper(LsTrk, momentFittingVariant); // Classic HMF uses order+1 for Surface Integrals and additionally 1 order higher for the HMF system // e.g order-2 is the cached quad rule if (SchemeHelper.MomentFittingVariant == XQuadFactoryHelper.MomentFittingVariants.Classic) { HMForder -= 2; } CellQuadratureScheme cqs = SchemeHelper.GetLevelSetquadScheme(0, LsTrk.Regions.GetCutCellMask()); double force = 0; CellQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat, cqs.Compile(LsTrk.GridDat, HMForder), delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { func(i0, Length, QR.Nodes, EvalResult); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { for (int i = 0; i < Length; i++) { force += ResultsOfIntegration[i, 0]; } } ).Execute(); double localForce = force; double globalForce; unsafe { csMPI.Raw.Allreduce( (IntPtr)(&localForce), (IntPtr)(&globalForce), 1, csMPI.Raw._DATATYPE.DOUBLE, csMPI.Raw._OP.SUM, csMPI.Raw._COMM.WORLD); } return(globalForce); } }
/// <summary> /// Computes L2 distance between this field and /// <paramref name="other"/> /// </summary> /// <param name="other"></param> /// <param name="cm"> /// Optional restriction of domain /// </param> /// <param name="overrideGridCheck"> /// If this parameter is set to true, the error will be computed even /// though <see cref="DGField.GridDat"/> is not identical for both /// fields. Only do so if you are really sure that the grids are still /// equivalent. /// </param> public double L2Error(DGField other, CellMask cm = null, bool overrideGridCheck = false) { if (!overrideGridCheck && !object.ReferenceEquals(this.GridDat, other.GridDat)) { throw new Exception( "Cannot compute error between DG fields on different grids"); } int order = Math.Max(this.Basis.Degree, other.Basis.Degree) * 2; CellQuadratureScheme cqs = new CellQuadratureScheme(domain: cm); return(LxError(other.Evaluate, null, cqs.Compile(this.GridDat, order))); }
/// <summary> /// computes the L2 norm of the Residual of the Eikonal equation in the /// domain <paramref name="K"/>, i.e. <br/> /// \f[ /// \left\| /// \textrm{\textbf{1}}_K /// \cdot /// \left( | \nabla \phi | - 1 \right) /// \right\|_2 /// \f] /// </summary> /// <param name="K"> /// optional restriction to a subdomain /// </param> public double SignedDistanceError(CellMask K) { var cqc = new CellQuadratureScheme(true, K); var q = new SignedDistanceErrorQuad( this, cqc.Compile(this.Basis.GridDat, this.Basis.Degree * 4)); q.Execute(); unsafe { double local = q.LocalErrorL2Accumulated; double global; csMPI.Raw.Allreduce((IntPtr)(&local), (IntPtr)(&global), 1, csMPI.Raw._DATATYPE.DOUBLE, csMPI.Raw._OP.SUM, csMPI.Raw._COMM.WORLD); return(global); } }
internal void BuildEvaluatorsAndMasks() { CellMask fluidCells = speciesMap.SubGrid.VolumeMask.Intersect(ABSubGrid.VolumeMask); cutCells = speciesMap.Tracker.Regions.GetCutCellMask().Intersect(ABSubGrid.VolumeMask); cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells).Intersect(ABSubGrid.VolumeMask); IBMControl control = speciesMap.Control; SpeciesId species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName); CellQuadratureScheme volumeScheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme( species, true, fluidCells, control.LevelSetQuadratureOrder); // Does _not_ include agglomerated edges EdgeMask nonVoidEdges = speciesMap.QuadSchemeHelper.GetEdgeMask(species); nonVoidEdges = nonVoidEdges.Intersect(ABSubGrid.AllEdgesMask.ToGeometicalMask()); EdgeQuadratureScheme edgeScheme = speciesMap.QuadSchemeHelper.GetEdgeQuadScheme( species, true, nonVoidEdges, control.LevelSetQuadratureOrder); this.m_Evaluator = new Lazy <IEvaluatorNonLin>(delegate() { this.Operator.EdgeQuadraturSchemeProvider = g => edgeScheme; this.Operator.VolumeQuadraturSchemeProvider = g => volumeScheme; var opi = this.Operator.GetEvaluatorEx( Mapping, boundaryParameterMap, Mapping); opi.ActivateSubgridBoundary(ABSubGrid.VolumeMask, subGridBoundaryTreatment: SubGridBoundaryModes.InnerEdgeLTS); return(opi); }); // Evaluator for boundary conditions at level set zero contour CellQuadratureScheme boundaryVolumeScheme = speciesMap.QuadSchemeHelper.GetLevelSetquadScheme( 0, cutCells, control.LevelSetQuadratureOrder); this.boundaryEvaluator = new Lazy <IEvaluatorNonLin>(delegate() { boundaryOperator.EdgeQuadraturSchemeProvider = g => null; // Contains no boundary terms --> PROBLEM?????????? boundaryOperator.VolumeQuadraturSchemeProvider = g => boundaryVolumeScheme; return(boundaryOperator.GetEvaluatorEx( Mapping, boundaryParameterMap, Mapping)); }); }
/// <summary> /// Calculate Forces acting from fluid onto the particle /// </summary> internal double[] Forces(out List <double[]>[] stressToPrintOut, CellMask cutCells) { double[] tempForces = new double[m_SpatialDim]; double[] IntegrationForces = tempForces.CloneAs(); List <double[]>[] stressToPrint = new List <double[]> [m_SpatialDim]; stressToPrint[0] = new List <double[]>(); stressToPrint[1] = new List <double[]>(); for (int d = 0; d < m_SpatialDim; d++) { void ErrFunc(int CurrentCellID, int Length, NodeSet Ns, MultidimensionalArray result) { int K = result.GetLength(1); MultidimensionalArray Grad_UARes = MultidimensionalArray.Create(Length, K, m_SpatialDim, m_SpatialDim); MultidimensionalArray pARes = MultidimensionalArray.Create(Length, K); MultidimensionalArray Normals = m_LevelSetTracker.DataHistories[0].Current.GetLevelSetNormals(Ns, CurrentCellID, Length); for (int i = 0; i < m_SpatialDim; i++) { m_U[i].EvaluateGradient(CurrentCellID, Length, Ns, Grad_UARes.ExtractSubArrayShallow(-1, -1, i, -1), 0, 1); } m_P.Evaluate(CurrentCellID, Length, Ns, pARes); for (int j = 0; j < Length; j++) { for (int k = 0; k < K; k++) { result[j, k] = StressTensor(Grad_UARes, pARes, Normals, m_FluidViscosity, k, j, m_SpatialDim, d); double t = Math.PI * (1 - Math.Sign(Normals[j, k, 1])) / 2 + Math.Acos(Normals[j, k, 0]); stressToPrint[d].Add(new double[] { t, result[j, k] }); } } } int[] noOfIntegrals = new int[] { 1 }; XQuadSchemeHelper SchemeHelper = m_LevelSetTracker.GetXDGSpaceMetrics(new[] { m_LevelSetTracker.GetSpeciesId("A") }, m_RequiredOrder, 1).XQuadSchemeHelper; CellQuadratureScheme cqs = SchemeHelper.GetLevelSetquadScheme(0, cutCells); ICompositeQuadRule <QuadRule> surfaceRule = cqs.Compile(m_LevelSetTracker.GridDat, m_RequiredOrder); CellQuadrature.GetQuadrature(noOfIntegrals, m_GridData, surfaceRule, delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { ErrFunc(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0)); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { IntegrationForces[d] = ForceTorqueSummationWithNeumaierArray(IntegrationForces[d], ResultsOfIntegration, Length); } ).Execute(); } stressToPrintOut = stressToPrint.CloneAs(); return(tempForces = IntegrationForces.CloneAs()); }
private void BuildEvaluatorsAndMasks() { CellMask fluidCells = speciesMap.SubGrid.VolumeMask; cutCells = speciesMap.Tracker.Regions.GetCutCellMask(); cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells); IBMControl control = speciesMap.Control; SpeciesId species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName); CellQuadratureScheme volumeScheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme( species, true, fluidCells, control.LevelSetQuadratureOrder); // Does _not_ include agglomerated edges EdgeMask nonVoidEdges = speciesMap.QuadSchemeHelper.GetEdgeMask(species); EdgeQuadratureScheme edgeScheme = speciesMap.QuadSchemeHelper.GetEdgeQuadScheme( species, true, nonVoidEdges, control.LevelSetQuadratureOrder); this.m_Evaluator = new Lazy <IEvaluatorNonLin>(delegate() { this.Operator.EdgeQuadraturSchemeProvider = g => edgeScheme; this.Operator.VolumeQuadraturSchemeProvider = g => volumeScheme; var opi = this.Operator.GetEvaluatorEx( Mapping, null, // TO DO: I SIMPLY REMOVE PARAMETERMAP HERE; MAKE THIS MORE PRETTY //this.boundaryParameterMap, // TO DO: I SIMPLY REMOVE PARAMETERMAP HERE; MAKE THIS MORE PRETTY Mapping); opi.ActivateSubgridBoundary(volumeScheme.Domain, subGridBoundaryTreatment: SubGridBoundaryModes.InnerEdgeLTS); //opi.ActivateSubgridBoundary(fluidCells, subGridBoundaryTreatment: SubGridBoundaryModes.InnerEdgeLTS); return(opi); }); // Evaluator for boundary conditions at level set zero contour CellQuadratureScheme boundaryVolumeScheme = speciesMap.QuadSchemeHelper.GetLevelSetquadScheme( 0, cutCells, control.LevelSetQuadratureOrder); this.boundaryEvaluator = new Lazy <IEvaluatorNonLin>(delegate() { boundaryOperator.EdgeQuadraturSchemeProvider = g => null; // Contains no boundary terms boundaryOperator.VolumeQuadraturSchemeProvider = g => boundaryVolumeScheme; return(boundaryOperator.GetEvaluatorEx( Mapping, boundaryParameterMap, Mapping)); }); }
internal void BuildEvaluatorsAndMasks() { CellMask fluidCells = speciesMap.SubGrid.VolumeMask.Intersect(ABSubGrid.VolumeMask); cutCells = speciesMap.Tracker.Regions.GetCutCellMask().Intersect(ABSubGrid.VolumeMask); cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells).Intersect(ABSubGrid.VolumeMask); IBMControl control = speciesMap.Control; SpeciesId species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName); CellQuadratureScheme volumeScheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme( species, true, fluidCells, control.LevelSetQuadratureOrder); // Does _not_ include agglomerated edges EdgeMask nonVoidEdges = speciesMap.QuadSchemeHelper.GetEdgeMask(species); nonVoidEdges = nonVoidEdges.Intersect(ABSubGrid.AllEdgesMask); EdgeQuadratureScheme edgeScheme = speciesMap.QuadSchemeHelper.GetEdgeQuadScheme( species, true, nonVoidEdges, control.LevelSetQuadratureOrder); this.m_Evaluator = new Lazy <SpatialOperator.Evaluator>(() => this.Operator.GetEvaluatorEx( Mapping, boundaryParameterMap, Mapping, edgeScheme, volumeScheme, ABSubGrid, subGridBoundaryTreatment: SpatialOperator.SubGridBoundaryModes.InnerEdgeLTS)); // Evaluator for boundary conditions at level set zero contour CellQuadratureScheme boundaryVolumeScheme = speciesMap.QuadSchemeHelper.GetLevelSetquadScheme( 0, cutCells, control.LevelSetQuadratureOrder); this.boundaryEvaluator = new Lazy <SpatialOperator.Evaluator>(() => boundaryOperator.GetEvaluatorEx( Mapping, boundaryParameterMap, Mapping, null, // Contains no boundary terms --> PROBLEM?????????? boundaryVolumeScheme)); }
public static double GetKineticDissipation(LevelSetTracker LsTrk, DGField[] Velocity, double[] mu, int momentFittingOrder, int HistInd = 1) { using (new FuncTrace()) { int D = LsTrk.GridDat.SpatialDimension; if (Velocity.Count() != D) { throw new ArgumentException(); } if (LsTrk.SpeciesIdS.Count != mu.Length) { throw new ArgumentException(); } double dE = 0.0; var SchemeHelper = LsTrk.GetXDGSpaceMetrics(LsTrk.SpeciesIdS.ToArray(), momentFittingOrder, HistInd).XQuadSchemeHelper; for (int iSpc = 0; iSpc < LsTrk.SpeciesIdS.Count; iSpc++) { SpeciesId spcId = LsTrk.SpeciesIdS[iSpc]; double _mu = mu[iSpc]; var Uspc = Velocity.Select(u => (u as XDGField).GetSpeciesShadowField(spcId)).ToArray(); ScalarFunctionEx changerate_dEspc = GetSpeciesKineticDissipationFunc(Uspc, _mu); CellQuadratureScheme vqs = SchemeHelper.GetVolumeQuadScheme(spcId); CellQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat, vqs.Compile(LsTrk.GridDat, momentFittingOrder), delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { changerate_dEspc(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0)); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { for (int i = 0; i < Length; i++) { dE += ResultsOfIntegration[i, 0]; } } ).Execute(); } return(dE); } }
/// <summary> /// computes the inner product of fields <paramref name="a"/> and <paramref name="b"/> /// </summary> static public double InnerProduct(DGField a, DGField b, CellQuadratureScheme quadScheme = null) { using (new FuncTrace()) { if (!Object.ReferenceEquals(a.GridDat, b.GridDat)) { throw new ApplicationException("fields must be defined on the same grid."); } MPICollectiveWatchDog.Watch(csMPI.Raw._COMM.WORLD); InnerProductQuadrature ipq = new InnerProductQuadrature(a, b, quadScheme, a.Basis.Degree + b.Basis.Degree); ipq.Execute(); unsafe { double innerProdTot = double.NaN; double InnerProdLoc = ipq.m_InnerProd; csMPI.Raw.Allreduce((IntPtr)(&InnerProdLoc), (IntPtr)(&innerProdTot), 1, csMPI.Raw._DATATYPE.DOUBLE, csMPI.Raw._OP.SUM, csMPI.Raw._COMM.WORLD); return(innerProdTot); } } }
/// <summary> /// Computes the energy stored in the fluid interface of a two-phase flow. /// </summary> /// <param name="LsTrk"></param> /// <param name="sigma"></param> public static double GetSurfaceEnergy(LevelSetTracker LsTrk, double sigma) { using (new FuncTrace()) { if (LsTrk.LevelSets.Count != 1) { throw new NotImplementedException(); } double totSurface = 0; int order = 0; if (LsTrk.GetCachedOrders().Count > 0) { order = LsTrk.GetCachedOrders().Max(); } else { order = 1; } var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, order, 1).XQuadSchemeHelper; //var SchemeHelper = new XQuadSchemeHelper(LsTrk, momentFittingVariant, LsTrk.GetSpeciesId("A")); CellQuadratureScheme cqs = SchemeHelper.GetLevelSetquadScheme(0, LsTrk.Regions.GetCutCellMask()); CellQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat, cqs.Compile(LsTrk.GridDat, order), delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { EvalResult.SetAll(1.0); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { for (int i = 0; i < Length; i++) { totSurface += ResultsOfIntegration[i, 0]; } } ).Execute(); return(totSurface * sigma); } }
protected void UpdateEvaluatorsAndMasks() { CellMask fluidCells = speciesMap.SubGrid.VolumeMask; cutCells = speciesMap.Tracker.Regions.GetCutCellMask(); cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells); IBMControl control = speciesMap.Control; SpeciesId species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName); CellQuadratureScheme volumeScheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme( species, true, fluidCells, control.LevelSetQuadratureOrder); // Does _not_ include agglomerated edges EdgeMask nonVoidEdges = speciesMap.QuadSchemeHelper.GetEdgeMask(species); EdgeQuadratureScheme edgeScheme = speciesMap.QuadSchemeHelper.GetEdgeQuadScheme( species, true, nonVoidEdges, control.LevelSetQuadratureOrder); this.m_Evaluator = new Lazy <IEvaluatorNonLin>(delegate() { var opi = this.Operator.GetEvaluatorEx( Mapping, boundaryParameterMap, Mapping, edgeScheme, volumeScheme); opi.ActivateSubgridBoundary(volumeScheme.Domain.ToLogicalMask(), subGridBoundaryTreatment: SpatialOperator.SubGridBoundaryModes.InnerEdgeLTS); return(opi); }); // Evaluator for boundary conditions at level set zero contour CellQuadratureScheme boundaryVolumeScheme = speciesMap.QuadSchemeHelper.GetLevelSetquadScheme( 0, cutCells, control.LevelSetQuadratureOrder); this.boundaryEvaluator = new Lazy <IEvaluatorNonLin>(() => boundaryOperator.GetEvaluatorEx( Mapping, boundaryParameterMap, Mapping, null, // Contains no boundary terms boundaryVolumeScheme)); }
/// <summary> /// Calculate Forces acting from fluid onto the particle /// </summary> internal double Torque(double[] position, CellMask cutCells) { double tempTorque = new double(); void ErrFunc2(int j0, int Len, NodeSet Ns, MultidimensionalArray result) { int K = result.GetLength(1); MultidimensionalArray Grad_UARes = MultidimensionalArray.Create(Len, K, m_SpatialDim, m_SpatialDim);; MultidimensionalArray pARes = MultidimensionalArray.Create(Len, K); MultidimensionalArray Normals = m_LevelSetTracker.DataHistories[0].Current.GetLevelSetNormals(Ns, j0, Len); for (int i = 0; i < m_SpatialDim; i++) { m_U[i].EvaluateGradient(j0, Len, Ns, Grad_UARes.ExtractSubArrayShallow(-1, -1, i, -1), 0, 1); } m_P.Evaluate(j0, Len, Ns, pARes); for (int j = 0; j < Len; j++) { MultidimensionalArray Ns_Global = Ns.CloneAs(); m_LevelSetTracker.GridDat.TransformLocal2Global(Ns, Ns_Global, j0 + j); for (int k = 0; k < K; k++) { result[j, k] = TorqueStressTensor(Grad_UARes, pARes, Normals, Ns_Global, m_FluidViscosity, k, j, position); } } } var SchemeHelper2 = m_LevelSetTracker.GetXDGSpaceMetrics(new[] { m_LevelSetTracker.GetSpeciesId("A") }, m_RequiredOrder, 1).XQuadSchemeHelper; CellQuadratureScheme cqs2 = SchemeHelper2.GetLevelSetquadScheme(0, cutCells); CellQuadrature.GetQuadrature(new int[] { 1 }, m_LevelSetTracker.GridDat, cqs2.Compile(m_LevelSetTracker.GridDat, m_RequiredOrder), delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { ErrFunc2(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0)); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { tempTorque = ForceTorqueSummationWithNeumaierArray(tempTorque, ResultsOfIntegration, Length); } ).Execute(); return(tempTorque); }
/// <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</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 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.Commit(); var ev = src.GetEvaluatorEx( new CoordinateMapping(U), null, this.Mapping, edgeQrCtx: new EdgeQuadratureScheme(false, EdgeMask.GetEmptyMask(this.Basis.GridDat)), volQrCtx: cqs); ev.Evaluate(alpha, 1.0, this.CoordinateVector); }
private double PerformVolumeQuadrature(Modes mode, IQuadRuleFactory <QuadRule> factory, SubGrid cutCellGrid, int order, Stopwatch timer) { using (new FuncTrace()) { ScalarFieldQuadrature quadrature; CellQuadratureScheme quadInstr = new CellQuadratureScheme( factory, cutCellGrid.VolumeMask); if (testCase is ISurfaceTestCase) { quadrature = new ScalarFieldQuadrature(GridData, SinglePhaseField, quadInstr, order); } else { quadrature = new ScalarFieldQuadrature(GridData, XDGField, quadInstr, order); } timer.Start(); quadrature.Execute(); timer.Stop(); return(quadrature.Result); } }