/// <summary> /// /// </summary> /// <param name="PrecondMassMatrix"> /// No scaling, but with agglomeration -- used to compute the DG basis of the preconditioner /// </param> /// <param name="ScaledMassMatrix"> /// No agglomeration, but with <see cref="XdgTimesteppingBase.Config_MassScale"/> applied. /// </param> /// <param name="time"></param> void UpdateMassMatrix(out BlockMsrMatrix PrecondMassMatrix, out BlockMsrMatrix ScaledMassMatrix, double time) { if (this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsIdentity) { // may occur e.g. if one runs the FSI solver as a pure single-phase solver, // i.e. if the Level-Set is outside the domain. ScaledMassMatrix = null; PrecondMassMatrix = null; } else { // checks: Debug.Assert(this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsNonIdentity || this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsTimeDependent || this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsTimeAndSolutionDependent, "Something is not implemented here."); if (this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsNonIdentity && Config_LevelSetHandling != LevelSetHandling.None) { throw new NotSupportedException("Illegal configuration;"); } if ((this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsNonIdentity) || (this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsTimeDependent) || (this.Config_MassMatrixShapeandDependence == MassMatrixShapeandDependence.IsTimeAndSolutionDependent) ) { //MassMatrixFactory MassFact = new MassMatrixFactory(CurrentStateMapping.BasisS.ElementAtMax(b => b.Degree), m_CurrentAgglomeration); MassMatrixFactory MassFact = m_LsTrk.GetXDGSpaceMetrics(Config_SpeciesToCompute, Config_CutCellQuadratureOrder, 1).MassMatrixFactory; PrecondMassMatrix = MassFact.GetMassMatrix(CurrentStateMapping, false); m_CurrentAgglomeration.ManipulateMatrixAndRHS(PrecondMassMatrix, default(double[]), CurrentStateMapping, CurrentStateMapping); ScaledMassMatrix = new BlockMsrMatrix(CurrentStateMapping); int NF = this.CurrentStateMapping.Fields.Count; //MassFact.AccMassMatrix(ScaledMassMatrix, CurrentStateMapping, _alpha: Config_MassScale); base.ComputeMassMatrixImpl(ScaledMassMatrix, time); } else { throw new NotSupportedException(); } } }
protected void ComputeMassMatrixImpl(BlockMsrMatrix MassMatrix, double time) { if (!MassMatrix._RowPartitioning.EqualsPartition(CurrentStateMapping)) { throw new ArgumentException("Internal error."); } if (!MassMatrix._ColPartitioning.EqualsPartition(CurrentStateMapping)) { throw new ArgumentException("Internal error."); } if (ComputeMassMatrix == null) { // ++++++++++++++ // default branch // ++++++++++++++ MassMatrixFactory MassFact = m_LsTrk.GetXDGSpaceMetrics(this.Config_SpeciesToCompute, this.Config_CutCellQuadratureOrder).MassMatrixFactory; MassFact.AccMassMatrix(MassMatrix, CurrentStateMapping, _alpha: Config_MassScale); } else { ComputeMassMatrix(MassMatrix, CurrentStateMapping, CurrentStateMapping.Fields.ToArray(), time); } }
private void AssembleMatrix(double MU_A, double MU_B, out BlockMsrMatrix M, out double[] b, out MultiphaseCellAgglomerator agg, out MassMatrixFactory massFact) { using (var tr = new FuncTrace()) { // create operator // =============== if (this.Control.SetDefaultDiriBndCnd) { this.Control.xLaplaceBCs.g_Diri = ((CommonParamsBnd inp) => 0.0); this.Control.xLaplaceBCs.IsDirichlet = (inp => true); } double D = this.GridData.SpatialDimension; int p = u.Basis.Degree; double penalty_base = (p + 1) * (p + D) / D; double penalty_multiplyer = base.Control.penalty_multiplyer; XQuadFactoryHelper.MomentFittingVariants momentFittingVariant; if (D == 3) { momentFittingVariant = XQuadFactoryHelper.MomentFittingVariants.Classic; } momentFittingVariant = this.Control.CutCellQuadratureType; int order = this.u.Basis.Degree * 2; XSpatialOperator Op = new XSpatialOperator(1, 1, (A, B, C) => order, "u", "c1"); var lengthScales = ((BoSSS.Foundation.Grid.Classic.GridData)GridData).Cells.PenaltyLengthScales; var lap = new XLaplace_Bulk(this.LsTrk, penalty_multiplyer * penalty_base, "u", this.Control.xLaplaceBCs, 1.0, MU_A, MU_B, lengthScales, this.Control.ViscosityMode); Op.EquationComponents["c1"].Add(lap); // Bulk form Op.EquationComponents["c1"].Add(new XLaplace_Interface(this.LsTrk, MU_A, MU_B, penalty_base * 2, this.Control.ViscosityMode)); // coupling form Op.Commit(); // create agglomeration // ==================== var map = new UnsetteledCoordinateMapping(u.Basis); //agg = new MultiphaseCellAgglomerator( // new CutCellMetrics(momentFittingVariant, // QuadOrderFunc.SumOfMaxDegrees(RoundUp: true)(map.BasisS.Select(bs => bs.Degree).ToArray(), new int[0], map.BasisS.Select(bs => bs.Degree).ToArray()), // //this.HMFDegree, // LsTrk, this.LsTrk.SpeciesIdS.ToArray()), // this.Control.AgglomerationThreshold, false); agg = LsTrk.GetAgglomerator(this.LsTrk.SpeciesIdS.ToArray(), order, this.Control.AgglomerationThreshold); // compute matrix // ============= using (new BlockTrace("XdgMatrixAssembly", tr)) { M = new BlockMsrMatrix(map, map); b = new double[M.RowPartitioning.LocalLength]; Op.ComputeMatrixEx(LsTrk, map, null, map, M, b, false, 0.0, true, agg.CellLengthScales, null, null, //out massFact, this.LsTrk.SpeciesIdS.ToArray()); } // compare with linear evaluation // ============================== DGField[] testDomainFieldS = map.BasisS.Select(bb => new XDGField(bb as XDGBasis)).ToArray(); CoordinateVector test = new CoordinateVector(testDomainFieldS); DGField[] errFieldS = map.BasisS.Select(bb => new XDGField(bb as XDGBasis)).ToArray(); CoordinateVector Err = new CoordinateVector(errFieldS); var eval = Op.GetEvaluatorEx(LsTrk, testDomainFieldS, null, map); foreach (var s in this.LsTrk.SpeciesIdS) { eval.SpeciesOperatorCoefficients[s].CellLengthScales = agg.CellLengthScales[s]; } eval.time = 0.0; int L = test.Count; Random r = new Random(); for (int i = 0; i < L; i++) { test[i] = r.NextDouble(); } double[] R1 = new double[L]; double[] R2 = new double[L]; eval.Evaluate(1.0, 1.0, R1); R2.AccV(1.0, b); M.SpMV(1.0, test, 1.0, R2); Err.AccV(+1.0, R1); Err.AccV(-1.0, R2); double ErrDist = GenericBlas.L2DistPow2(R1, R2).MPISum().Sqrt(); double Ref = test.L2NormPow2().MPISum().Sqrt(); Assert.LessOrEqual(ErrDist, Ref * 1.0e-5, "Mismatch between explicit evaluation of XDG operator and matrix."); // agglomeration wahnsinn // ====================== agg.ManipulateMatrixAndRHS(M, b, map, map); foreach (var S in this.LsTrk.SpeciesNames) { Console.WriteLine(" Species {0}: no of agglomerated cells: {1}", S, agg.GetAgglomerator(this.LsTrk.GetSpeciesId(S)).AggInfo.SourceCells.NoOfItemsLocally); } // mass matrix factory // =================== Basis maxB = map.BasisS.ElementAtMax(bss => bss.Degree); //massFact = new MassMatrixFactory(maxB, agg); massFact = LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), order).MassMatrixFactory; } }