Exemplo n.º 1
0
        void DelComputeOperatorMatrix(BlockMsrMatrix OpMtx, double[] OpAffine, UnsetteledCoordinateMapping Mapping, DGField[] CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double phystime)
        {
            DGField[] Params = null;
            if (this.Control.Eq == Equation.ScalarTransport)
            {
                Params = this.V.ToArray();
            }
            else if (this.Control.Eq == Equation.HeatEq)
            {
                Params = null;
            }
            else if (this.Control.Eq == Equation.Burgers)
            {
                Params = CurrentState;
            }
            else
            {
                throw new NotImplementedException();
            }

            // compute operator
            Debug.Assert(OpMtx.InfNorm() == 0.0);
            Debug.Assert(OpAffine.L2Norm() == 0.0);
            //Operator.ComputeMatrixEx(this.LsTrk,
            //    Mapping, Params, Mapping,
            //    OpMtx, OpAffine, false, phystime, true,
            //    AgglomeratedCellLengthScales, null, null,
            //    AgglomeratedCellLengthScales.Keys.ToArray());
            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Operator.GetMatrixBuilder(this.LsTrk, Mapping, Params, Mapping, AgglomeratedCellLengthScales.Keys.ToArray());
            mtxBuilder.time           = phystime;
            mtxBuilder.MPITtransceive = true;
            mtxBuilder.ComputeMatrix(OpMtx, OpAffine);
        }
