Exemple #1
0
        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);
                }
            }
        }
Exemple #2
0
        /// <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);
            }
        }
Exemple #3
0
        void ComputeMatrix()
        {
            using (new FuncTrace()) {
                m_OperatorMatrix.Clear();

                m_SpatialOperator.ComputeMatrixEx <MsrMatrix, IList <double> >(m_ColMapping,
                                                                               m_ParameterFields,
                                                                               m_RowMapping,
                                                                               m_OperatorMatrix,
                                                                               null);
            }
        }
        /// <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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="spatialOp"></param>
        /// <param name="fields"></param>
        /// <param name="matrix"></param>
        /// <param name="affineOffset"></param>
        /// <param name="OnlyAffine">
        /// if true, only the <paramref name="affineOffset"/>
        /// is computed and <paramref name="matrix"/> is null on exit.
        /// </param>
        public static void ComputeMatrix(SpatialOperator spatialOp, CoordinateMapping fields, bool OnlyAffine, out MsrMatrix matrix, out double[] affineOffset)
        {
            // Check operator and arguments
            if (!spatialOp.IsCommited)
            {
                throw new ArgumentException("operator must be committed first.", "spatialOp");
            }
            if (spatialOp.ContainsNonlinear)
            {
                throw new ArgumentException("spatial differential operator cannot contain nonlinear components for implicit euler.", "spatialOp");
            }
            if (!spatialOp.ContainsLinear())
            {
                throw new ArgumentException("spatial differential operator seems to contain no components.", "spatialOp");
            }
            if (spatialOp.DomainVar.Count != spatialOp.CodomainVar.Count)
            {
                throw new ArgumentException("spatial differential operator must have the same number of domain and codomain variables.", "spatialOp");
            }
            if (fields.Fields.Count != spatialOp.CodomainVar.Count)
            {
                throw new ArgumentException("the number of fields in the coordinate mapping must be equal to the number of domain/codomain variables of the spatial differential operator", "fields");
            }

            // Assemble matrix and affine offset
            IPartitioning matrixPartition = fields;


            if (!OnlyAffine)
            {
                matrix = new MsrMatrix(matrixPartition);
            }
            else
            {
                matrix = null;
            }
            affineOffset = new double[fields.LocalLength];
            spatialOp.ComputeMatrixEx(
                fields, null, fields,
                matrix, affineOffset,
                OnlyAffine);
        }
Exemple #7
0
        /// <summary>
        /// ctor.
        /// </summary>
        public LinearSolver(ISparseSolver solver, SpatialOperator spatialOp, CoordinateMapping UnknownsMap)
        {
            // verify input
            // ------------
            if (!spatialOp.IsCommited)
            {
                throw new ArgumentException("operator must be committed first.", "spatialOp");
            }
            if (spatialOp.ContainsNonlinear)
            {
                throw new ArgumentException("spatial differential operator cannot contain nonlinear components for linear solver.", "spatialOp");
            }
            if (!spatialOp.ContainsLinear())
            {
                throw new ArgumentException("spatial differential operator seems to contain no components.", "spatialOp");
            }
            if (spatialOp.DomainVar.Count != spatialOp.CodomainVar.Count)
            {
                throw new ArgumentException("spatial differential operator must have the same number of domain and codomain variables.", "spatialOp");
            }

            if (UnknownsMap.Fields.Count != spatialOp.CodomainVar.Count)
            {
                throw new ArgumentException("the number of fields in the coordinate mapping must be equal to the number of domain/codomain variables of the spatial differential operator", "fields");
            }

            m_Mapping = UnknownsMap;
            m_Solver  = solver;

            // matrix assembly
            // ---------------
            MsrMatrix eM;

            {
                eM             = new MsrMatrix(m_Mapping);
                m_AffineOffset = new double[m_Mapping.LocalLength];

                spatialOp.ComputeMatrixEx(m_Mapping, null, m_Mapping, eM, m_AffineOffset);
            }

            ConstructorCommon(eM);
        }
