Exemple #1
0
        void TestAgglomeration_Extraploation(MultiphaseCellAgglomerator Agg)
        {
            _2D SomePolynomial;

            if (this.u.Basis.Degree == 0)
            {
                SomePolynomial = (x, y) => 3.2;
            }
            else if (this.u.Basis.Degree == 1)
            {
                SomePolynomial = (x, y) => 3.2 + x - 2.4 * y;
            }
            else
            {
                SomePolynomial = (x, y) => x * x + y * y;
            }

            // ========================================================
            // extrapolate polynomial function for species B of a XDG-field
            // ========================================================


            var Bmask = LsTrk.Regions.GetSpeciesMask("B");

            XDGField xt = new XDGField(new XDGBasis(this.LsTrk, this.u.Basis.Degree), "XDG-test");

            xt.GetSpeciesShadowField("B").ProjectField(1.0,
                                                       SomePolynomial.Vectorize(),
                                                       new CellQuadratureScheme(true, Bmask));


            double[] bkupVec = xt.CoordinateVector.ToArray();

            Agg.ClearAgglomerated(xt.Mapping);
            Agg.Extrapolate(xt.Mapping);

            double Err = GenericBlas.L2DistPow2(bkupVec, xt.CoordinateVector).MPISum().Sqrt();

            Console.WriteLine("Agglom: extrapolation error: " + Err);
            Assert.LessOrEqual(Err, 1.0e-10);

            // ========================================================
            // extrapolate polynomial function for a single-phase-field
            // ========================================================

            SinglePhaseField xt2 = new SinglePhaseField(this.u.Basis, "DG-test");

            xt2.ProjectField(SomePolynomial);

            double[] bkupVec2 = xt2.CoordinateVector.ToArray();

            Agg.ClearAgglomerated(xt2.Mapping);
            Agg.Extrapolate(xt2.Mapping);

            double Err2 = GenericBlas.L2DistPow2(bkupVec, xt.CoordinateVector).MPISum().Sqrt();

            Console.WriteLine("Agglom: extrapolation error: " + Err2);
            Assert.LessOrEqual(Err2, 1.0e-10);
        }
Exemple #2
0
        /// <summary>
        /// Updates the XDG component of an aggregation basis according to the new aggomeration.
        /// </summary>
        public static void UpdateXdgAggregationBasis(this AggregationGridBasis[][] MultigridBasis, MultiphaseCellAgglomerator CurrentAgglomeration)
        {
            bool useX = false;
            var  _XdgAggregationBasis = new XdgAggregationBasis[MultigridBasis.Length];

            for (int iLevel = 0; iLevel < MultigridBasis.Length; iLevel++)
            {
                XdgAggregationBasis[] xab = MultigridBasis[iLevel].Where(b => b is XdgAggregationBasis).Select(b => ((XdgAggregationBasis)b)).ToArray();
                if (xab != null && xab.Length > 0)
                {
                    for (int ib = 1; ib < xab.Length; ib++)
                    {
                        if (!(object.ReferenceEquals(xab[ib].DGBasis.GridDat, CurrentAgglomeration.Tracker.GridDat)))
                        {
                            throw new ApplicationException();
                        }
                        if (!object.ReferenceEquals(xab[0], xab[ib]))
                        {
                            throw new ArgumentException("One should only use one XDG aggregation basis per multigrid level.");
                        }
                    }
                    _XdgAggregationBasis[iLevel] = xab[0];
                    useX = true;
                }
            }

            if (useX)
            {
                foreach (var xmgb in _XdgAggregationBasis)
                {
                    xmgb.Update(CurrentAgglomeration);
                }
            }
        }
