/// <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();
                }
            }
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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;
            }
        }