Beispiel #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);
                }
            }
        }
Beispiel #2
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            //phystime = 1.8;
            LsUpdate(phystime);

            // operator-matrix assemblieren
            OperatorMatrix    = new BlockMsrMatrix(ProblemMapping);
            AltOperatorMatrix = new MsrMatrix(ProblemMapping);
            double[] Affine = new double[OperatorMatrix.RowPartitioning.LocalLength];
            MultiphaseCellAgglomerator Agg;

            // Agglomerator setup
            //Agg = new MultiphaseCellAgglomerator(new CutCellMetrics(MomentFittingVariant, m_quadOrder, LsTrk, LsTrk.GetSpeciesId("B")), this.THRESHOLD, false);
            Agg = LsTrk.GetAgglomerator(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, m_quadOrder, __AgglomerationTreshold: this.THRESHOLD);
            Console.WriteLine("Inter-Process agglomeration? " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.InterProcessAgglomeration);

            // operator matrix assembly
            //Op.ComputeMatrixEx(LsTrk,
            //    ProblemMapping, null, ProblemMapping,
            //    OperatorMatrix, Affine, false, 0.0, true,
            //    Agg.CellLengthScales, null, null,
            //    LsTrk.SpeciesIdS.ToArray());
            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, ProblemMapping, null, ProblemMapping, LsTrk.SpeciesIdS.ToArray());
            mtxBuilder.time = 0.0;
            mtxBuilder.ComputeMatrix(OperatorMatrix, Affine);
            Agg.ManipulateMatrixAndRHS(OperatorMatrix, Affine, this.ProblemMapping, this.ProblemMapping);

            //Op.ComputeMatrixEx(LsTrk,
            //    ProblemMapping, null, ProblemMapping,
            //    AltOperatorMatrix, Affine, false, 0.0, true,
            //    Agg.CellLengthScales, null, null,
            //    LsTrk.SpeciesIdS.ToArray());
            mtxBuilder.ComputeMatrix(AltOperatorMatrix, Affine);
            Agg.ManipulateMatrixAndRHS(AltOperatorMatrix, Affine, this.ProblemMapping, this.ProblemMapping);


            int nnz = this.OperatorMatrix.GetTotalNoOfNonZeros();

            Console.WriteLine("Number of non-zeros in matrix: " + nnz);

            int nnz2 = this.AltOperatorMatrix.GetTotalNoOfNonZeros();

            Assert.IsTrue(nnz == nnz2, "Number of non-zeros in matrix different for " + OperatorMatrix.GetType() + " and " + AltOperatorMatrix.GetType());
            Console.WriteLine("Number of non-zeros in matrix (reference): " + nnz2);

            MsrMatrix Comp = AltOperatorMatrix.CloneAs();

            Comp.Acc(-1.0, OperatorMatrix);
            double CompErr    = Comp.InfNorm();
            double Denom      = Math.Max(AltOperatorMatrix.InfNorm(), OperatorMatrix.InfNorm());
            double CompErrRel = Denom > Math.Sqrt(double.Epsilon) ? CompErr / Denom : CompErr;

            Console.WriteLine("Comparison: " + CompErrRel);

            Assert.LessOrEqual(CompErrRel, 1.0e-7, "Huge difference between MsrMatrix and BlockMsrMatrix.");

            base.TerminationKey = true;
            return(0.0);
        }
Beispiel #3
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);
            }
        }
Beispiel #4
0
        public void VelocityPredictor(double[] PressureEstimateIn, double[] VelocityEstimateIn, double[] VelocityPrediction, double[] RHSMomentum)
        {
            using (new FuncTrace()) {
                double m_relax_vel = m_SIMPLEOptions.relax_v;

                //build Matrix
                var PredictorMX = ConvDiff.CloneAs();


                //underrelaxation LHS
                if (m_relax_vel <= 0.0)
                {
                    throw new ArithmeticException("Illegal velocity underrelaxation parameter: " + m_relax_vel);
                }

                PredictorMX.Acc((1 - m_relax_vel) / m_relax_vel, Aapprox);


#if DEBUG
                PredictorMX.CheckForNanOrInfM();
#endif


                // build RHS: b1-grad*p (+ oldVelocities/dt)
                double[] RHS = new double [RHSMomentum.Length];
                RHS.AccV(1.0, RHSMomentum);
                PressureGrad.SpMVpara(-1.0, PressureEstimateIn, 1.0, RHS);

                //underrelaxation RHS
                Aapprox.SpMVpara((1 - m_relax_vel) / m_relax_vel, VelocityEstimateIn, 1.0, RHS);

                // solve
                using (ISparseSolver solver = m_SIMPLEOptions.ViscousSolver) {
                    //Agglomerator.ClearAgglomerated(RHS, VelocityMapping);
                    //double SolverResidual = PC.SolveDirect(VelocityPrediction.CoordinateVector, RHS, solver, false);
                    //solver.Dispose();
                    solver.DefineMatrix(PredictorMX);
                    solver.Solve(VelocityPrediction, RHS);
                }
            }
        }