Exemplo n.º 2
0
        protected virtual void DelComputeOperatorMatrix(BlockMsrMatrix OpMatrix, double[] OpAffine, UnsetteledCoordinateMapping Mapping, DGField[] CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double phystime)
        {
            OpAffine.ClearEntries();

            bool Eval = false;

            if (OpMatrix == null)
            {
                Eval     = true;
                OpMatrix = new BlockMsrMatrix(uResidual.Mapping, u.Mapping);
            }
            else
            {
                OpMatrix.Clear();
            }

            //Op.ComputeMatrixEx(base.LsTrk,
            //    u.Mapping, null, uResidual.Mapping,
            //    OpMatrix, OpAffine, false,
            //    phystime,
            //    false,
            //    base.LsTrk.SpeciesIdS.ToArray());
            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, u.Mapping, null, uResidual.Mapping);

            mtxBuilder.CellLengthScales.AddRange(AgglomeratedCellLengthScales);

            mtxBuilder.time = phystime;
            mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);

            if (Eval)
            {
                OpMatrix.SpMV(1.0, new CoordinateVector(CurrentState), 1.0, OpAffine);
            }
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
        /// <summary>
        /// base matrix assembly
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="OpMatrix"></param>
        /// <param name="OpAffine"></param>
        /// <param name="RowMapping"></param>
        /// <param name="ColMapping"></param>
        /// <param name="CurrentState"></param>
        /// <param name="ParamsMap"></param>
        /// <param name="AgglomeratedCellLengthScales"></param>
        /// <param name="time"></param>
        public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine,
                                       UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
                                       IEnumerable <T> CurrentState, IList <DGField> ParamsMap, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales,
                                       double time) where T : DGField
        {
            // checks
            if (ColMapping.BasisS.Count != m_XOp.DomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (RowMapping.BasisS.Count != m_XOp.CodomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (OpMatrix == null && CurrentState == null)
            {
                throw new ArgumentException();
            }

            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();

            if (OpMatrix != null)
            {
                XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = m_XOp.GetMatrixBuilder(LsTrk, ColMapping, ParamsMap, RowMapping, SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                }

                mtxBuilder.time = time;

                mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);
            }
            else
            {
                XSpatialOperatorMk2.XEvaluatorNonlin eval = m_XOp.GetEvaluatorEx(this.LsTrk,
                                                                                 CurrentState.ToArray(), ParamsMap, RowMapping,
                                                                                 SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                }

                eval.time = time;

                eval.Evaluate(1.0, 1.0, OpAffine);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Create Spatial Operators and build the corresponding Matrices
        /// </summary>
        public void UpdateRHS(SinglePhaseField Extension, SinglePhaseField InterfaceValue, bool nearfield)
        {
            this.Extension = Extension;

            OpAffine.Clear();

            //XSpatialOperatorExtensions.ComputeMatrixEx(Operator_interface,
            ////Operator_interface.ComputeMatrixEx(
            //   LevelSetTracker,
            //    Extension.Mapping,
            //    new List<DGField> { InterfaceValue },
            //    Extension.Mapping,
            //    OpMatrix_interface,
            //    OpAffine_interface,
            //    OnlyAffine: true,
            //    time: 0,
            //    MPIParameterExchange: false,
            //    whichSpc: LevelSetTracker.GetSpeciesId("A"),
            //    subGrid: nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1) : null
            //    );
            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Operator_interface.GetMatrixBuilder(LevelSetTracker,
                                                                                                  Extension.Mapping, new List <DGField> {
                InterfaceValue
            }, Extension.Mapping);
            mtxBuilder.time           = 0;
            mtxBuilder.MPITtransceive = false;
            mtxBuilder.ComputeAffine(OpAffine_interface);

            if (OpAffine.L2Norm() == 0)
            {
                Console.WriteLine("RHS of Bulk equation is empty as expected.");
            }

            OpAffine.Clear();
            OpAffine.AccV(1.0, OpAffine_bulk);
            OpAffine.AccV(1.0, OpAffine_interface);
        }
Exemplo n.º 6
0
        /// <summary>
        ///
        /// </summary>
        public void AssembleMatrix_Timestepper <T>(
            int CutCellQuadOrder,
            BlockMsrMatrix OpMatrix, double[] OpAffine,
            Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales,
            IEnumerable <T> CurrentState,
            VectorField <SinglePhaseField> SurfaceForce,
            VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature,
            UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
            double time, IEnumerable <T> CoupledCurrentState = null, IEnumerable <T> CoupledParams = null) where T : DGField
        {
            if (ColMapping.BasisS.Count != this.Op.DomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (RowMapping.BasisS.Count != this.Op.CodomainVar.Count)
            {
                throw new ArgumentException();
            }

            // check:
            var Tracker = this.LsTrk;
            int D       = Tracker.GridDat.SpatialDimension;

            if (CurrentState != null && CurrentState.Count() != (D + 1))
            {
                throw new ArgumentException();
            }
            if (OpMatrix == null && CurrentState == null)
            {
                throw new ArgumentException();
            }
            DGField[] U0;
            if (CurrentState != null)
            {
                U0 = CurrentState.Take(D).ToArray();
            }
            else
            {
                U0 = null;
            }



            LevelSet Phi = (LevelSet)(Tracker.LevelSets[0]);

            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();

            IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea;


            // advanced settings for the navier slip boundary condition
            // ========================================================

            CellMask SlipArea;

            switch (this.dntParams.GNBC_Localization)
            {
            case NavierSlip_Localization.Bulk: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask;
                break;
            }

            case NavierSlip_Localization.ContactLine: {
                SlipArea = null;
                break;
            }

            case NavierSlip_Localization.Nearband: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth));
                break;
            }

            case NavierSlip_Localization.Prescribed: {
                throw new NotImplementedException();
            }

            default:
                throw new ArgumentException();
            }


            MultidimensionalArray SlipLengths;

            SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs();
            SlipLengths.Clear();
            //SlipLengths.AccConstant(-1.0);

            if (SlipArea != null)
            {
                foreach (Chunk cnk in SlipArea)
                {
                    for (int i = cnk.i0; i < cnk.JE; i++)
                    {
                        switch (this.dntParams.GNBC_SlipLength)
                        {
                        case NavierSlip_SlipLength.hmin_DG: {
                            int degU = ColMapping.BasisS.ToArray()[0].Degree;
                            SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1);
                            break;
                        }

                        case NavierSlip_SlipLength.hmin_Grid: {
                            SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i];
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_SlipLength: {
                            SlipLengths[i] = this.physParams.sliplength;
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_Beta: {
                            SlipLengths[i] = -1.0;
                            break;
                        }
                        }
                    }
                }
            }


            // parameter assembly
            // ==================

            // normals:
            SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions.
            if (this.NormalsRequired)
            {
                if (LevelSetGradient == null)
                {
                    LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory);
                    LevelSetGradient.Gradient(1.0, Phi);
                }
                Normals = LevelSetGradient.ToArray();
            }
            else
            {
                Normals = new SinglePhaseField[D];
            }

            // curvature:
            SinglePhaseField Curvature;

            if (this.CurvatureRequired)
            {
                Curvature = ExternalyProvidedCurvature;
            }
            else
            {
                Curvature = null;
            }

            // linearization velocity:
            DGField[] U0_U0mean;
            if (this.U0meanrequired)
            {
                XDGBasis U0meanBasis          = new XDGBasis(Tracker, 0);
                VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory);

                U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }

            // Temperature gradient for evaporation
            VectorField <DGField> GradTemp = new VectorField <DGField>(D, U0[0].Basis, XDGField.Factory);

            if (CoupledCurrentState != null)
            {
                DGField Temp = CoupledCurrentState.ToArray()[0];
                GradTemp = new VectorField <DGField>(D, Temp.Basis, "GradTemp", XDGField.Factory);
                XNSEUtils.ComputeGradientForParam(Temp, GradTemp, this.LsTrk);
            }

            // concatenate everything
            var Params = ArrayTools.Cat <DGField>(
                U0_U0mean,
                Curvature,
                ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]),
                Normals,
                ((evaporation) ? GradTemp.ToArray() : new SinglePhaseField[D]),
                ((evaporation) ? CoupledCurrentState.ToArray <DGField>() : new SinglePhaseField[1]),
                ((evaporation) ? CoupledParams.ToArray <DGField>() : new SinglePhaseField[1]));  //((evaporation) ? GradTemp.ToArray() : new SinglePhaseField[D]));

            // linearization velocity:
            if (this.U0meanrequired)
            {
                VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray());

                U0mean.Clear();
                if (this.physParams.IncludeConvection)
                {
                    ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
                }
            }



            // assemble the matrix & affine vector
            // ===================================

            // compute matrix
            if (OpMatrix != null)
            {
                //Op.ComputeMatrixEx(Tracker,
                //    ColMapping, Params, RowMapping,
                //    OpMatrix, OpAffine, false, time, true,
                //    AgglomeratedCellLengthScales,
                //    InterfaceLengths, SlipLengths,
                //    SpcToCompute);

                XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping, SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                }

                if (Op.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                mtxBuilder.time = time;

                mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);
            }
            else
            {
                XSpatialOperatorMk2.XEvaluatorNonlin eval = Op.GetEvaluatorEx(Tracker,
                                                                              CurrentState.ToArray(), Params, RowMapping,
                                                                              SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                }

                if (Op.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                eval.time = time;

                eval.Evaluate(1.0, 1.0, OpAffine);

#if DEBUG
                // remark: remove this piece in a few months from now on (09may18) if no problems occur
                //{

                //    BlockMsrMatrix checkOpMatrix = new BlockMsrMatrix(RowMapping, ColMapping);
                //    double[] checkAffine = new double[OpAffine.Length];

                //    Op.ComputeMatrixEx(Tracker,
                //    ColMapping, Params, RowMapping,
                //    OpMatrix, OpAffine, false, time, true,
                //    AgglomeratedCellLengthScales,
                //    InterfaceLengths, SlipLengths,
                //    SpcToCompute);


                //    double[] checkResult = checkAffine.CloneAs();
                //    var currentVec = new CoordinateVector(CurrentState.ToArray());
                //    checkOpMatrix.SpMV(1.0, new CoordinateVector(CurrentState.ToArray()), 1.0, checkResult);

                //    double L2_dist = GenericBlas.L2DistPow2(checkResult, OpAffine).MPISum().Sqrt();
                //    double RefNorm = (new double[] { checkResult.L2NormPow2(), OpAffine.L2NormPow2(), currentVec.L2NormPow2() }).MPISum().Max().Sqrt();

                //    Assert.LessOrEqual(L2_dist, RefNorm * 1.0e-6);
                //    Debug.Assert(L2_dist < RefNorm * 1.0e-6);
                //}
#endif
            }


            // check
            // =====

            /*
             * {
             *  DGField[] testDomainFieldS = ColMapping.BasisS.Select(bb => new XDGField(bb as XDGBasis)).ToArray();
             *  CoordinateVector test = new CoordinateVector(testDomainFieldS);
             *
             *  DGField[] errFieldS = ColMapping.BasisS.Select(bb => new XDGField(bb as XDGBasis)).ToArray();
             *  CoordinateVector Err = new CoordinateVector(errFieldS);
             *
             *  var eval = Op.GetEvaluatorEx(LsTrk,
             *      testDomainFieldS, Params, RowMapping);
             *
             *  foreach (var s in this.LsTrk.SpeciesIdS)
             *      eval.SpeciesOperatorCoefficients[s].CellLengthScales = AgglomeratedCellLengthScales[s];
             *
             *  eval.time = time;
             *  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, OpAffine);
             *  OpMatrix.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();
             *
             *  Debug.Assert(ErrDist <= Ref*1.0e-5, "Mismatch between explicit evaluation of XDG operator and matrix.");
             * }
             */
        }