Exemple #8
0
        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);
        }
        /// <summary>
        /// checks whether the linear and nonlinear implementation of operator evaluation are mathematically equal
        /// </summary>
        void LinearNonlinComparisonTest()
        {
            int L = this.bnd.CoordinateVector.Count();

            // need to assure to use the same quadrature oder on both evaluation variants
            var volQrSch = (new CellQuadratureScheme(false, CellMask.GetFullMask(this.GridData, MaskType.Geometrical)))
                           .AddFixedOrderRules(this.GridData, this.PolynomialDegree * 3);
            var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData, MaskType.Geometrical))
                           .AddFixedOrderRules(this.GridData, this.PolynomialDegree * 3);

            //var volQrSch = new CellQuadratureScheme(true, CellMask.GetEmptyMask(this.GridData));
            //var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(this.GridData));
            //var edgQrSch = new EdgeQuadratureScheme(true, this.GridData.BoundaryEdges)
            //                        .AddFixedOrderRules(this.GridData, this.PolynomialDegree * 3);
            //var edgQrSch = new EdgeQuadratureScheme(true, this.GridData.BoundaryEdges.Complement())
            //                          .AddFixedOrderRules(this.GridData, this.PolynomialDegree * 3);



            for (int run = 0; run < 1; run++)
            {
                // setup a random test vector
                Random rnd          = new Random();
                var    TestArgument = this.bnd.CloneAs().CoordinateVector;
                for (int i = 0; i < L; i++)
                {
                    TestArgument[i] = rnd.NextDouble();
                }

                Stopwatch lin = new Stopwatch();
                Stopwatch nol = new Stopwatch();

                // linear evaluation
                CoordinateVector LinResult = this.ViscU_linear.CoordinateVector;
                LinResult.Clear();
                lin.Start();
                {
                    var map             = this.U.Mapping;
                    var tempOperatorMtx = new MsrMatrix(map, map);
                    var tempAffine      = new double[L];
                    Operator.ComputeMatrixEx(map, new DGField[] { this.mu }, map,
                                             tempOperatorMtx, tempAffine,
                                             volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch);


                    tempOperatorMtx.SpMVpara(1.0, TestArgument, 0.0, LinResult);
                    LinResult.AccV(1.0, tempAffine);
                }
                lin.Stop();

                // nonliner evaluation
                CoordinateVector NolResult = this.ViscU_nonlinear.CoordinateVector;
                NolResult.Clear();
                nol.Start();
                {
                    var evaluator = Operator.GetEvaluatorEx(TestArgument.Mapping, new DGField[] { this.mu }, this.Residual.Mapping,
                                                            volQrCtx: volQrSch, edgeQrCtx: edgQrSch);
                    evaluator.Evaluate(1.0, 0.0, NolResult);
                }
                nol.Stop();

                double L2Dist = GenericBlas.L2DistPow2(LinResult, NolResult).MPISum().Sqrt();
                Console.WriteLine("L2 dist of linear/Nonlinear evaluation comparison: {0}", L2Dist);

                LinResult.Acc(-1.0, NolResult);

                foreach (SinglePhaseField DGfield in LinResult.Mapping.Fields)
                {
                    for (int p = 0; p <= DGfield.Basis.Degree; p++)
                    {
                        double L2err_p = DGfield.L2NormPerMode(p);
                        Console.WriteLine("   ERR{2} {1} \t{0}", L2err_p, DGfield.Identification, p);
                    }
                }

                Console.WriteLine("Time linear {0}, time nonlinear: {1}", lin.Elapsed, nol.Elapsed);

                Assert.LessOrEqual(L2Dist, 1.0e-4, "L2 distance between linear and nonlinear evaluation of the same flux.");
            }
        }