Exemple #3
0
        void TestAgglomeration_Projection(int quadOrder, MultiphaseCellAgglomerator Agg)
        {
            var Bmask      = LsTrk.Regions.GetSpeciesMask("B");
            var BbitMask   = Bmask.GetBitMask();
            var XDGmetrics = LsTrk.GetXDGSpaceMetrics(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, quadOrder, 1);

            int degree = Math.Max(0, this.u.Basis.Degree - 1);

            _2D SomePolynomial;

            if (degree == 0)
            {
                SomePolynomial = (x, y) => 3.2;
            }
            else if (degree == 1)
            {
                SomePolynomial = (x, y) => 3.2 + x - 2.4 * y;
            }
            else
            {
                SomePolynomial = (x, y) => x * x + y * y;
            }

            // ------------------------------------------------
            // project the polynomial onto a single-phase field
            // ------------------------------------------------
            SinglePhaseField NonAgglom = new SinglePhaseField(new Basis(this.GridData, degree), "NonAgglom");

            NonAgglom.ProjectField(1.0,
                                   SomePolynomial.Vectorize(),
                                   new CellQuadratureScheme(true, Bmask));

            // ------------------------------------------------
            // project the polynomial onto the aggomerated XDG-field
            // ------------------------------------------------

            var qsh = XDGmetrics.XQuadSchemeHelper;

            // Compute the inner product of 'SomePolynomial' with the cut-cell-basis, ...
            SinglePhaseField xt = new SinglePhaseField(NonAgglom.Basis, "test");

            xt.ProjectField(1.0,
                            SomePolynomial.Vectorize(),
                            qsh.GetVolumeQuadScheme(this.LsTrk.GetSpeciesId("B")).Compile(this.GridData, Agg.CutCellQuadratureOrder));

            CoordinateMapping map = xt.Mapping;

            // ... change to the cut-cell-basis, ...
            double[] xVec = xt.CoordinateVector.ToArray();
            Agg.ManipulateMatrixAndRHS(default(MsrMatrix), xVec, map, null);

            {
                double[] xVec2 = xVec.CloneAs();
                Agg.ClearAgglomerated(xVec2, map); // clearing should have no effect now.

                double Err3 = GenericBlas.L2DistPow2(xVec, xVec2).MPISum().Sqrt();
                Assert.LessOrEqual(Err3, 0.0);
            }

            // ... multiply with the inverse mass-matrix, ...
            var            Mfact   = XDGmetrics.MassMatrixFactory;
            BlockMsrMatrix MassMtx = Mfact.GetMassMatrix(map, false);

            Agg.ManipulateMatrixAndRHS(MassMtx, default(double[]), map, map);
            var InvMassMtx = MassMtx.InvertBlocks(OnlyDiagonal: true, Subblocks: true, ignoreEmptyBlocks: true, SymmetricalInversion: true);

            double[] xAggVec = new double[xVec.Length];

            InvMassMtx.SpMV(1.0, xVec, 0.0, xAggVec);

            // ... and extrapolate.
            // Since we projected a polynomial, the projection is exact and after extrapolation, must be equal
            // to the polynomial.
            xt.CoordinateVector.SetV(xAggVec);
            Agg.Extrapolate(xt.Mapping);

            // ------------------------------------------------
            // check the error
            // ------------------------------------------------


            //double Err2 = xt.L2Error(SomePolynomial.Vectorize(), new CellQuadratureScheme(domain: Bmask));
            double Err2 = NonAgglom.L2Error(xt);

            Console.WriteLine("Agglom: projection and extrapolation error: " + Err2);
            Assert.LessOrEqual(Err2, 1.0e-10);
        }