Exemplo n.º 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;

                Op = new XSpatialOperatorMk2(1, 1, (A, B, C) => order, this.LsTrk.SpeciesNames, "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());
                    XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(this.LsTrk, map, null, map);

                    mtxBuilder.CellLengthScales.AddRange(agg.CellLengthScales);

                    mtxBuilder.time           = 0.0;
                    mtxBuilder.MPITtransceive = true;
                    mtxBuilder.ComputeMatrix(M, b);
                }
                // 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);

                eval.CellLengthScales.AddRange(agg.CellLengthScales);

                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;
            }
        }
Exemplo n.º 8
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
                }
            }
        }
Exemplo n.º 9
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="OpMatrix"></param>
        /// <param name="OpAffine"></param>
        /// <param name="RowMapping"></param>
        /// <param name="ColMapping"></param>
        /// <param name="CurrentState"></param>
        /// <param name="AgglomeratedCellLengthScales"></param>
        /// <param name="time"></param>
        /// <param name="CutCellQuadOrder"></param>
        /// <param name="SurfaceForce"></param>
        /// <param name="LevelSetGradient"></param>
        /// <param name="ExternalyProvidedCurvature"></param>
        public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine,
                                       UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
                                       IEnumerable <T> CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time,
                                       int CutCellQuadOrder, VectorField <SinglePhaseField> SurfaceForce,
                                       VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature) where T : DGField
        {
            // checks:
            if (ColMapping.BasisS.Count != this.m_XOp.DomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (RowMapping.BasisS.Count != this.m_XOp.CodomainVar.Count)
            {
                throw new ArgumentException();
            }

            int D = this.LsTrk.GridDat.SpatialDimension;

            if (CurrentState != null && CurrentState.Count() != (D + 1))
            {
                throw new ArgumentException();
            }

            if (OpMatrix == null && CurrentState == null)
            {
                throw new ArgumentException();
            }

            DGField[] U0;
            if (CurrentState != null)
            {
                U0 = CurrentState.Take(D).ToArray();
            }
            else
            {
                U0 = null;
            }



            // advanced settings for the navier slip boundary condition
            // ========================================================

            CellMask SlipArea;

            switch (this.dntParams.GNBC_Localization)
            {
            case NavierSlip_Localization.Bulk: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask;
                break;
            }

            case NavierSlip_Localization.ContactLine: {
                SlipArea = null;
                break;
            }

            case NavierSlip_Localization.Nearband: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth));
                break;
            }

            case NavierSlip_Localization.Prescribed: {
                throw new NotImplementedException();
            }

            default:
                throw new ArgumentException();
            }


            MultidimensionalArray SlipLengths;

            SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs();
            SlipLengths.Clear();
            //SlipLengths.AccConstant(-1.0);
            if (SlipArea != null)
            {
                foreach (Chunk cnk in SlipArea)
                {
                    for (int i = cnk.i0; i < cnk.JE; i++)
                    {
                        switch (this.dntParams.GNBC_SlipLength)
                        {
                        case NavierSlip_SlipLength.hmin_DG: {
                            int degU = ColMapping.BasisS.ToArray()[0].Degree;
                            SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1);
                            break;
                        }

                        case NavierSlip_SlipLength.hmin_Grid: {
                            SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i];
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_SlipLength: {
                            SlipLengths[i] = this.physParams.sliplength;
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_Beta: {
                            SlipLengths[i] = -1.0;
                            break;
                        }
                        }
                    }
                }
            }


            // parameter assembly
            // ==================

            LevelSet Phi = (LevelSet)(this.LsTrk.LevelSets[0]);

            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();

            // normals:
            SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions.
            if (this.NormalsRequired)
            {
                if (LevelSetGradient == null)
                {
                    LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory);
                    LevelSetGradient.Gradient(1.0, Phi);
                }
                Normals = LevelSetGradient.ToArray();
            }
            else
            {
                Normals = new SinglePhaseField[D];
            }

            // curvature:
            SinglePhaseField Curvature;

            if (this.CurvatureRequired)
            {
                Curvature = ExternalyProvidedCurvature;
            }
            else
            {
                Curvature = null;
            }

            // linearization velocity:
            DGField[] U0_U0mean;
            if (this.U0meanrequired)
            {
                XDGBasis U0meanBasis          = new XDGBasis(this.LsTrk, 0);
                VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory);

                U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }

            // Temperature gradient for evaporation
            //VectorField<DGField> GradTemp = new VectorField<DGField>(D, new XDGBasis(LsTrk, 0), XDGField.Factory);
            //if (CoupledCurrentState != null) {
            //    DGField Temp = CoupledCurrentState.ToArray()[0];
            //    GradTemp = new VectorField<DGField>(D, Temp.Basis, "GradTemp", XDGField.Factory);
            //    XNSEUtils.ComputeGradientForParam(Temp, GradTemp, this.LsTrk);
            //}

            // concatenate everything
            var Params = ArrayTools.Cat <DGField>(
                U0_U0mean,
                Normals,
                Curvature,
                ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]));

            // linearization velocity:
            if (this.U0meanrequired)
            {
                VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray());

                U0mean.Clear();
                if (this.physParams.IncludeConvection)
                {
                    ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
                }
            }



            // assemble the matrix & affine vector
            // ===================================

            IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea;

            // compute matrix
            if (OpMatrix != null)
            {
                XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = this.m_XOp.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping, SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                }

                if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                mtxBuilder.time = time;

                mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);
            }
            else
            {
                XSpatialOperatorMk2.XEvaluatorNonlin eval = this.m_XOp.GetEvaluatorEx(this.LsTrk,
                                                                                      CurrentState.ToArray(), Params, RowMapping,
                                                                                      SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    eval.SpeciesOperatorCoefficients[kv.Key].EdgeLengthScales = kv.Value;
                    eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                }

                if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                eval.time = time;

                eval.Evaluate(1.0, 1.0, OpAffine);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        ///
        /// </summary>
        public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine,
                                       UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
                                       IEnumerable <T> CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time,
                                       int CutCellQuadOrder, VectorField <SinglePhaseField> SurfaceForce,
                                       VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature,
                                       bool[] updateSolutionParams = null, DGField[] ExtParams = null) where T : DGField
        {
            //IEnumerable<T> CoupledCurrentState = null, IEnumerable<T> CoupledParams = null) where T : DGField {

            // checks:
            if (ColMapping.BasisS.Count != this.m_XOp.DomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (RowMapping.BasisS.Count != this.m_XOp.CodomainVar.Count)
            {
                throw new ArgumentException();
            }

            int D = this.LsTrk.GridDat.SpatialDimension;

            if (CurrentState != null && !config.solveEnergy && !config.solveHeat && CurrentState.Count() != (D + 1))
            {
                throw new ArgumentException();
            }

            if (OpMatrix == null && CurrentState == null)
            {
                throw new ArgumentException();
            }

            DGField[] U0;
            if (CurrentState != null)
            {
                U0 = CurrentState.Take(D).ToArray();
            }
            else
            {
                U0 = null;
            }



            // parameter assembly
            // ==================
            #region param assembly

            LevelSet    Phi          = (LevelSet)(this.LsTrk.LevelSets[0]);
            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();


            // linearization velocity:
            DGField[] U0_U0mean;
            if (this.U0meanrequired)
            {
                XDGBasis U0meanBasis          = new XDGBasis(this.LsTrk, 0);
                VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory);
                U0mean.Clear();
                if (this.physParams.IncludeConvection)
                {
                    ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
                }

                U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }

            // linearization velocity:
            //if (this.U0meanrequired) {
            //    VectorField<XDGField> U0mean = new VectorField<XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray());

            //    U0mean.Clear();
            //    if (this.physParams.IncludeConvection)
            //        ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
            //}


            // normals:
            SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions.
            if (this.NormalsRequired)
            {
                if (LevelSetGradient == null)
                {
                    LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory);
                    LevelSetGradient.Gradient(1.0, Phi);
                }
                Normals = LevelSetGradient.ToArray();
            }
            else
            {
                Normals = new SinglePhaseField[D];
            }

            // curvature:
            SinglePhaseField Curvature;
            if (this.CurvatureRequired)
            {
                Curvature = ExternalyProvidedCurvature;
            }
            else
            {
                Curvature = null;
            }


            // velocity gradient vectors
            var       VelMap   = new CoordinateMapping(U0);
            DGField[] VelParam = VelMap.Fields.ToArray();

            VectorField <DGField> GradVelX = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityXGradient", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((VelParam[0] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (GradVelX[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            GradVelX.ForEach(F => F.CheckForNanOrInf(true, true, true));

            VectorField <DGField> GradVelY = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityYGradient", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((VelParam[1] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (GradVelY[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            GradVelY.ForEach(F => F.CheckForNanOrInf(true, true, true));


            VectorField <DGField> GradVelXGradX = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityXGradX_Gradient", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((GradVelX[0] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (GradVelXGradX[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            GradVelXGradX.ForEach(F => F.CheckForNanOrInf(true, true, true));

            VectorField <DGField> GradVelXGradY = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityXGradY_Gradient", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((GradVelX[1] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (GradVelXGradY[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            GradVelXGradY.ForEach(F => F.CheckForNanOrInf(true, true, true));

            VectorField <DGField> GradVelYGradX = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityYGradX_Gradient", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((GradVelY[0] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (GradVelYGradX[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            GradVelYGradX.ForEach(F => F.CheckForNanOrInf(true, true, true));

            VectorField <DGField> GradVelYGradY = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityYGradY_Gradient", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((GradVelY[1] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (GradVelYGradY[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            GradVelYGradY.ForEach(F => F.CheckForNanOrInf(true, true, true));



            // pressure and gradient
            var       PressMap   = new CoordinateMapping(CurrentState.ToArray()[D]);
            DGField[] PressParam = PressMap.Fields.ToArray();

            VectorField <DGField> PressGrad = new VectorField <DGField>(D, PressParam[0].Basis, "PressureGrad", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((PressParam[0] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (PressGrad[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            PressGrad.ForEach(F => F.CheckForNanOrInf(true, true, true));

            // gravity
            var       GravMap   = new CoordinateMapping(ExtParams);
            DGField[] GravParam = GravMap.Fields.ToArray();


            // heat flux for evaporation
            DGField[] HeatFluxParam = new DGField[D];
            if (config.solveHeat)
            {
                if (config.conductMode == ConductivityInSpeciesBulk.ConductivityMode.SIP && updateSolutionParams[D + 1])
                {
                    HeatFluxParam = new VectorField <XDGField>(D, CurrentState.ToArray()[D + 1].Basis, "HeatFlux0_", XDGField.Factory).ToArray();
                    Dictionary <string, double> kSpc = new Dictionary <string, double>();
                    kSpc.Add("A", -thermParams.k_A);
                    kSpc.Add("B", -thermParams.k_B);
                    XNSEUtils.ComputeGradientForParam(CurrentState.ToArray()[D + 1], HeatFluxParam, this.LsTrk, kSpc, this.LsTrk.Regions.GetCutCellSubGrid());
                }
                else if (config.conductMode != ConductivityInSpeciesBulk.ConductivityMode.SIP && updateSolutionParams[D + 2])
                {
                    var HeatFluxMap = new CoordinateMapping(CurrentState.ToArray().GetSubVector(D + 2, D));
                    HeatFluxParam = HeatFluxMap.Fields.ToArray();
                }
                else
                {
                    HeatFluxParam = storedParams.GetSubVector(2 * D + 4, D);
                }
            }
            if (ExtParams != null)
            {
                HeatFluxParam = ExtParams;
            }

            #endregion


            // concatenate everything
            var Params = ArrayTools.Cat <DGField>(
                U0_U0mean,
                Normals,
                Curvature,
                ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]));

            if (config.solveEnergy)
            {
                Params = ArrayTools.Cat <DGField>(Params.ToArray <DGField>(),
                                                  GradVelX,
                                                  GradVelY,
                                                  GradVelXGradX,
                                                  GradVelXGradY,
                                                  GradVelYGradX,
                                                  GradVelYGradY,
                                                  PressParam,
                                                  PressGrad,
                                                  GravMap);
            }

            if (config.solveHeat)
            {
                Params = ArrayTools.Cat <DGField>(Params.ToArray <DGField>(),
                                                  CurrentState.ToArray <DGField>().GetSubVector(D + 1, 1),
                                                  HeatFluxParam,
                                                  new SinglePhaseField[1]);
            }


            // store old params
            for (int p = 0; p < Params.Length; p++)
            {
                if (Params[p] != null)
                {
                    storedParams[p] = Params[p].CloneAs();
                }
            }



            // advanced settings for the navier slip boundary condition
            // ========================================================


            CellMask SlipArea;
            switch (this.dntParams.GNBC_Localization)
            {
            case NavierSlip_Localization.Bulk: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask;
                break;
            }

            case NavierSlip_Localization.ContactLine: {
                SlipArea = null;
                break;
            }

            case NavierSlip_Localization.Nearband: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth));
                break;
            }

            case NavierSlip_Localization.Prescribed: {
                throw new NotImplementedException();
            }

            default:
                throw new ArgumentException();
            }


            MultidimensionalArray SlipLengths;
            SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs();
            SlipLengths.Clear();
            //SlipLengths.AccConstant(-1.0);
            if (SlipArea != null)
            {
                foreach (Chunk cnk in SlipArea)
                {
                    for (int i = cnk.i0; i < cnk.JE; i++)
                    {
                        switch (this.dntParams.GNBC_SlipLength)
                        {
                        case NavierSlip_SlipLength.hmin_DG: {
                            int degU = ColMapping.BasisS.ToArray()[0].Degree;
                            SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1);
                            break;
                        }

                        case NavierSlip_SlipLength.hmin_Grid: {
                            SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i];
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_SlipLength: {
                            SlipLengths[i] = this.physParams.sliplength;
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_Beta: {
                            SlipLengths[i] = -1.0;
                            break;
                        }
                        }
                    }
                }
            }


            // interface coefficients
            // ======================

            MultidimensionalArray lambdaI, muI;
            lambdaI = SlipLengths.CloneAs();
            lambdaI.Clear();
            muI = SlipLengths.CloneAs();
            muI.Clear();

            foreach (Chunk cnk in this.LsTrk.Regions.GetCutCellMask())
            {
                for (int i = cnk.i0; i < cnk.JE; i++)
                {
                    double lI = 0.0;
                    double mI = 0.0;

                    // do the magic!!!
                    if (this.LsTrk.GridDat.Cells.CellCenter[i, 0] > 0 && this.LsTrk.GridDat.Cells.CellCenter[i, 1] > 0)
                    {
                    }
                    if (this.LsTrk.GridDat.Cells.CellCenter[i, 0] > 0 && this.LsTrk.GridDat.Cells.CellCenter[i, 1] < 0)
                    {
                        //lI = config.physParams.Sigma;
                        mI = config.physParams.Sigma;
                    }
                    if (this.LsTrk.GridDat.Cells.CellCenter[i, 0] < 0 && this.LsTrk.GridDat.Cells.CellCenter[i, 1] < 0)
                    {
                        //lI = -config.physParams.Sigma;
                        mI = -config.physParams.Sigma;
                    }
                    if (this.LsTrk.GridDat.Cells.CellCenter[i, 0] < 0 && this.LsTrk.GridDat.Cells.CellCenter[i, 1] > 0)
                    {
                        //lI = 10 * config.physParams.Sigma;
                        mI = 10 * config.physParams.Sigma;
                    }

                    lambdaI[i] = lI;
                    muI[i]     = mI;
                }
            }



            // assemble the matrix & affine vector
            // ===================================

            IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea;

            BitArray EvapMicroRegion = this.LsTrk.GridDat.GetBoundaryCells().GetBitMask();
            EvapMicroRegion.SetAll(false);

            // compute matrix
            if (OpMatrix != null)
            {
                XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = this.m_XOp.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    mtxBuilder.CellLengthScales[kv.Key] = kv.Value;
                    this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["SlipLengths"]     = SlipLengths;
                    this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["EvapMicroRegion"] = EvapMicroRegion;
                    if (config.prescribedMassflux != null)
                    {
                        double[] dummyX = new double[] { 0.0, 0.0 };
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["prescribedMassflux"] = config.prescribedMassflux(dummyX, time);
                    }
                }

                if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["InterfaceLengths"] = kv.Value;
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["lambda_interface"] = lambdaI;
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["mu_interface"]     = muI;
                    }
                }

                mtxBuilder.time = time;

                mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);
            }
            else
            {
                XSpatialOperatorMk2.XEvaluatorNonlin eval = this.m_XOp.GetEvaluatorEx(this.LsTrk,
                                                                                      CurrentState.ToArray(), Params, RowMapping);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    eval.CellLengthScales[kv.Key] = kv.Value;
                    this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["SlipLengths"]     = SlipLengths;
                    this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["EvapMicroRegion"] = EvapMicroRegion;
                    if (config.prescribedMassflux != null)
                    {
                        double[] dummyX = new double[] { 0.0, 0.0 };
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["prescribedMassflux"] = config.prescribedMassflux(dummyX, time);
                    }
                }

                if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["InterfaceLengths"] = kv.Value;
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["lambda_interface"] = lambdaI;
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["mu_interface"]     = muI;
                    }
                }

                eval.time = time;

                eval.Evaluate(1.0, 1.0, OpAffine);
            }
        }