Exemple #10
0
        protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L)
        {
            using (FuncTrace tr = new FuncTrace()) {
                this.BcMap = new IncompressibleBoundaryCondMap(this.GridData, grid.GetBoundaryConfig(), PhysicsMode.Incompressible);


                // assemble system, create matrix
                // ------------------------------



                int D = GridData.SpatialDimension;
                //double penalty_base = ((double)((U[0].Basis.Degree + 1) * (U[0].Basis.Degree + D))) / ((double)D);
                double penalty_base   = 1.0;
                double penalty_factor = 1.2;



                // equation assembly
                // -----------------
                string[] CodNames = D.ForLoop(i => "C" + i);
                Operator = new SpatialOperator(VariableNames.VelocityVector(D), new string[] { VariableNames.ViscosityMolecular }, CodNames, QuadOrderFunc.Linear());

                for (int d = 0; d < D; d++)
                {
                    if ((this.whichTerms & Terms.T1) != 0)
                    {
                        var flx1 = new swipViscosity_Term1(penalty_base * penalty_factor, d, D, BcMap, ViscosityOption.VariableViscosity);

                        flx1.g_Diri_Override = this.solution.U;
                        flx1.g_Neu_Override  = this.solution.dU;
                        Operator.EquationComponents[CodNames[d]].Add(flx1);
                    }
                    if ((this.whichTerms & Terms.T2) != 0)
                    {
                        var flx2 = new swipViscosity_Term2(penalty_base * penalty_factor, d, D, BcMap, ViscosityOption.VariableViscosity);

                        flx2.g_Diri_Override = this.solution.U;
                        flx2.g_Neu_Override  = this.solution.dU;
                        Operator.EquationComponents[CodNames[d]].Add(flx2);
                    }
                    if ((this.whichTerms & Terms.T3) != 0)
                    {
                        var flx3 = new swipViscosity_Term3(penalty_base * penalty_factor, d, D, BcMap, ViscosityOption.VariableViscosity);

                        flx3.g_Diri_Override = this.solution.U;
                        flx3.g_Neu_Override  = this.solution.dU;
                        Operator.EquationComponents[CodNames[d]].Add(flx3);
                    }
                } // */
                Operator.Commit();


                var map = this.U.Mapping;
                OperatorMtx = new MsrMatrix(map, map);
                Operator.ComputeMatrixEx(map, new DGField[] { this.mu }, map,
                                         OperatorMtx, this.bnd.CoordinateVector,
                                         volQuadScheme: null, edgeQuadScheme: null);

                // test for matrix symmetry
                // ========================

                if (base.MPISize == 1)
                {
                    double MatrixAssymmetry = OperatorMtx.SymmetryDeviation();
                    Console.WriteLine("Matrix asymmetry: " + MatrixAssymmetry);
                    Assert.LessOrEqual(Math.Abs(MatrixAssymmetry), 1.0e-10);
                }
            }
        }