Beispiel #5
0
        public void Init(MultigridOperator op)
        {
            int D     = op.Mapping.GridData.SpatialDimension;
            var M     = op.OperatorMatrix;
            var MgMap = op.Mapping;

            this.m_mgop = op;

            if (!M.RowPartitioning.EqualsPartition(MgMap.Partitioning))
            {
                throw new ArgumentException("Row partitioning mismatch.");
            }
            if (!M.ColPartition.EqualsPartition(MgMap.Partitioning))
            {
                throw new ArgumentException("Column partitioning mismatch.");
            }

            Uidx = MgMap.ProblemMapping.GetSubvectorIndices(true, D.ForLoop(i => i));
            Pidx = MgMap.ProblemMapping.GetSubvectorIndices(true, D);

            int Upart = Uidx.Length;
            int Ppart = Pidx.Length;

            ConvDiff = new MsrMatrix(Upart, Upart, 1, 1);
            pGrad    = new MsrMatrix(Upart, Ppart, 1, 1);
            divVel   = new MsrMatrix(Ppart, Upart, 1, 1);
            var PxP = new MsrMatrix(Ppart, Ppart, 1, 1);

            M.AccSubMatrixTo(1.0, ConvDiff, Uidx, default(int[]), Uidx, default(int[]));
            M.AccSubMatrixTo(1.0, pGrad, Uidx, default(int[]), Pidx, default(int[]));
            M.AccSubMatrixTo(1.0, divVel, Pidx, default(int[]), Uidx, default(int[]));
            M.AccSubMatrixTo(1.0, PxP, Pidx, default(int[]), Pidx, default(int[]));

            Mtx = M;

            int L = M.RowPartitioning.LocalLength;

            int i0 = Mtx.RowPartitioning.i0;

            P = new MsrMatrix(Mtx);
            P.Clear();

            // Debugging output
            //ConvDiff.SaveToTextFileSparse("ConvDiff");
            //divVel.SaveToTextFileSparse("divVel");
            //pGrad.SaveToTextFileSparse("pGrad");
            //PxP.SaveToTextFileSparse("PxP");


            velMassMatrix = new MsrMatrix(Upart, Upart, 1, 1);
            op.MassMatrix.AccSubMatrixTo(1.0, velMassMatrix, Uidx, default(int[]), Uidx, default(int[]));

            switch (SchurOpt)
            {
            case SchurOptions.exact:
            {
                // Building complete Schur and Approximate Schur
                MultidimensionalArray Poisson       = MultidimensionalArray.Create(Pidx.Length, Pidx.Length);
                MultidimensionalArray SchurConvPart = MultidimensionalArray.Create(Pidx.Length, Pidx.Length);
                MultidimensionalArray Schur         = MultidimensionalArray.Create(Pidx.Length, Pidx.Length);
                using (BatchmodeConnector bmc = new BatchmodeConnector())
                {
                    bmc.PutSparseMatrix(ConvDiff, "ConvDiff");
                    bmc.PutSparseMatrix(velMassMatrix, "MassMatrix");
                    bmc.PutSparseMatrix(divVel, "divVel");
                    bmc.PutSparseMatrix(pGrad, "pGrad");
                    bmc.Cmd("Qdiag = diag(diag(MassMatrix))");
                    bmc.Cmd("invT= inv(Qdiag)");
                    bmc.Cmd("Poisson = full(invT)*pGrad");
                    bmc.Cmd("ConvPart = ConvDiff*Poisson");
                    bmc.Cmd("ConvPart= full(invT)*ConvPart");
                    bmc.Cmd("ConvPart= divVel*ConvPart");
                    bmc.Cmd("Poisson = divVel*Poisson");
                    bmc.Cmd("ConvDiffInv = inv(full(ConvDiff))");
                    bmc.Cmd("Schur = divVel*ConvDiffInv");
                    bmc.Cmd("Schur = Schur*pGrad");
                    bmc.GetMatrix(Poisson, "Poisson");
                    bmc.GetMatrix(SchurConvPart, "ConvPart");
                    bmc.GetMatrix(Schur, "-Schur");
                    bmc.Execute(false);
                }
                PoissonMtx_T = Poisson.ToMsrMatrix();
                PoissonMtx_H = Poisson.ToMsrMatrix();
                SchurConvMtx = SchurConvPart.ToMsrMatrix();
                SchurMtx     = Schur.ToMsrMatrix();
                SchurMtx.Acc(PxP, 1);

                ConvDiff.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Uidx);
                pGrad.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Pidx);
                SchurMtx.AccSubMatrixTo(1.0, P, default(int[]), Pidx, default(int[]), Pidx);
                return;
            }

            case SchurOptions.decoupledApprox:
            {
                // Do assembly for approximate Schur inverse
                invVelMassMatrix = velMassMatrix.CloneAs();
                invVelMassMatrix.Clear();
                invVelMassMatrixSqrt = invVelMassMatrix.CloneAs();
                for (int i = velMassMatrix.RowPartitioning.i0; i < velMassMatrix.RowPartitioning.iE; i++)
                {
                    if (ApproxScaling)
                    {
                        invVelMassMatrix.SetDiagonalElement(i, 1 / (velMassMatrix[i, i]));
                        invVelMassMatrixSqrt.SetDiagonalElement(i, 1 / (Math.Sqrt(velMassMatrix[i, i])));
                    }
                    else
                    {
                        invVelMassMatrix.SetDiagonalElement(i, 1);
                        invVelMassMatrixSqrt.SetDiagonalElement(i, 1);
                    }
                }

                //invVelMassMatrix.SaveToTextFileSparse("invVelMassMatrix");
                //velMassMatrix.SaveToTextFileSparse("velMassMatrix");


                //ConvDiffPoissonMtx = MsrMatrix.Multiply(ConvDiff, pGrad);
                //ConvDiffPoissonMtx = MsrMatrix.Multiply(divVel, ConvDiffPoissonMtx);

                // Inverse of mass matrix in Matlab
                //MultidimensionalArray temp = MultidimensionalArray.Create(Uidx.Length, Uidx.Length);
                //using (BatchmodeConnector bmc = new BatchmodeConnector())
                //{
                //    bmc.PutSparseMatrix(velMassMatrix, "velMassMatrix");
                //    bmc.Cmd("invVelMassMatrix = inv(full(velMassMatrix))");
                //    bmc.GetMatrix(temp, "invVelMassMatrix");
                //    bmc.Execute(false);
                //}
                //invVelMassMatrix = temp.ToMsrMatrix();

                //ConvDiffPoissonMtx = MsrMatrix.Multiply(ConvDiffPoissonMtx, PoissonMtx);
                //ConvDiffPoissonMtx = MsrMatrix.Multiply(PoissonMtx, ConvDiffPoissonMtx);

                //ConvDiff.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Uidx);
                //pGrad.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Pidx);
                //ConvDiffPoissonMtx.AccSubMatrixTo(1.0, P, default(int[]), Pidx, default(int[]), Pidx);

                //op.MassMatrix.SaveToTextFileSparse("MassMatrix");
                //velMassMatrix.SaveToTextFileSparse("velMassMatrix2");


                // Possion scaled by inverse of the velocity mass matrix
                PoissonMtx_T = MsrMatrix.Multiply(invVelMassMatrix, pGrad);
                PoissonMtx_T = MsrMatrix.Multiply(divVel, PoissonMtx_T);
                ////PoissonMtx_T.Acc(PxP, 1); // p.379

                // Poisson scaled by sqrt of inverse of velocity mass matrix
                PoissonMtx_H = MsrMatrix.Multiply(invVelMassMatrixSqrt, pGrad);
                PoissonMtx_H = MsrMatrix.Multiply(divVel, PoissonMtx_H);
                //PoissonMtx_H.Acc(PxP, 1); // p.379
                return;
            }

            case SchurOptions.SIMPLE:
            {
                var invdiag_ConvDiff = ConvDiff.CloneAs();
                invdiag_ConvDiff.Clear();
                for (int i = ConvDiff.RowPartitioning.i0; i < ConvDiff.RowPartitioning.iE; i++)
                {
                    invdiag_ConvDiff[i, i] = 1 / ConvDiff[i, i];
                }

                simpleSchur = MsrMatrix.Multiply(invdiag_ConvDiff, pGrad);
                simpleSchur = MsrMatrix.Multiply(divVel, simpleSchur);

                return;
            }

            default:
                throw new NotImplementedException("SchurOption");
            }


            //var ConvDiffInvMtx = ConvDiffInv.ToMsrMatrix();


            //// x= inv(P)*b !!!!! To be done with approximate Inverse
            // P.SpMV(1, B, 0, X);
        }