Exemple #4
0
        /// <summary>
        /// defines how species in the agglomerated cells
        /// map to species in the base grid cells.
        /// </summary>
        private void UpdateSpeciesMapping(MultiphaseCellAgglomerator Agglomerator)
        {
            Debug.Assert(object.ReferenceEquals(Agglomerator.Tracker, this.XDGBasis.Tracker));
            var LsTrk         = this.XDGBasis.Tracker;
            int GlobalNoOfSpc = LsTrk.SpeciesIdS.Count;
            var agg           = base.AggGrid;

            int[][] compCells = agg.iLogicalCells.AggregateCellToParts;
            int     JAGG      = compCells.Length;

            Debug.Assert(JAGG == agg.iLogicalCells.Count);
            int JAGGup = agg.iLogicalCells.NoOfLocalUpdatedCells;

            this.UsedSpecies = Agglomerator.SpeciesList.ToArray();

            if (NoOfSpecies == null)
            {
                NoOfSpecies         = new int[JAGG];
                SpeciesIndexMapping = new int[JAGG][, ];
            }
            else
            {
                Debug.Assert(NoOfSpecies.Length == JAGG);
                Array.Clear(NoOfSpecies, 0, JAGG);
            }

            if (AggCellsSpecies == null)
            {
                AggCellsSpecies = new SpeciesId[JAGG][];
            }
            //if (CoarseToFineSpeciesIndex == null && agg.MgLevel > 0)
            //    CoarseToFineSpeciesIndex = new int[JAGG][,];


            Dictionary <SpeciesId, BitArray> agglomeratedCells = new Dictionary <SpeciesId, BitArray>();

            foreach (var SpId in Agglomerator.SpeciesList)
            {
                agglomeratedCells.Add(SpId, Agglomerator.GetAgglomerator(SpId).AggInfo.SourceCells.GetBitMaskWithExternal());
            }

            // temp buffer
            int[] _NoOfSpecies                    = new int[agg.jCellCoarse2jCellFine[0].Length];
            ReducedRegionCode[] _RRcs             = new ReducedRegionCode[agg.iLogicalCells.AggregateCellToParts[0].Length];
            SpeciesId[]         allPresentSpecies = new SpeciesId[LsTrk.TotalNoOfSpecies];

            // loop over all aggregate (multigrid) cells...
            for (int jagg = 0; jagg < JAGGup; jagg++)
            {
                int[] compCell = compCells[jagg];
                int   K        = compCell.Length;

                // buffer sizes
                if (K > _NoOfSpecies.Length)
                {
                    int newLen = (int)Math.Ceiling(K * 1.2);
                    Array.Resize(ref _NoOfSpecies, newLen);
                    Array.Resize(ref _RRcs, newLen);
                }

                // check no of species:
                int MaxNoOfSpecies = 0;     // number of species in the composite cell
                for (int k = 0; k < K; k++) // loop over original cells in composite cell
                {
                    int jCell = compCell[k];
                    _NoOfSpecies[k] = LsTrk.Regions.GetNoOfSpecies(jCell, out _RRcs[k]);
                    MaxNoOfSpecies  = Math.Max(_NoOfSpecies[k], MaxNoOfSpecies);
                }

                if (MaxNoOfSpecies == 1)
                {
                    // only one species -- use single-phase implementation in underlying class

                    this.SpeciesIndexMapping[jagg] = null;
                    this.NoOfSpecies[jagg]         = 1;
                    //this.XCompositeBasis[jagg] = null;
                    this.AggCellsSpecies[jagg] = null;
                    //this.CoarseToFineSpeciesIndex[jagg] = null;
                }
                else
                {
                    //LsTrk.ContainesSpecies

                    int w = 0; // counter for found species

                    if (this.SpeciesIndexMapping[jagg] == null || this.SpeciesIndexMapping[jagg].GetLength(0) != w)
                    {
                        this.SpeciesIndexMapping[jagg] = new int[0, compCell.Length];
                    }
                    ArrayTools.SetAll(this.SpeciesIndexMapping[jagg], -897645);


                    // collect all species which are present in the composite cell 'jagg':
                    // -------------------------------------------------------------------
                    for (int k = 0; k < K; k++)  // loop over all base cells in the aggregate cell 'jagg'
                    {
                        var rrc   = _RRcs[k];
                        int jCell = compCell[k]; // base cell index

                        for (int iSpc = _NoOfSpecies[k] - 1; iSpc >= 0; iSpc--)
                        {
                            SpeciesId spId           = LsTrk.GetSpeciesIdFromIndex(rrc, iSpc);
                            bool      isPresent      = LsTrk.Regions.IsSpeciesPresentInCell(spId, jCell);
                            bool      isAgglomerated = agglomeratedCells.ContainsKey(spId) ? agglomeratedCells[spId][jCell] : false;
                            bool      isUsed         = Array.IndexOf(this.UsedSpecies, spId) >= 0;

                            if (isUsed && isPresent && !isAgglomerated)
                            {
                                bool bfound = false;

                                int z;
                                for (z = 0; z < w; z++)  // loop over species found so far...
                                {
                                    if (allPresentSpecies[z] == spId)
                                    {
                                        bfound = true;
                                        break;
                                    }
                                }
                                if (!bfound)
                                {
                                    // species not found -> add to list
                                    allPresentSpecies[w] = spId;
                                    z = w;
                                    w++;
                                }

                                // z    is the species index in the composite cell
                                // iSpc is the species index in 'jCell'
                                Resize2DArray(ref this.SpeciesIndexMapping[jagg], w, K, -897645);
                                this.SpeciesIndexMapping[jagg][z, k] = iSpc;
                            }
                        }
                    }

                    this.AggCellsSpecies[jagg] = allPresentSpecies.GetSubVector(0, w);
                    this.NoOfSpecies[jagg]     = w;
                    Debug.Assert(this.NoOfSpecies[jagg] == this.SpeciesIndexMapping[jagg].GetLength(0));
                }
                Debug.Assert(this.NoOfSpecies[jagg] >= 0);
                Debug.Assert(this.NoOfSpecies[jagg] <= this.UsedSpecies.Length);
            }

            // MPI exchange for external cells
            // note: external aggregation cells may be incomplete, i.e. not have all parts, only those known to parent
            NoOfSpecies.MPIExchange(this.AggGrid);
        }