Exemplo n.º 11
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);
        }
Exemplo n.º 12
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="OpMatrix"></param>
        /// <param name="OpAffine"></param>
        /// <param name="RowMapping"></param>
        /// <param name="ColMapping"></param>
        /// <param name="CurrentState"></param>
        /// <param name="AgglomeratedCellLengthScales"></param>
        /// <param name="time"></param>
        /// <param name="CutCellQuadOrder"></param>
        /// <param name="SurfaceForce"></param>
        /// <param name="LevelSetGradient"></param>
        /// <param name="ExternalyProvidedCurvature"></param>
        public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine,
                                       UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
                                       IEnumerable <T> CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time,
                                       int CutCellQuadOrder, VectorField <SinglePhaseField> SurfaceForce,
                                       VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature, double currentWeissenberg,
                                       IEnumerable <T> CoupledCurrentState = null, IEnumerable <T> CoupledParams = null) where T : DGField
        {
            // checks:
            if (ColMapping.BasisS.Count != this.m_XOp.DomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (RowMapping.BasisS.Count != this.m_XOp.CodomainVar.Count)
            {
                throw new ArgumentException();
            }

            int D = this.LsTrk.GridDat.SpatialDimension;

            if (CurrentState != null && CurrentState.Count() != (D + 4))
            {
                throw new ArgumentException();
            }

            if (OpMatrix == null && CurrentState == null)
            {
                throw new ArgumentException();
            }

            DGField[] U0;
            if (CurrentState != null)
            {
                U0 = CurrentState.Take(D).ToArray();
            }
            else
            {
                U0 = null;
            }

            DGField[] Stress0;
            Stress0 = CurrentState.Skip(D + 1).Take(3).ToArray();

            if (U0.Count() != D)
            {
                throw new ArgumentException("Spatial dimesion and number of velocity parameter components does not match!");
            }

            if (Stress0.Count() != D + 1)
            {
                throw new ArgumentException("Spatial dimesion and number of stress parameter components does not match!");
            }



            // advanced settings for the navier slip boundary condition
            // ========================================================

            CellMask SlipArea;

            switch (this.dntParams.GNBC_Localization)
            {
            case NavierSlip_Localization.Bulk: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask;
                break;
            }

            case NavierSlip_Localization.ContactLine: {
                SlipArea = null;
                break;
            }

            case NavierSlip_Localization.Nearband: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth));
                break;
            }

            case NavierSlip_Localization.Prescribed: {
                throw new NotImplementedException();
            }

            default:
                throw new ArgumentException();
            }


            MultidimensionalArray SlipLengths;

            SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs();
            SlipLengths.Clear();
            //SlipLengths.AccConstant(-1.0);
            if (SlipArea != null)
            {
                foreach (Chunk cnk in SlipArea)
                {
                    for (int i = cnk.i0; i < cnk.JE; i++)
                    {
                        switch (this.dntParams.GNBC_SlipLength)
                        {
                        case NavierSlip_SlipLength.hmin_DG: {
                            int degU = ColMapping.BasisS.ToArray()[0].Degree;
                            SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1);
                            break;
                        }

                        case NavierSlip_SlipLength.hmin_Grid: {
                            SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i];
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_SlipLength: {
                            SlipLengths[i] = this.physParams.sliplength;
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_Beta: {
                            SlipLengths[i] = -1.0;
                            break;
                        }
                        }
                    }
                }
            }


            // parameter assembly
            // ==================

            LevelSet Phi = (LevelSet)(this.LsTrk.LevelSets[0]);

            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();

            // normals:
            SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions.
            if (this.NormalsRequired)
            {
                if (LevelSetGradient == null)
                {
                    LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory);
                    LevelSetGradient.Gradient(1.0, Phi);
                }
                Normals = LevelSetGradient.ToArray();
            }
            else
            {
                Normals = new SinglePhaseField[D];
            }

            // curvature:
            SinglePhaseField Curvature;

            if (this.CurvatureRequired)
            {
                Curvature = ExternalyProvidedCurvature;
            }
            else
            {
                Curvature = null;
            }


            // Velocity and stresses for linearization

            // linearization velocity:
            DGField[] U0_U0mean;
            if (this.U0meanrequired)
            {
                XDGBasis U0meanBasis          = new XDGBasis(this.LsTrk, 0);
                VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory);

                U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }


            if (VelocityXGradient == null)
            {
                VelocityXGradient = new VectorField <XDGField>(D, CurrentState.ElementAt(0).Basis, "VelocityX_Gradient", XDGField.Factory);
            }
            if (VelocityYGradient == null)
            {
                VelocityYGradient = new VectorField <XDGField>(D, CurrentState.ElementAt(1).Basis, "VelocityY_Gradient", XDGField.Factory);
            }


            // concatenate everything
            var Params = ArrayTools.Cat <DGField>(
                U0_U0mean,
                VelocityXGradient,
                VelocityYGradient,
                Stress0,
                //artificalViscosity,
                Normals,
                Curvature,
                ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]));


            // linearization velocity:
            if (this.U0meanrequired)
            {
                VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray());

                U0mean.Clear();
                if (this.physParams.IncludeConvection)
                {
                    ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
                }
            }



            // assemble the matrix & affine vector
            // ===================================

            IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea;

            BitArray EvapMicroRegion = this.LsTrk.GridDat.GetBoundaryCells().GetBitMask();

            EvapMicroRegion.SetAll(false);

            // compute matrix
            if (OpMatrix != null)
            {
                if (!useJacobianForOperatorMatrix)
                {
                    XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = this.m_XOp.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping, SpcToCompute);
                    this.ParameterUpdate(CurrentState, Params, CutCellQuadOrder, AgglomeratedCellLengthScales);

                    foreach (var kv in AgglomeratedCellLengthScales)
                    {
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].EdgeLengthScales = this.LsTrk.GridDat.Edges.h_max_Edge;
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion);
                    }

                    if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                    {
                        foreach (var kv in InterfaceLengths)
                        {
                            mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                        }
                    }

                    mtxBuilder.time = time;
                    mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);

                    foreach (var kv in AgglomeratedCellLengthScales)
                    {
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("Weissenbergnumber", currentWeissenberg);
                    }
                }
                else
                {
                    throw new NotImplementedException("The FDbuilder for the Jacobian is missing for the XSpatial Opearator!");
                    // Finite Difference Linearization
                    //XSpatialOperatorMk2.XEvaluatorLinear FDBuilder = this.m_XOp.GetFDJacobianBuilder(domMap, Params, codMap, this.ParameterUpdate);

                    //foreach (var kv in AgglomeratedCellLengthScales) {
                    //    FDbuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    //    FDbuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                    //    FDbuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion);
                    //}

                    //if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0) {
                    //    foreach (var kv in InterfaceLengths) {
                    //        FDbuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    //    }
                    //}
                    //FDbuilder.time = time;

                    //FDbuilder.ComputeMatrix(OpMatrix, OpAffine);

                    //// FDJacobian has (Mx +b) as RHS, for unsteady calc. we must subtract Mx for real affine Vector!
                    //OpMatrix.SpMV(-1.0, new CoordinateVector(CurrentState), 1.0, OpAffine);

                    //foreach (var kv in AgglomeratedCellLengthScales) {
                    //    FDbuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("Weissenbergnumber", currentWeissenberg);
                    //}
                }
            }
            else
            {
                XSpatialOperatorMk2.XEvaluatorNonlin eval = this.m_XOp.GetEvaluatorEx(this.LsTrk,
                                                                                      CurrentState.ToArray(), Params, RowMapping,
                                                                                      SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    eval.SpeciesOperatorCoefficients[kv.Key].EdgeLengthScales = this.LsTrk.GridDat.Edges.h_max_Edge;
                    eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                    eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion);
                    eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("Weissenbergnumber", currentWeissenberg);
                }

                if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                eval.time = time;

                eval.Evaluate(1.0, 1.0, OpAffine);
            }
        }