Exemple #11
0
        // Local Variables for Iteration

        // <summary>
        // Counter for Iteration Steps
        // </summary>


        //double OldResidual = double.MaxValue;
        //int divergencecounter = 0;
        ///// <summary>
        ///// Checks for Reaching Max. Number of Iterations and Divergence of Algorithm
        ///// </summary>
        ///// <param name="Residual">Change Rate of the Algorithm</param>
        ///// <returns>Reaching Max Iterations, Aborts when diverged</returns>
        //public bool CheckAbortCriteria(double Residual, int IterationCounter) {
        //    if (Residual <= ConvergenceCriterion) {
        //        Console.WriteLine("EllipticReInit converged after {0} Iterations ", IterationCounter);
        //        return true;
        //    }
        //    if (Residual >= OldResidual) divergencecounter++;
        //    else divergencecounter = 0;
        //    if (IterationCounter >= MaxIteration) {
        //        Console.WriteLine("Elliptic Reinit Max Iterations Reached");
        //        return true;
        //    };
        //    if (divergencecounter > MaxIteration / 2) {
        //        Console.WriteLine("Elliptic Reinit diverged - Aborting");
        //        throw new ApplicationException();
        //    }

        //    OldResidual = Residual;
        //    IterationCounter++;
        //    return false;
        //}


        //bool PreviouslyOnSubgrid = false;

        /// <summary>
        /// Updates the Operator Matrix after level-set motion
        /// </summary>
        /// <param name="Restriction">
        /// The subgrid, on which the ReInit is performed
        /// </param>
        /// <param name="IncludingInterface">
        /// !! Not yet functional !!
        /// True, if the subgrid contains the interface, this causes all external edges of the subgrid to be treated as boundaries
        /// False, for the rest of the domain, thus the flux to the adjacent cells wil be evaluated
        /// </param>
        public void UpdateOperators(SubGrid Restriction = null, bool IncludingInterface = true)
        {
            if (!IncludingInterface)
            {
                throw new NotImplementedException("Untested, not yet functional!");
            }
            using (new FuncTrace()) {
                //using (var slv = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) {
                //using (var slv = new ilPSP.LinSolvers.PARDISO.PARDISOSolver()) {
                //using (var slv = new ilPSP.LinSolvers.HYPRE.GMRES()) {

                if (Control.Upwinding)
                {
                    OldPhi.Clear();
                    OldPhi.Acc(1.0, Phi);
                    //Calculate
                    LevelSetGradient.Clear();
                    LevelSetGradient.Gradient(1.0, Phi, Restriction?.VolumeMask);
                    //LevelSetGradient.Gradient(1.0, Phi);

                    //LevelSetGradient.GradientByFlux(1.0, Phi);
                    MeanLevelSetGradient.Clear();
                    MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient, Restriction?.VolumeMask);
                    //MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient);
                }

                if (slv != null)
                {
                    slv.Dispose();
                }

                slv = Control.solverFactory();

                OpMatrix_interface.Clear();
                OpAffine_interface.Clear();


                // Build the Quadrature-Scheme for the interface operator
                // Note: The HMF-Quadrature over a surface is formally a volume quadrature, since it uses the volume quadrature nodes.
                //XSpatialOperatorExtensions.ComputeMatrixEx(Operator_interface,
                ////Operator_interface.ComputeMatrixEx(
                //    LevelSetTracker,
                //    Phi.Mapping,
                //    null,
                //    Phi.Mapping,
                //    OpMatrix_interface,
                //    OpAffine_interface,
                //    false,
                //    0,
                //    false,
                //    subGrid:Restriction,
                //    whichSpc: LevelSetTracker.GetSpeciesId("A")
                //    );
                XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Operator_interface.GetMatrixBuilder(LevelSetTracker, Phi.Mapping, null, Phi.Mapping);

                MultiphaseCellAgglomerator dummy = LevelSetTracker.GetAgglomerator(LevelSetTracker.SpeciesIdS.ToArray(), Phi.Basis.Degree * 2 + 2, 0.0);
                //mtxBuilder.SpeciesOperatorCoefficients[LevelSetTracker.GetSpeciesId("A")].CellLengthScales = dummy.CellLengthScales[LevelSetTracker.GetSpeciesId("A")];
                mtxBuilder.CellLengthScales.Add(LevelSetTracker.GetSpeciesId("A"), dummy.CellLengthScales[LevelSetTracker.GetSpeciesId("A")]);


                mtxBuilder.time           = 0;
                mtxBuilder.MPITtransceive = false;
                mtxBuilder.ComputeMatrix(OpMatrix_interface, OpAffine_interface);

                // Regenerate OpMatrix for subgrid -> adjacent cells must be trated as boundary
                if (Restriction != null)
                {
                    OpMatrix_bulk.Clear();
                    OpAffine_bulk.Clear();

                    //Operator_bulk.ComputeMatrix(
                    //    Phi.Mapping,
                    //    parameterFields,
                    //    Phi.Mapping,
                    //    OpMatrix_bulk, OpAffine_bulk,
                    //    OnlyAffine: false, sgrd: Restriction);
                    EdgeQuadratureScheme edgescheme;
                    //if (Control.Upwinding) {
                    //    edgescheme = new EdgeQuadratureScheme(true, IncludingInterface ? Restriction.AllEdgesMask : null);
                    //}
                    //else {
                    edgescheme = new EdgeQuadratureScheme(true, IncludingInterface ? Restriction.InnerEdgesMask : null);
                    //}
                    Operator_bulk.ComputeMatrixEx(Phi.Mapping,
                                                  parameterFields,
                                                  Phi.Mapping, OpMatrix_bulk, OpAffine_bulk, false, 0,
                                                  edgeQuadScheme: edgescheme,
                                                  volQuadScheme: new CellQuadratureScheme(true, IncludingInterface ? Restriction.VolumeMask : null)
                                                  );
                    //PreviouslyOnSubgrid = true;
                }
                // recalculate full Matrix
                //else if (PreviouslyOnSubgrid) {
                else
                {
                    OpMatrix_bulk.Clear();
                    OpAffine_bulk.Clear();


                    Operator_bulk.ComputeMatrixEx(Phi.Mapping,
                                                  parameterFields,
                                                  Phi.Mapping, OpMatrix_bulk, OpAffine_bulk, false, 0
                                                  );
                    //PreviouslyOnSubgrid = false;
                }


                /// Compose the Matrix
                /// This is symmetric due to the symmetry of the SIP and the penalty term
                OpMatrix.Clear();
                OpMatrix.Acc(1.0, OpMatrix_bulk);
                OpMatrix.Acc(1.0, OpMatrix_interface);
                OpMatrix.AssumeSymmetric = !Control.Upwinding;
                //OpMatrix.AssumeSymmetric = false;

                /// Compose the RHS of the above operators. (-> Boundary Conditions)
                /// This does NOT include the Nonlinear RHS, which will be added later
                OpAffine.Clear();
                OpAffine.AccV(1.0, OpAffine_bulk);
                OpAffine.AccV(1.0, OpAffine_interface);


#if Debug
                ilPSP.Connectors.Matlab.BatchmodeConnector matlabConnector;
                matlabConnector = new BatchmodeConnector();
#endif

                if (Restriction != null)
                {
                    SubVecIdx = Phi.Mapping.GetSubvectorIndices(Restriction, true, new int[] { 0 });
                    int L = SubVecIdx.Length;
                    SubMatrix   = new MsrMatrix(L);
                    SubRHS      = new double[L];
                    SubSolution = new double[L];

                    OpMatrix.AccSubMatrixTo(1.0, SubMatrix, SubVecIdx, default(int[]), SubVecIdx, default(int[]));

                    slv.DefineMatrix(SubMatrix);
#if Debug
                    Console.WriteLine("ConditionNumber of ReInit-Matrix is " + SubMatrix.condest().ToString("E"));
#endif
                }
                else
                {
                    slv.DefineMatrix(OpMatrix);
#if Debug
                    Console.WriteLine("ConditionNumber of ReInit-Matrix is " + OpMatrix.condest().ToString("E"));
#endif
                }
            }
        }