Exemple #5
0
        public void Update(MultiphaseCellAgglomerator Agglomerator)
        {
            using (new FuncTrace()) {
                //if(!this.XDGBasis.IsSubBasis(mmf.MaxBasis))
                //    throw new ArgumentException();

                var LsTrk = this.XDGBasis.Tracker;
                var CCBit = LsTrk.Regions.GetCutCellMask().GetBitMask();

                int N    = this.DGBasis.Length;
                int JAGG = base.AggGrid.iLogicalCells.NoOfLocalUpdatedCells;
                UpdateSpeciesMapping(Agglomerator);



                // mass matrix in the aggregate cell, before we orthonormalize:
                var AggCellMMb4Ortho = MultidimensionalArray.Create(N, N);

                for (int jagg = 0; jagg < JAGG; jagg++)
                {
                    int   NoOfSpc_jagg = this.NoOfSpecies[jagg];
                    int[] AggCell      = base.AggGrid.iLogicalCells.AggregateCellToParts[jagg];
                    int   K            = AggCell.Length;

                    int[,] sim = this.SpeciesIndexMapping[jagg];
                    Debug.Assert((sim == null) || (sim.GetLength(0) == NoOfSpc_jagg));
                    Debug.Assert((sim == null) || (sim.GetLength(1) == K));


                    if (sim == null)
                    {
                        // nothing to do.
                        // +++++++++++++++++++++++++++++++++++++++++++++++

                        this.XCompositeBasis[jagg] = null;
                    }
                    else
                    {
                        // the cut-cell may require some special treatment
                        // +++++++++++++++++++++++++++++++++++++++++++++++


                        for (int iSpc_agg = 0; iSpc_agg < NoOfSpc_jagg; iSpc_agg++)  // loop over all species in aggregate cell

                        {
                            bool emptyCell = false; // true: at least one of the base cells which form
                            //                         aggregate cell 'jagg' is empty with respect to the 'iSpc_agg'--th species.
                            //                         => this will alter the projection operator.
                            for (int k = 0; k < K; k++)
                            {
                                if (sim[iSpc_agg, k] < 0)
                                {
                                    emptyCell = true;
                                    break;
                                }
                            }
#if DEBUG
                            {
                                bool NonEmpty = false;
                                for (int k = 0; k < K; k++)
                                {
                                    if (sim[iSpc_agg, k] >= 0)
                                    {
                                        NonEmpty = true;
                                        break;
                                    }
                                }
                                Debug.Assert(NonEmpty); // there should be at least one non-empty base cell (for species 'iSpc_agg')
                                //                         in aggregate cell 'jagg'
                            }
#endif

                            if (this.XCompositeBasis[jagg] == null || (this.XCompositeBasis[jagg].Length != NoOfSpc_jagg))
                            {
                                this.XCompositeBasis[jagg] = new MultidimensionalArray[NoOfSpc_jagg];
                            }

                            if (emptyCell)
                            {
                                // compute mass matrix in aggregate cell 'jagg' for species index 'iSpc_agg'
                                // -------------------------------------------------------------------------

                                AggCellMMb4Ortho.Clear();
                                for (int k = 0; k < K; k++)  // loop over the base cells in the aggregate cell
                                {
                                    if (sim[iSpc_agg, k] >= 0)
                                    {
                                        var ExPolMtx = base.CompositeBasis[jagg].ExtractSubArrayShallow(k, -1, -1);
                                        AggCellMMb4Ortho.Multiply(1.0, ExPolMtx, ExPolMtx, 1.0, "lm", "im", "il");
                                    }
                                }


                                // change to orthonormal basis
                                // ---------------------------
                                MultidimensionalArray B = MultidimensionalArray.Create(N, N);
                                AggCellMMb4Ortho.SymmetricLDLInversion(B, default(double[]));


                                if (this.XCompositeBasis[jagg][iSpc_agg] == null)
                                {
                                    this.XCompositeBasis[jagg][iSpc_agg] = MultidimensionalArray.Create(K, N, N);
                                }

                                var X_ExPolMtx    = this.XCompositeBasis[jagg][iSpc_agg];
                                var NonX_ExPolMtx = CompositeBasis[jagg];
                                X_ExPolMtx.Allocate(NonX_ExPolMtx.Lengths); // should not reallocate if lengths stay the same;

                                X_ExPolMtx.Multiply(1.0, NonX_ExPolMtx, B, 0.0, "imn", "imk", "kn");
                            }
                            else
                            {
                                // no empty cell with respect to species 'iSpc_agg' in aggregate cell
                                // --> non-XDG projector can be used.
                                // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                                this.XCompositeBasis[jagg][iSpc_agg] = null;
                            }
                        }
                    }
                }
            }
        }