Exemplo n.º 13
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);
        }
Exemplo n.º 14
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];
            MultiphaseCellAgglomerator Agg;
            MassMatrixFactory          Mfact;

            // Agglomerator setup
            int quadOrder = Op.QuadOrderFunction(new int[] { u.Basis.Degree }, new int[0], new int[] { u.Basis.Degree });

            //Agg = new MultiphaseCellAgglomerator(new CutCellMetrics(MomentFittingVariant, quadOrder, LsTrk, ), this.THRESHOLD, false);
            Agg = LsTrk.GetAgglomerator(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, quadOrder, this.THRESHOLD);

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

            // operator matrix assembly
            //Op.ComputeMatrixEx(LsTrk,
            //    u.Mapping, null, u.Mapping,
            //    OperatorMatrix, Affine, false, 0.0, true,
            //    Agg.CellLengthScales, null, null,
            //    LsTrk.GetSpeciesId("B"));
            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, u.Mapping, null, u.Mapping, LsTrk.GetSpeciesId("B"));
            mtxBuilder.time = 0.0;
            mtxBuilder.ComputeMatrix(OperatorMatrix, Affine);
            Agg.ManipulateMatrixAndRHS(OperatorMatrix, Affine, u.Mapping, u.Mapping);

            // mass matrix factory
            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);
            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
            if (TimestepNo > 1)
            {
                if (this.THRESHOLD > 0.01)
                {
                    // 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, 1.0e-6);
                }
                Assert.LessOrEqual(xL2Err, 1.0e-6);
            }

            bool IsPassed = ((L2Err <= 1.0e-6 || this.THRESHOLD <= 0.01) && xL2Err <= 1.0e-7);

            if (IsPassed)
            {
                Console.WriteLine("Test PASSED");
            }
            else
            {
                Console.WriteLine("Test FAILED: check errors.");
            }

            // return/Ende
            base.NoOfTimesteps = 17;
            //base.NoOfTimesteps = 2;
            dt = 0.3;
            return(dt);
        }