Exemple #12
0
        /// <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();

                // Stats:
                {
                    int BlkSize       = T.Mapping.MaxTotalNoOfCoordinatesPerCell;
                    int NoOfMtxBlocks = 0;
                    foreach (int[] Neigs in this.GridData.iLogicalCells.CellNeighbours)
                    {
                        NoOfMtxBlocks++;               //               diagonal block
                        NoOfMtxBlocks += Neigs.Length; // off-diagonal block
                    }
                    NoOfMtxBlocks = NoOfMtxBlocks.MPISum();

                    int MtxBlockSize = BlkSize * BlkSize;
                    int MtxSize      = MtxBlockSize * NoOfMtxBlocks;

                    double MtxStorage = MtxSize * (8.0 + 4.0) / (1024 * 1024); // 12 bytes (double+int) per entry

                    Console.WriteLine("   System size:                 {0}", T.Mapping.TotalLength);
                    Console.WriteLine("   No of blocks:                {0}", T.Mapping.TotalNoOfBlocks);
                    Console.WriteLine("   No of blocks in matrix:      {0}", NoOfMtxBlocks);
                    Console.WriteLine("   DG coordinates per cell:     {0}", BlkSize);
                    Console.WriteLine("   Non-zeros per matrix block:  {0}", MtxBlockSize);
                    Console.WriteLine("   Total non-zeros in matrix:   {0}", MtxSize);
                    Console.WriteLine("   Approx. matrix storage (MB): {0}", MtxStorage);


                    base.QueryHandler.ValueQuery("MtxBlkSz", MtxBlockSize, true);
                    base.QueryHandler.ValueQuery("NNZMtx", MtxSize, true);
                    base.QueryHandler.ValueQuery("NNZblk", NoOfMtxBlocks, true);
                    base.QueryHandler.ValueQuery("MtxMB", MtxStorage, true);
                }


                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));

                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);
                }

                stw.Stop();

                //Print process information
                Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds);
                LaplaceMtx.GetMemoryInfo(out long AllocatedMem, out long UsedMem);
                Console.WriteLine("   Used   matrix storage (MB): {0}", UsedMem / (1024.0 * 1024));
                Console.WriteLine("   Alloc. matrix storage (MB): {0}", AllocatedMem / (1024.0 * 1024));
            }
        }