Exemple #6
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 #7
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;
            }
        }
Exemple #8
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            Console.WriteLine("    Timestep # " + TimestepNo + ", phystime = " + phystime);

            //phystime = 1.8;
            LsUpdate(phystime);


            // operator-matrix assemblieren
            MsrMatrix OperatorMatrix = new MsrMatrix(u.Mapping, u.Mapping);

            double[] Affine = new double[OperatorMatrix.RowPartitioning.LocalLength];

            // Agglomerator setup
            MultiphaseCellAgglomerator Agg = LsTrk.GetAgglomerator(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, QuadOrder, this.THRESHOLD);

            // plausibility of cell length scales
            if (SER_PAR_COMPARISON)
            {
                TestLengthScales(QuadOrder, TimestepNo);
            }

            Console.WriteLine("Inter-Process agglomeration? " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.InterProcessAgglomeration);
            if (this.THRESHOLD > 0.01)
            {
                TestAgglomeration_Extraploation(Agg);
                TestAgglomeration_Projection(QuadOrder, Agg);
            }
            CheckExchange(true);
            CheckExchange(false);

            // operator matrix assembly
            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, u.Mapping, null, u.Mapping);
            mtxBuilder.time = 0.0;
            mtxBuilder.ComputeMatrix(OperatorMatrix, Affine);
            Agg.ManipulateMatrixAndRHS(OperatorMatrix, Affine, u.Mapping, u.Mapping);

            // mass matrix factory
            var Mfact = LsTrk.GetXDGSpaceMetrics(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, QuadOrder, 1).MassMatrixFactory;// new MassMatrixFactory(u.Basis, Agg);

            // Mass matrix/Inverse Mass matrix
            //var MassInv = Mfact.GetMassMatrix(u.Mapping, new double[] { 1.0 }, true, LsTrk.GetSpeciesId("B"));
            var Mass = Mfact.GetMassMatrix(u.Mapping, new double[] { 1.0 }, false, LsTrk.GetSpeciesId("B"));

            Agg.ManipulateMatrixAndRHS(Mass, default(double[]), u.Mapping, u.Mapping);
            var MassInv = Mass.InvertBlocks(OnlyDiagonal: true, Subblocks: true, ignoreEmptyBlocks: true, SymmetricalInversion: false);


            // test that operator depends only on B-species values
            double DepTest = LsTrk.Regions.GetSpeciesSubGrid("B").TestMatrixDependency(OperatorMatrix, u.Mapping, u.Mapping);

            Console.WriteLine("Matrix dependency test: " + DepTest);
            Assert.LessOrEqual(DepTest, 0.0);

            // diagnostic output
            Console.WriteLine("Number of Agglomerations (all species): " + Agg.TotalNumberOfAgglomerations);
            Console.WriteLine("Number of Agglomerations (species 'B'): " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.SourceCells.NoOfItemsLocally.MPISum());

            // operator auswerten:
            double[] x = new double[Affine.Length];
            BLAS.daxpy(x.Length, 1.0, Affine, 1, x, 1);
            OperatorMatrix.SpMVpara(1.0, u.CoordinateVector, 1.0, x);
            MassInv.SpMV(1.0, x, 0.0, du_dx.CoordinateVector);
            Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).Extrapolate(du_dx.Mapping);

            // markieren, wo ueberhaupt A und B sind
            Bmarker.AccConstant(1.0, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);
            Amarker.AccConstant(+1.0, LsTrk.Regions.GetSpeciesSubGrid("A").VolumeMask);
            if (usePhi0 && usePhi1)
            {
                Xmarker.AccConstant(+1.0, LsTrk.Regions.GetSpeciesSubGrid("X").VolumeMask);
            }

            // compute error
            ERR.Clear();
            ERR.Acc(1.0, du_dx_Exact, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);
            ERR.Acc(-1.0, du_dx, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);
            double L2Err = ERR.L2Norm(LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);

            Console.WriteLine("L2 Error: " + L2Err);

            XERR.Clear();
            XERR.GetSpeciesShadowField("B").Acc(1.0, ERR, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);
            double xL2Err = XERR.L2Norm();

            Console.WriteLine("L2 Error (in XDG space): " + xL2Err);



            // check error
            double ErrorThreshold = 1.0e-1;

            if (this.MomentFittingVariant == XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes)
            {
                ErrorThreshold = 1.0e-6; // HMF is designed for such integrands and should perform close to machine accuracy; on general integrands, the precision is different.
            }
            bool IsPassed = ((L2Err <= ErrorThreshold || this.THRESHOLD <= ErrorThreshold) && xL2Err <= ErrorThreshold);

            if (IsPassed)
            {
                Console.WriteLine("Test PASSED");
            }
            else
            {
                Console.WriteLine("Test FAILED: check errors.");
                //PlotCurrentState(phystime, TimestepNo, 3);
            }

            if (TimestepNo > 1)
            {
                if (this.THRESHOLD > ErrorThreshold)
                {
                    // without agglomeration, the error in very tiny cut-cells may be large over the whole cell
                    // However, the error in the XDG-space should be small under all circumstances
                    Assert.LessOrEqual(L2Err, ErrorThreshold, "DG L2 error of computing du_dx");
                }
                Assert.LessOrEqual(xL2Err, ErrorThreshold, "XDG L2 error of computing du_dx");
            }



            // return/Ende
            base.NoOfTimesteps = 17;
            //base.NoOfTimesteps = 2;
            dt = 0.3;
            return(dt);
        }
        protected virtual void DelComputeOperatorMatrix(BlockMsrMatrix OpMatrix, double[] OpAffine, UnsetteledCoordinateMapping Mapping, DGField[] CurrentState, MultiphaseCellAgglomerator Agglomerator, double phystime)
        {
            OpMatrix.Clear();
            OpAffine.ClearEntries();

            Op.ComputeMatrixEx(base.LsTrk,
                               u.Mapping, null, uResidual.Mapping,
                               OpMatrix, OpAffine, false,
                               phystime,
                               false,
                               XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes,
                               base.LsTrk.SpeciesIdS.ToArray());
        }