Exemplo n.º 15
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
        }
Exemplo n.º 16
0
        protected virtual void DelComputeOperatorMatrix(BlockMsrMatrix OpMatrix, double[] OpAffine, UnsetteledCoordinateMapping Mapping, DGField[] CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double phystime)
        {
            OpAffine.ClearEntries();

            bool Eval = false;

            if (OpMatrix == null)
            {
                Eval     = true;
                OpMatrix = new BlockMsrMatrix(uResidual.Mapping, u.Mapping);
            }
            else
            {
                OpMatrix.Clear();
            }

            //Op.ComputeMatrixEx(base.LsTrk,
            //    u.Mapping, null, uResidual.Mapping,
            //    OpMatrix, OpAffine, false,
            //    phystime,
            //    false,
            //    base.LsTrk.SpeciesIdS.ToArray());
            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, u.Mapping, null, uResidual.Mapping, base.LsTrk.SpeciesIdS.ToArray());

            foreach (var kv in AgglomeratedCellLengthScales)
            {
                mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
            }

            mtxBuilder.time = phystime;
            mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);

            if (Eval)
            {
                OpMatrix.SpMV(1.0, new CoordinateVector(CurrentState), 1.0, OpAffine);
            }


            /*
             * if (!Mapping.EqualsPartition(uResidual.Mapping))
             *  throw new ArgumentException();
             *
             * if (OpMatrix != null) {
             *  OpMatrix.Clear();
             *  OpAffine.ClearEntries();
             *
             *  Op.ComputeMatrixEx(base.LsTrk,
             *      u.Mapping, null, Mapping,
             *      OpMatrix, OpAffine, false,
             *      phystime,
             *      false,
             *      base.LsTrk.SpeciesIdS.ToArray());
             * } else {
             *  var eval = Op.GetEvaluatorEx(base.LsTrk,
             *      CurrentState, null, Mapping,
             *      base.LsTrk.SpeciesIdS.ToArray());
             *
             *  eval.time = phystime;
             *
             *  eval.Evaluate(1.0, 1.0, OpAffine);
             * }
             */
        }