Exemple #13
0
        /// <summary>
        /// Create Spatial Operators and build the corresponding Matrices
        /// </summary>
        public void ComputeMatrices(IList <DGField> InterfaceParams, bool nearfield)
        {
            OpMatrix = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping);
            OpAffine = new double[OpMatrix.RowPartitioning.LocalLength];

            OpMatrix_bulk = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping);
            OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength];

            OpMatrix_interface = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping);
            OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength];


            //LevelSetTracker.GetLevelSetGradients(0,);

            // bulk part of the matrix
            //Operator_bulk.ComputeMatrix(
            //    Extension.Mapping,
            //    LevelSetGradient.ToArray(),
            //    Extension.Mapping,
            //    OpMatrix_bulk, OpAffine_bulk,
            //    OnlyAffine: false, sgrd: null);

            switch (Control.FluxVariant)
            {
            case FluxVariant.GradientBased:
                // Flux Direction based on Mean Level Set Gradient
                BulkParams = new List <DGField> {
                };                                      // Hack, to make ArrayTools.Cat produce a List of DGFields
                // second Hack: Does only work, when InterfaceParams is according to a single component flux,
                // else, we will have to change the boundary edge flux
                BulkParams = ArrayTools.Cat(BulkParams, LevelSetGradient.ToArray(), Phi, MeanLevelSetGradient.ToArray(), InterfaceParams.ToArray());
                MeanLevelSetGradient.Clear();
                MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient);
                break;

            case FluxVariant.ValueBased:
                // Flux Direction Based on Cell-Averaged Level-Set Value
                BulkParams = ArrayTools.Cat(LevelSetGradient.ToArray(), Phi, MeanLevelSet);
                MeanLevelSet.Clear();
                MeanLevelSet.AccLaidBack(1.0, Phi);
                break;

            case FluxVariant.SWIP:
                BulkParams = LevelSetGradient.ToArray();
                break;

            default:
                throw new Exception();
            }

            // Build Operator

            Operator_bulk.ComputeMatrixEx(Extension.Mapping,
                                          BulkParams,
                                          Extension.Mapping,
                                          OpMatrix_bulk, OpAffine_bulk,
                                          OnlyAffine: false,
                                          time: 0.0,
                                          edgeQuadScheme: new EdgeQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).InnerEdgesMask : null),
                                          volQuadScheme: new CellQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).VolumeMask : null)
                                          );

            Operator_interface.ComputeMatrixEx(
                LevelSetTracker,
                Extension.Mapping,
                InterfaceParams,
                Extension.Mapping,
                OpMatrix_interface,
                OpAffine_interface,
                OnlyAffine: false,
                time: 0,
                MPIParameterExchange: false,
                whichSpc: LevelSetTracker.GetSpeciesId("A")
                );