Exemple #10
0
        /// <summary>
        /// Mainly, comparison of single-core vs MPI-parallel run
        /// </summary>
        void TestLengthScales(int quadOrder, int TimestepNo)
        {
            string name_disc = $"t{TimestepNo}-alpha{this.THRESHOLD}-p{this.DEGREE}-q{MomentFittingVariant}";
            var    spcA      = LsTrk.GetSpeciesId("A");
            var    spcB      = LsTrk.GetSpeciesId("B");

            var species = new[] { spcA, spcB };
            //MultiphaseCellAgglomerator.CheckFile = $"InsideMpagg-{name_disc}.csv";
            MultiphaseCellAgglomerator Agg = LsTrk.GetAgglomerator(species, quadOrder, this.THRESHOLD);

            int RefMPIsize = 1;


            // check level-set coordinates
            // ===========================
            {
                var LsChecker = new TestingIO(this.GridData, $"LevelSets-{name_disc}.csv", RefMPIsize);
                LsChecker.AddDGField(this.Phi0);
                LsChecker.AddDGField(this.Phi1);
                LsChecker.DoIOnow();

                Assert.Less(LsChecker.AbsError(this.Phi0), 1.0e-8, "Mismatch in level-set 0 between single-core and parallel run.");
                Assert.Less(LsChecker.AbsError(this.Phi1), 1.0e-8, "Mismatch in level-set 1 between single-core and parallel run.");
            }


            // check equality of agglomeration
            // ===============================

            // Note: agglomeration in parallel and serial mode is not necessarily equal - but very often it is.
            //       Therefore, we need to check whether the agglomeration is equal or not,
            //       in order to know whether agglomerated length scales should be compared or not.

            bool[] equalAggAsinReferenceRun;
            {
                var    aggoCheck = new TestingIO(this.GridData, $"Agglom-{name_disc}.csv", RefMPIsize);
                long[] GiDs      = GridData.CurrentGlobalIdPermutation.Values;
                int    J         = GridData.iLogicalCells.NoOfLocalUpdatedCells;
                long[] extGiDs   = GridData.iParallel.GlobalIndicesExternalCells;

                for (int iSpc = 0; iSpc < species.Length; iSpc++)
                {
                    var spc      = species[iSpc];
                    var spcN     = LsTrk.GetSpeciesName(spc);
                    var ai       = Agg.GetAgglomerator(spc).AggInfo;
                    var srcMask  = ai.SourceCells.GetBitMask();
                    var aggPairs = ai.AgglomerationPairs;

                    aggoCheck.AddColumn($"SourceCells{spcN}", delegate(double[] X, int j, int jG) {
                        if (srcMask[j])
                        {
                            var pair = aggPairs.Single(cap => cap.jCellSource == j);
                            if (pair.jCellTarget < J)
                            {
                                return((double)GiDs[pair.jCellTarget]);
                            }
                            else
                            {
                                return((double)extGiDs[pair.jCellTarget - J]);
                            }
                        }
                        return(0.0);
                    });
                }

                aggoCheck.DoIOnow();

                equalAggAsinReferenceRun = new bool[species.Length];
                for (int iSpc = 0; iSpc < species.Length; iSpc++)
                {
                    var spc  = species[iSpc];
                    var spcN = LsTrk.GetSpeciesName(spc);

                    equalAggAsinReferenceRun[iSpc] = aggoCheck.AbsError($"SourceCells{spcN}") < 0.1;
                    if (equalAggAsinReferenceRun[iSpc] == false)
                    {
                        Console.WriteLine("Different agglomeration between single-core and parallel run for species " + spcN + ".");
                    }
                }

                //Agg.PlotAgglomerationPairs($"-aggPairs-{name_disc}-MPI{MPIRank + 1}of{MPISize}");
            }


            // compare length scales
            // =====================

            csMPI.Raw.Comm_Rank(csMPI.Raw._COMM.WORLD, out int rank);

            foreach (ICutCellMetrics ccm in new ICutCellMetrics[] { Agg.NonAgglomeratedMetrics, Agg })  // loop over non-agglom and agglomerated metrics
            {
                string name;
                bool   Agglom;
                if (object.ReferenceEquals(ccm, Agg))
                {
                    name   = "Agglomerated";
                    Agglom = true;
                }
                else
                {
                    name   = "Nonagglom";
                    Agglom = false;
                }

                MultidimensionalArray CellSurfaceA = ccm.CellSurface[spcA];
                MultidimensionalArray CellVolumeA  = ccm.CutCellVolumes[spcA];
                MultidimensionalArray CellSurfaceB = ccm.CellSurface[spcB];
                MultidimensionalArray CellVolumeB  = ccm.CutCellVolumes[spcB];


                string FileName = $"{name}LengthScales-{name_disc}.csv";
                var    Checker  = new TestingIO(this.GridData, FileName, RefMPIsize);
                Checker.AddColumn("CellSurfA", (double[] X, int j, int jG) => CellSurfaceA[j]);
                Checker.AddColumn("CellVolA", (double[] X, int j, int jG) => CellVolumeA[j]);
                Checker.AddColumn("CellSurfB", (double[] X, int j, int jG) => CellSurfaceB[j]);
                Checker.AddColumn("CellVolB", (double[] X, int j, int jG) => CellVolumeB[j]);
                Checker.DoIOnow();

                if (this.MPISize == 1)
                {
                    var Checker2 = new TestingIO(this.GridData, FileName, int.MaxValue);
                    Checker2.AddColumn("CellSurfA", (double[] X, int j, int jG) => CellSurfaceA[j]);
                    Checker2.AddColumn("CellVolA", (double[] X, int j, int jG) => CellVolumeA[j]);
                    Checker2.AddColumn("CellSurfB", (double[] X, int j, int jG) => CellSurfaceB[j]);
                    Checker2.AddColumn("CellVolB", (double[] X, int j, int jG) => CellVolumeB[j]);
                    Checker2.DoIOnow();

                    foreach (string s in Checker2.ColumnNames)
                    {
                        Assert.Less(Checker2.RelError(s), 1.0e-10, "'TestingUtils.Compare' itself is f****d up.");
                    }
                }

                double srfA = Checker.RelError("CellSurfA") * ((!Agglom || equalAggAsinReferenceRun[0]) ? 1.0 : 0.0);
                double volA = Checker.RelError("CellVolA") * ((!Agglom || equalAggAsinReferenceRun[0]) ? 1.0 : 0.0);
                double srfB = Checker.RelError("CellSurfB") * ((!Agglom || equalAggAsinReferenceRun[1]) ? 1.0 : 0.0);
                double volB = Checker.RelError("CellVolB") * ((!Agglom || equalAggAsinReferenceRun[1]) ? 1.0 : 0.0);

                if (srfA + volA + srfB + volB > 0.001)
                {
                    Console.WriteLine($"Mismatch in {name} cell surface for species A between single-core and parallel run: {srfA}.");
                    Console.WriteLine($"Mismatch in {name} cell volume  for species A between single-core and parallel run: {volA}.");
                    Console.WriteLine($"Mismatch in {name} cell surface for species B between single-core and parallel run: {srfB}.");
                    Console.WriteLine($"Mismatch in {name} cell volume  for species B between single-core and parallel run: {volB}.");
                }


                Assert.Less(srfA, BLAS.MachineEps.Sqrt(), $"Mismatch in {name} cell surface for species A between single-core and parallel run.");
                Assert.Less(volA, BLAS.MachineEps.Sqrt(), $"Mismatch in {name} cell volume  for species A between single-core and parallel run.");
                Assert.Less(srfB, BLAS.MachineEps.Sqrt(), $"Mismatch in {name} cell surface for species B between single-core and parallel run.");
                Assert.Less(volB, BLAS.MachineEps.Sqrt(), $"Mismatch in {name} cell volume  for species B between single-core and parallel run.");
            }
        }