Beispiel #6
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            LsUpdate(phystime);

            // operator-matrix assemblieren
            OperatorMatrix    = new BlockMsrMatrix(MG_Mapping.ProblemMapping);
            AltOperatorMatrix = new MsrMatrix(MG_Mapping.ProblemMapping);
            double[] Affine = new double[OperatorMatrix.RowPartitioning.LocalLength];
            MultiphaseCellAgglomerator Agg;

            Agg = LsTrk.GetAgglomerator(this.LsTrk.SpeciesIdS.ToArray(), m_quadOrder, __AgglomerationTreshold: this.THRESHOLD);

            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, MG_Mapping.ProblemMapping, null, MG_Mapping.ProblemMapping);
            mtxBuilder.time = 0.0;
            mtxBuilder.ComputeMatrix(OperatorMatrix, Affine);
            Agg.ManipulateMatrixAndRHS(OperatorMatrix, Affine, MG_Mapping.ProblemMapping, MG_Mapping.ProblemMapping);

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


            MGOp = new MultigridOperator(XAggB, map,
                                         OperatorMatrix,
                                         this.massFact.GetMassMatrix(map, false),
                                         OpConfig, null);
            Debug.Assert(MGOp.OperatorMatrix != null);
            Debug.Assert(MGOp.Mapping != null);

            someVec = GetRHS(Affine, OperatorMatrix);

            mtxBuilder.ComputeMatrix(AltOperatorMatrix, Affine);
            Agg.ManipulateMatrixAndRHS(AltOperatorMatrix, Affine, MG_Mapping.ProblemMapping, MG_Mapping.ProblemMapping);


            //LsTrk.GetSpeciesName(((XdgAggregationBasis)MGOp.Mapping.AggBasis[0]).UsedSpecies[1]);
            //LsTrk.GetSpeciesName(((XdgAggregationBasis)MGOp.Mapping.AggBasis[0]).UsedSpecies[0]);

            int nnz = this.OperatorMatrix.GetTotalNoOfNonZeros();

            Console.WriteLine("Number of non-zeros in matrix: " + nnz);

            int nnz2 = this.AltOperatorMatrix.GetTotalNoOfNonZeros();

            Assert.IsTrue(nnz == nnz2, "Number of non-zeros in matrix different for " + OperatorMatrix.GetType() + " and " + AltOperatorMatrix.GetType());
            Console.WriteLine("Number of non-zeros in matrix (reference): " + nnz2);

            MsrMatrix Comp = AltOperatorMatrix.CloneAs();

            Comp.Acc(-1.0, OperatorMatrix);
            double CompErr    = Comp.InfNorm();
            double Denom      = Math.Max(AltOperatorMatrix.InfNorm(), OperatorMatrix.InfNorm());
            double CompErrRel = Denom > Math.Sqrt(double.Epsilon) ? CompErr / Denom : CompErr;

            Console.WriteLine("Comparison: " + CompErrRel);

            Assert.LessOrEqual(CompErrRel, 1.0e-7, "Huge difference between MsrMatrix and BlockMsrMatrix.");

            base.TerminationKey = true;
            return(0.0);
        }
Beispiel #7
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);
            }
        }