#if DEBUG
            OpMatrix_bulk.CheckForNanOrInfM();
            OpAffine_bulk.CheckForNanOrInfV();

            OpMatrix_interface.CheckForNanOrInfM();
            OpAffine_interface.CheckForNanOrInfV();
#endif

            //Only for Debugging purposes
            //OpMatrix.SaveToTextFileSparse("C:\\tmp\\EllipticReInit.txt");

            Debug.Assert(OpMatrix_interface.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of InterfaceOperator is 0");
            Debug.Assert(OpMatrix_bulk.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of BulkOperator is 0");
#if DEBUG
            //Console.WriteLine( "L2-Norm of Diagonal of InterfaceOperator is {0}", OpMatrix_interface.GetDiagVector().L2Norm() );
#endif
            OpMatrix.Clear();
            OpMatrix.Acc(1.0, OpMatrix_bulk);
            OpMatrix.Acc(1.0, OpMatrix_interface);
            //Console.WriteLine("Op-Matrix Symmetry-Deviation: {0}", OpMatrix.SymmetryDeviation());
            OpMatrix.AssumeSymmetric = false;

            OpAffine.Clear();
            OpAffine.AccV(1.0, OpAffine_bulk);
            OpAffine.AccV(1.0, OpAffine_interface);
#if DEBUG
            //Console.WriteLine("Condition Number of Extension Operator {0}", OpMatrix.condest());
#endif
        }
Exemple #14
0
        /// <summary>
        /// Create Spatial Operators and build the corresponding Matrices
        /// </summary>
        public void ComputeMatrices(IList <DGField> InterfaceParams, bool nearfield)
        {
            OpMatrix = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping);
            OpAffine = new double[OpMatrix.RowPartitioning.LocalLength];

            OpMatrix_bulk = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping);
            OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength];

            OpMatrix_interface = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping);
            OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength];


            //LevelSetTracker.GetLevelSetGradients(0,);

            // bulk part of the matrix
            //Operator_bulk.ComputeMatrix(
            //    Extension.Mapping,
            //    LevelSetGradient.ToArray(),
            //    Extension.Mapping,
            //    OpMatrix_bulk, OpAffine_bulk,
            //    OnlyAffine: false, sgrd: null);

            switch (Control.FluxVariant)
            {
            case FluxVariant.GradientBased:
                // Flux Direction based on Mean Level Set Gradient
                BulkParams = new List <DGField> {
                };                                      // Hack, to make ArrayTools.Cat produce a List of DGFields
                // second Hack: Does only work, when InterfaceParams is according to a single component flux,
                // else, we will have to change the boundary edge flux
                BulkParams = ArrayTools.Cat(BulkParams, LevelSetGradient.ToArray(), Phi, MeanLevelSetGradient.ToArray(), InterfaceParams.ToArray());
                MeanLevelSetGradient.Clear();
                MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient);
                break;

            case FluxVariant.ValueBased:
                // Flux Direction Based on Cell-Averaged Level-Set Value
                BulkParams = ArrayTools.Cat(LevelSetGradient.ToArray(), Phi, MeanLevelSet);
                MeanLevelSet.Clear();
                MeanLevelSet.AccLaidBack(1.0, Phi);
                break;

            case FluxVariant.SWIP:
                BulkParams = LevelSetGradient.ToArray();
                break;

            default:
                throw new Exception();
            }

            // Build Operator

            Operator_bulk.ComputeMatrixEx(Extension.Mapping,
                                          BulkParams,
                                          Extension.Mapping,
                                          OpMatrix_bulk, OpAffine_bulk,
                                          OnlyAffine: false,
                                          time: 0.0,
                                          edgeQuadScheme: new EdgeQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).InnerEdgesMask : null),
                                          volQuadScheme: new CellQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).VolumeMask : null)
                                          );



            //Operator_interface.ComputeMatrixEx(
            //    LevelSetTracker,
            //    Extension.Mapping,
            //    InterfaceParams,
            //    Extension.Mapping,
            //    OpMatrix_interface,
            //    OpAffine_interface,
            //    OnlyAffine: false,
            //    time: 0,
            //    MPIParameterExchange: false,
            //    whichSpc: LevelSetTracker.GetSpeciesId("A")
            //    );

            Operator_interface.OperatorCoefficientsProvider =
                delegate(LevelSetTracker lstrk, SpeciesId spc, int quadOrder, int TrackerHistoryIdx, double time) {
                var r = new CoefficientSet()
                {
                };

                //throw new NotImplementedException("todo");
                return(r);
            };
            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Operator_interface.GetMatrixBuilder(LevelSetTracker,
                                                                                                  Extension.Mapping, InterfaceParams, Extension.Mapping);

            MultiphaseCellAgglomerator dummy = LevelSetTracker.GetAgglomerator(LevelSetTracker.SpeciesIdS.ToArray(), 2 * Extension.Basis.Degree + 2, 0.0);

            mtxBuilder.CellLengthScales.Add(LevelSetTracker.GetSpeciesId("A"), dummy.CellLengthScales[LevelSetTracker.GetSpeciesId("A")]);

            mtxBuilder.time           = 0;
            mtxBuilder.MPITtransceive = false;
            mtxBuilder.ComputeMatrix(OpMatrix_interface, OpAffine_interface);