Exemple #11
0
 /// <summary>
 /// Discards old quadrature information
 /// </summary>
 /// <param name="value"></param>
 public void OnNext(LevelSetTracker.LevelSetRegions value)
 {
     this.MaMaFactCache.Clear();
     this.cellAgglomeration = null;
 }
Exemple #12
0
        /// <summary>
        /// Constructor for XDG solvers
        /// </summary>
        public OpAnalysisBase(LevelSetTracker LsTrk, BlockMsrMatrix Mtx, double[] RHS, UnsetteledCoordinateMapping Mapping, MultiphaseCellAgglomerator CurrentAgglomeration, BlockMsrMatrix _mass, IEnumerable <MultigridOperator.ChangeOfBasisConfig[]> OpConfig, ISpatialOperator abstractOperator)
        {
            int RHSlen = Mapping.TotalLength;

            m_map    = Mapping;                              // mapping
            VarGroup = Mapping.BasisS.Count.ForLoop(i => i); //default: all dependent variables are included in operator matrix

            m_LsTrk = LsTrk;

            m_OpMtx  = Mtx.CloneAs();
            localRHS = RHS.CloneAs();

            // create the Dummy XDG aggregation basis
            var baseGrid = Mapping.GridDat;
            var mgSeq    = Foundation.Grid.Aggregation.CoarseningAlgorithms.CreateSequence(baseGrid, 1);

            AggregationGridBasis[][] XAggB = AggregationGridBasis.CreateSequence(mgSeq, Mapping.BasisS);

            //
            XAggB.UpdateXdgAggregationBasis(CurrentAgglomeration);

            // create multigrid operator
            m_MultigridOp = new MultigridOperator(XAggB, Mapping,
                                                  m_OpMtx,
                                                  _mass,
                                                  OpConfig,
                                                  abstractOperator.DomainVar.Select(varName => abstractOperator.FreeMeanValue[varName]).ToArray());
        }
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")
            //    );

            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
        }
 /// <summary>
 /// Discards old quadrature information
 /// </summary>
 /// <param name="value"></param>
 public void OnNext(LevelSetTracker.LevelSetRegions value)
 {
     this.MassMatrixFactory = null;
     this.cellAgglomeration = null;
 }