#if DEBUG
            OpMatrix_bulk.CheckForNanOrInfM();
            OpAffine_bulk.CheckForNanOrInfV();

            OpMatrix_interface.CheckForNanOrInfM();
            OpAffine_interface.CheckForNanOrInfV();
#endif

            //Only for Debugging purposes

            Debug.Assert(OpMatrix_interface.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of InterfaceOperator is 0");
            Debug.Assert(OpMatrix_bulk.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of BulkOperator is 0");
#if DEBUG
            //Console.WriteLine( "L2-Norm of Diagonal of InterfaceOperator is {0}", OpMatrix_interface.GetDiagVector().L2Norm() );
#endif
            OpMatrix.Clear();
            OpMatrix.Acc(1.0, OpMatrix_bulk);
            OpMatrix.Acc(1.0, OpMatrix_interface);
            //Console.WriteLine("Op-Matrix Symmetry-Deviation: {0}", OpMatrix.SymmetryDeviation());
            OpMatrix.AssumeSymmetric = false;

            OpAffine.Clear();
            OpAffine.AccV(1.0, OpAffine_bulk);
            OpAffine.AccV(1.0, OpAffine_interface);
#if DEBUG
            //Console.WriteLine("Condition Number of Extension Operator {0}", OpMatrix.condest());
#endif
        }
Exemple #15
0
        /// <summary>
        /// Includes assembly of the matrix.
        /// </summary>
        /// <param name="L"></param>
        protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L)
        {
            using (FuncTrace tr = new FuncTrace()) {
                // create operator
                // ===============
                SpatialOperator LapaceIp;
                {
                    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, this.GridData.Cells.cj, PoissonBcMap);
                    LapaceIp.EquationComponents["T"].Add(flux);

                    LapaceIp.Commit();
                }

                // Create Matrices
                // ===============

                {
                    // 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));
                    var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData));

#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);
                }


                //double condNo = LaplaceMtx.condest(BatchmodeConnector.Flavor.Octave);
                //Console.WriteLine("condition number: {0:0.####E-00} ",condNo);
            }
        }