Esempio n. 1
0
 /// <summary>
 /// ctor.
 /// </summary>
 /// <param name="xb">
 /// XDG basis on original grid
 /// </param>
 /// <param name="parentBasis">
 /// basis on parent grid
 /// </param>
 /// <param name="ag">
 /// aggregation grid level.
 /// </param>
 /// <param name="inj">
 /// injection operators.
 /// </param>
 internal XdgAggregationBasis(XDGBasis xb, XdgAggregationBasis parentBasis, AggregationGridData ag, MultidimensionalArray[] inj)
     : base(xb.NonX_Basis, parentBasis, ag, inj) //
 {
     using (new FuncTrace()) {
         this.XDGBasis        = xb;
         this.XCompositeBasis = new MultidimensionalArray[base.AggGrid.iLogicalCells.NoOfLocalUpdatedCells][];
     }
 }
Esempio n. 2
0
 public XdgAggregationBasis(XDGBasis xb, AggregationGrid ag)
     : base(xb.NonX_Basis, ag) //
 {
     using (new FuncTrace()) {
         this.XDGBasis        = xb;
         this.XCompositeBasis = new MultidimensionalArray[base.AggGrid.iLogicalCells.NoOfLocalUpdatedCells][];
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Initialization of the solver/preconditioner.
        /// </summary>
        protected void InitMultigrid(DGField[] Fields, bool useX)
        {
            Basis[] bs;
            if (useX)
            {
                bs = new Basis[Fields.Length];
                for (int i = 0; i < bs.Length; i++)
                {
                    bs[i] = new XDGBasis(m_LsTrk, Fields[i].Basis.Degree);
                }
            }
            else
            {
                bs = Fields.Select(f => f.Basis).ToArray();
            }

            this.MultigridBasis = AggregationGridBasis.CreateSequence(this.MultigridSequence, bs);
        }
Esempio n. 4
0
        protected override void CreateFields()
        {
            LevSet     = new LevelSet(new Basis(this.GridData, 2), "LevelSet");
            base.LsTrk = new LevelSetTracker((GridData)this.GridData, XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes, 1, new string[] { "A", "B" }, LevSet);

            var xBasis = new XDGBasis(base.LsTrk, DEGREE);

            u         = new XDGField(xBasis, "u");
            uResidual = new XDGField(xBasis, "Res");
            uEx       = new XDGField(xBasis, "uEx");

            Amarker     = new SinglePhaseField(new Basis(this.GridData, 0), "Amarker");
            Bmarker     = new SinglePhaseField(new Basis(this.GridData, 0), "Bmarker");
            MPICellRank = new SinglePhaseField(new Basis(this.GridData, 0), "MPIRank");
            base.m_RegisteredFields.Add(LevSet);
            base.m_RegisteredFields.Add(u);
            base.m_RegisteredFields.Add(uEx);
            base.m_RegisteredFields.Add(uResidual);
            base.m_RegisteredFields.Add(Amarker);
            base.m_RegisteredFields.Add(Bmarker);
            base.m_RegisteredFields.Add(MPICellRank);
        }
Esempio n. 5
0
        protected override void CreateFields()
        {
            LevSet     = new LevelSet(new Basis(this.GridData, 2), "LevelSet");
            base.LsTrk = new LevelSetTracker(this.GridData, 1, new string[] { "A", "B" }, LevSet);

            var xBasis = new XDGBasis(base.LsTrk, DEGREE);

            u         = new XDGField(xBasis, "u");
            uResidual = new XDGField(xBasis, "Res");
            uEx       = new XDGField(xBasis, "uEx");

            Amarker     = new SinglePhaseField(new Basis(this.GridData, 0), "Amarker");
            Bmarker     = new SinglePhaseField(new Basis(this.GridData, 0), "Bmarker");
            MPICellRank = new SinglePhaseField(new Basis(this.GridData, 0), "MPIRank");
            base.m_RegisteredFields.Add(LevSet);
            base.m_RegisteredFields.Add(u);
            base.m_RegisteredFields.Add(uEx);
            base.m_RegisteredFields.Add(uResidual);
            base.m_RegisteredFields.Add(Amarker);
            base.m_RegisteredFields.Add(Bmarker);
            base.m_RegisteredFields.Add(MPICellRank);
        }
Esempio n. 6
0
            public XDGTestSetup(
                int p,
                double AggregationThreshold,
                int TrackerWidth,
                MultigridOperator.Mode mumo,
                XQuadFactoryHelper.MomentFittingVariants momentFittingVariant,
                ScalarFunction LevSetFunc = null)
            {
                // Level set, tracker and XDG basis
                // ================================

                if (LevSetFunc == null)
                {
                    LevSetFunc = ((_2D)((x, y) => 0.8 * 0.8 - x * x - y * y)).Vectorize();
                }
                LevSet = new LevelSet(new Basis(grid, 2), "LevelSet");
                LevSet.Clear();
                LevSet.ProjectField(LevSetFunc);
                LsTrk = new LevelSetTracker(grid, XQuadFactoryHelper.MomentFittingVariants.Classic, TrackerWidth, new string[] { "A", "B" }, LevSet);
                LsTrk.UpdateTracker();

                XB = new XDGBasis(LsTrk, p);

                XSpatialOperator Dummy = new XSpatialOperator(1, 0, 1, QuadOrderFunc.SumOfMaxDegrees(RoundUp: true), "C1", "u");

                //Dummy.EquationComponents["c1"].Add(new
                Dummy.Commit();

                //Tecplot.PlotFields(new DGField[] { LevSet }, "agglo", 0.0, 3);


                // operator
                // ========

                Debug.Assert(p <= 4);
                XDGBasis opXB = new XDGBasis(LsTrk, 4); // we want to have a very precise quad rule
                var      map  = new UnsetteledCoordinateMapping(opXB);

                int quadOrder = Dummy.QuadOrderFunction(map.BasisS.Select(bs => bs.Degree).ToArray(), new int[0], map.BasisS.Select(bs => bs.Degree).ToArray());

                //agg = new MultiphaseCellAgglomerator(new CutCellMetrics(momentFittingVariant, quadOrder, LsTrk, LsTrk.SpeciesIdS.ToArray()), AggregationThreshold, false);
                agg = LsTrk.GetAgglomerator(LsTrk.SpeciesIdS.ToArray(), quadOrder, __AgglomerationTreshold: AggregationThreshold);


                foreach (var S in LsTrk.SpeciesIdS)
                {
                    Console.WriteLine("Species {0}, no. of agglomerated cells {1} ",
                                      LsTrk.GetSpeciesName(S),
                                      agg.GetAgglomerator(S).AggInfo.SourceCells.Count());
                }

                // mass matrix factory
                // ===================

                // Basis maxB = map.BasisS.ElementAtMax(b => b.Degree);
                //MassFact = new MassMatrixFactory(maxB, agg);
                MassFact = LsTrk.GetXDGSpaceMetrics(LsTrk.SpeciesIdS.ToArray(), quadOrder, 1).MassMatrixFactory;


                // Test field
                // ==========

                // set the test field: this is a polynomial function,
                // but different for each species; On this field, restriction followed by prolongation should be the identity
                this.Xdg_uTest = new XDGField(this.XB, "uTest");
                Dictionary <SpeciesId, double> dumia = new Dictionary <SpeciesId, double>();
                int i = 2;

                foreach (var Spc in LsTrk.SpeciesIdS)
                {
                    dumia.Add(Spc, i);
                    i -= 1;
                }
                SetTestValue(Xdg_uTest, dumia);


                // dummy operator matrix which fits polynomial degree p
                // ====================================================

                Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping);
                Xdg_opMtx.AccEyeSp(120.0);

                // XDG Aggregation BasiseS
                // =======================

                //XAggB = MgSeq.Select(agGrd => new XdgAggregationBasis[] { new XdgAggregationBasis(uTest.Basis, agGrd) }).ToArray();
                XAggB = new XdgAggregationBasis[MgSeq.Length][];
                var _XAggB = AggregationGridBasis.CreateSequence(MgSeq, Xdg_uTest.Mapping.BasisS);

                for (int iLevel = 0; iLevel < XAggB.Length; iLevel++)
                {
                    XAggB[iLevel] = new[] { (XdgAggregationBasis)(_XAggB[iLevel][0]) };
                    XAggB[iLevel][0].Update(agg);
                }

                // Multigrid Operator
                // ==================



                Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping);
                Xdg_opMtx.AccEyeSp(120.0);

                XdgMultigridOp = new MultigridOperator(XAggB, Xdg_uTest.Mapping,
                                                       Xdg_opMtx,
                                                       MassFact.GetMassMatrix(Xdg_uTest.Mapping, false),
                                                       new MultigridOperator.ChangeOfBasisConfig[][] {
                    new MultigridOperator.ChangeOfBasisConfig[] {
                        new MultigridOperator.ChangeOfBasisConfig()
                        {
                            VarIndex = new int[] { 0 }, mode = mumo, Degree = p
                        }
                    }
                });
            }
Esempio n. 7
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.");
             * }
             */
        }
Esempio n. 8
0
        /// <summary>
        /// Computes a mapping from the new, cell local DG coordinate index to the previous/old DG coordinate index, or vice-versa.
        /// </summary>
        /// <param name="jCell">
        /// Local cell index.
        /// </param>
        /// <param name="New2Old">
        /// If true, a mapping from new species index to previous/old species index is returned,
        /// if false the other way around.
        /// </param>
        /// <param name="LsTrk">
        /// </param>
        /// <param name="Map">
        /// DG coordinate mapping.
        /// </param>
        /// <returns>
        /// Null, if there is no change in species ordering in cell <paramref name="jCell"/>
        /// from the previous level-set tracker state to the actual.
        ///
        /// Otherwise, if <paramref name="New2Old"/> is true, an array of the same length
        /// as the number of degrees-of-freedom currently in cell <paramref name="jCell"/>.
        ///  - index: current DOF index in cell <paramref name="jCell"/>.
        ///  - content: index of this DOF with respect to the previous level-set-tracker state.
        /// If <paramref name="New2Old"/> false, the other way around.
        /// </returns>
        public static int[] MappingUpdate(LevelSetTracker LsTrk, int jCell, UnsetteledCoordinateMapping Map, bool New2Old)
        {
            int[] SpeciesMap = SpeciesUpdate(LsTrk, jCell, New2Old);
            if (SpeciesMap == null)
            {
                return(null);
            }

            int NoVar = Map.NoOfVariables;

            XDGBasis[] XBasiseS = new XDGBasis[NoVar];
            Basis[]    BasiseS  = new Basis[NoVar];
            int[]      Ns       = new int[NoVar];

            for (int iVar = 0; iVar < NoVar; iVar++)
            {
                Basis b = Map.BasisS[iVar];
                XBasiseS[iVar] = b as XDGBasis;
                if (XBasiseS[iVar] != null)
                {
                    BasiseS[iVar] = XBasiseS[iVar].NonX_Basis;
                }
                else
                {
                    BasiseS[iVar] = b;
                }
                Ns[iVar] = BasiseS[iVar].Length;
            }

            //List<int> oldIdx = new List<int>();
            //List<int> newIdx = new List<int>();
            int[] IdxMap = new int[Map.MaxTotalNoOfCoordinatesPerCell];
            ArrayTools.SetAll(IdxMap, int.MinValue);

            bool AnyRelocation = false;

            int i0 = Map.LocalUniqueCoordinateIndex(0, jCell, 0);

            for (int iVar = 0; iVar < NoVar; iVar++)
            {
                int i0Var  = Map.LocalUniqueCoordinateIndex(iVar, jCell, 0);
                int N      = Ns[iVar];
                int offset = i0Var - i0;

                if (XBasiseS[iVar] != null)
                {
                    // XDG-field

                    for (int i = 0; i < SpeciesMap.Length; i++)
                    {
                        int ii = SpeciesMap[i];
                        for (int n = 0; n < N; n++)
                        {
                            int idxS = offset + n + i * N;
                            int idxT = ii >= 0 ? offset + n + ii * N : int.MinValue;
                            Debug.Assert(IdxMap[idxS] < 0);
                            IdxMap[idxS] = idxT;

                            AnyRelocation |= (idxS != idxT);
                        }
                    }
                }
                else
                {
                    // single-phase-field
                    for (int n = 0; n < N; n++)
                    {
                        int idx = offset + n;
                        //oldIdx.Add(idx);
                        //newIdx.Add(idx);
                        Debug.Assert(IdxMap[idx] < 0);
                        IdxMap[idx] = idx;
                    }
                }
            }

            return(IdxMap);
            //if (AnyRelocation)
            //    return IdxMap;
            //else
            //    return null;
        }
Esempio 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);
            }
        }
Esempio 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);
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Backup data for some DG field before update of grid.
        /// </summary>
        /// <param name="f"></param>
        /// <param name="Reference">
        /// Unique string reference under which the re-distributed data can be accessed later, within <see cref="RestoreDGField(DGField, string)"/>.
        /// </param>
        override public void BackupField(DGField f, string Reference)
        {
            if (!object.ReferenceEquals(f.GridDat, m_OldGrid))
            {
                throw new ArgumentException("DG field seems to be assigned to some other grid.");
            }
            double[][] oldFieldsData = new double[m_oldJ][];
            m_oldDGFieldData.Add(Reference, oldFieldsData);

            if (f is ConventionalDGField)
            {
                Basis oldBasis = f.Basis;
                int   Nj       = oldBasis.Length;

                for (int j = 0; j < m_oldJ; j++)
                {
                    double[] data_j = new double[Nj];
                    for (int n = 0; n < Nj; n++)
                    {
                        data_j[n] = f.Coordinates[j, n];
                    }

                    oldFieldsData[j] = data_j;
                }
            }
            else if (f is XDGField)
            {
                XDGField xf = f as XDGField;
                XDGBasis xb = xf.Basis;
                int      Np = xb.NonX_Basis.Length;
                if (!object.ReferenceEquals(m_OldTracker, xb.Tracker))
                {
                    throw new ArgumentException("LevelSetTracker seems duplicate, or something.");
                }
                LevelSetTracker lsTrk = m_OldTracker;

                for (int j = 0; j < m_oldJ; j++)
                {
                    int NoOfSpc = lsTrk.Regions.GetNoOfSpecies(j);

                    int Nj = xb.GetLength(j);
                    Debug.Assert(Nj == NoOfSpc * Np);

                    double[] data_j = new double[Nj + NoOfSpc + 1];
                    data_j[0] = NoOfSpc;
                    int c = 1;
                    for (int iSpc = 0; iSpc < NoOfSpc; iSpc++)
                    {
                        SpeciesId spc = lsTrk.Regions.GetSpeciesIdFromIndex(j, iSpc);
                        data_j[c] = spc.cntnt;
                        c++;
                        for (int n = 0; n < Np; n++)
                        {
                            data_j[c] = f.Coordinates[j, n + Np * iSpc];
                            c++;
                        }
                    }
                    Debug.Assert(data_j.Length == c);

                    oldFieldsData[j] = data_j;
                }
            }
            else
            {
                throw new NotSupportedException();
            }
        }
Esempio n. 12
0
        void ParameterUpdate(IEnumerable <DGField> CurrentState, IEnumerable <DGField> ParameterVar, int CutCellQuadOrder, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales)
        {
            LevelSet Phi = (LevelSet)(this.LsTrk.LevelSets[0]);

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

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

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

                U0mean.Clear();
                ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }


            //if (this.Control.SetParamsAnalyticalSol == false) {
            //SinglePhaseField[] __VelocityXGradient = ParameterVar.Skip(2 * D).Take(D).Select(f => f as SinglePhaseField).ToArray();
            //SinglePhaseField[] __VelocityYGradient = ParameterVar.Skip(3 * D).Take(D).Select(f => f as SinglePhaseField).ToArray();
            //Debug.Assert(ArrayTools.AreEqual(__VelocityXGradient, VelocityXGradient.ToArray(), (fa, fb) => object.ReferenceEquals(fa, fb)));
            //Debug.Assert(ArrayTools.AreEqual(__VelocityYGradient, VelocityYGradient.ToArray(), (fa, fb) => object.ReferenceEquals(fa, fb)));

            //if (VelocityXGradient == null) {
            //    VelocityXGradient = new VectorField<XDGField>(D, CurrentState.ElementAt(0).Basis, "VelocityX_Gradient", XDGField.Factory);
            //}
            VelocityXGradient.Clear();
            VelocityXGradient.GradientByFlux(1.0, U0[0]);
            //if (VelocityYGradient == null) {
            //    VelocityYGradient = new VectorField<XDGField>(D, CurrentState.ElementAt(1).Basis, "VelocityY_Gradient", XDGField.Factory);
            //}
            VelocityYGradient.Clear();
            VelocityYGradient.GradientByFlux(1.0, U0[1]);
            //}

            if (this.useArtificialDiffusion == true)
            {
                throw new NotImplementedException("artificial diffusion not jet fully implemented...");
                //SinglePhaseField __ArtificialViscosity = ParameterVar.Skip(5 * D + 1).Take(1).Select(f => f as SinglePhaseField).ToArray()[0];
                //if (!object.ReferenceEquals(this.artificalViscosity, __ArtificialViscosity))
                //    throw new ApplicationException();

                //ArtificialViscosity.ProjectArtificalViscosityToDGField(__ArtificialViscosity, perssonsensor, this.Control.SensorLimit, artificialMaxViscosity);
            }
        }
Esempio n. 13
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);
            }
        }
Esempio n. 14
0
        /// <summary>
        ///
        /// </summary>
        public void AssembleMatrix_Timestepper <T>(
            int CutCellQuadOrder,
            BlockMsrMatrix OpMatrix, double[] OpAffine,
            Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales,
            IEnumerable <T> U0,
            VectorField <SinglePhaseField> SurfaceForce,
            VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature,
            UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
            double time) 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 (U0 != null && U0.Count() != D)
            {
                throw new ArgumentException();
            }


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

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


            // 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];
            }

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

            // 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
            Op.ComputeMatrixEx(Tracker,
                               ColMapping, Params, RowMapping,
                               OpMatrix, OpAffine, false, time, true,
                               AgglomeratedCellLengthScales,
                               SpcToCompute);
        }
Esempio n. 15
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ProblemMapping"></param>
        /// <param name="MultigridSequence"></param>
        /// <param name="useX">
        /// Create an XDG aggregation basis even if <paramref name="ProblemMapping"/> only contains DG basis.
        /// </param>
        /// <returns></returns>
        public static AggregationGridBasis[][] CreateAggregationGridBasis(UnsetteledCoordinateMapping ProblemMapping, LevelSetTracker _LsTrk, AggregationGrid[] MultigridSequence, bool useX)
        {
            Debug.Assert(object.ReferenceEquals(_LsTrk.GridDat, ProblemMapping.GridDat));
            Basis[] BasisS = ProblemMapping.BasisS.ToArray();
            Debug.Assert(BasisS.Where(b => !object.ReferenceEquals(b.GridDat, _LsTrk.GridDat)).Count() == 0);
            AggregationGridBasis[][] MultigridBasis = new AggregationGridBasis[MultigridSequence.Length][];



            XDGBasis maxXDGbasis = null;
            Basis    maxDGbasis  = null;

            foreach (var b in BasisS)
            {
                if (b is XDGBasis)
                {
                    XDGBasis xb = (XDGBasis)b;
                    if (maxXDGbasis == null || maxXDGbasis.Degree < xb.Degree)
                    {
                        maxXDGbasis = xb;
                    }
                }
                else
                {
                    if (maxDGbasis == null || maxDGbasis.Degree < b.Degree)
                    {
                        maxDGbasis = b;
                    }
                }
            }

            if (useX)
            {
                if (maxDGbasis != null)
                {
                    if (maxXDGbasis == null || maxXDGbasis.Degree < maxDGbasis.Degree)
                    {
                        maxXDGbasis = new XDGBasis(_LsTrk, maxDGbasis.Degree);
                    }
                }
            }


            XdgAggregationBasis[] mgXdgB;
            if (maxXDGbasis != null)
            {
                mgXdgB = MultigridSequence.Select(aggGrd => new XdgAggregationBasis(maxXDGbasis, aggGrd)).ToArray();
            }
            else
            {
                mgXdgB = null;
            }


            AggregationGridBasis[] mgDgB;
            if (maxDGbasis != null)
            {
                mgDgB = MultigridSequence.Select(aggGrd => new AggregationGridBasis(maxDGbasis, aggGrd)).ToArray();
            }
            else
            {
                mgDgB = null;
            }

            for (int iLevel = 0; iLevel < MultigridSequence.Length; iLevel++)
            {
                MultigridBasis[iLevel] = new AggregationGridBasis[BasisS.Length];
                for (int r = 0; r < BasisS.Length; r++)
                {
                    if (BasisS[r] is XDGBasis || useX)
                    {
                        MultigridBasis[iLevel][r] = mgXdgB[iLevel];
                    }
                    else
                    {
                        MultigridBasis[iLevel][r] = mgDgB[iLevel];
                    }
                }
            }

            return(MultigridBasis);
        }
Esempio n. 16
0
        protected override void CreateFields()
        {
            // Create level set and level set tracker
            this.LevelSet        = new LevelSet(new Basis(this.GridData, this.Control.LevelSetDegree), XDGShockVariables.LevelSet);
            this.LevelSetTracker = new LevelSetTracker((GridData)this.GridData, XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes, 1, new string[] { "A", "B" }, this.LevelSet);
            base.LsTrk           = this.LevelSetTracker;

            // Create mandatory conservative fields
            int D = CompressibleEnvironment.NumberOfDimensions;

            this.Density = new XDGField(new XDGBasis(this.LevelSetTracker, this.Control.DensityDegree), CompressibleVariables.Density);
            XDGField[] momentumFields = new XDGField[D];
            XDGBasis   momentumBasis  = new XDGBasis(this.LevelSetTracker, this.Control.MomentumDegree);

            for (int d = 0; d < D; d++)
            {
                string variableName = CompressibleVariables.Momentum[d];
                momentumFields[d] = new XDGField(momentumBasis, variableName);
            }
            this.Momentum = new VectorField <XDGField>(momentumFields);
            this.Energy   = new XDGField(new XDGBasis(this.LevelSetTracker, this.Control.EnergyDegree), CompressibleVariables.Energy);

            // Create fields for residuals
            XDGBasis basis = new XDGBasis(this.LevelSetTracker, this.Control.DensityDegree);

            this.Residuals    = new XDGField[D + 2];
            this.Residuals[0] = new XDGField(basis, "residual_" + CompressibleVariables.Density);
            for (int d = 0; d < D; d++)
            {
                this.Residuals[d + 1] = new XDGField(basis, "residual_" + CompressibleVariables.Momentum[d]);
            }
            this.Residuals[D + 1] = new XDGField(basis, "residual_" + CompressibleVariables.Energy);

            // Create derived fields
            this.DerivedVariableToXDGFieldMap         = new Dictionary <DerivedVariable <XDGField>, XDGField>();
            this.DerivedVariableToSinglePhaseFieldMap = new Dictionary <DerivedVariable <SinglePhaseField>, SinglePhaseField>();
            foreach (KeyValuePair <Variable, int> pair in this.Control.VariableToDegreeMap)
            {
                Variable variable = pair.Key;
                int      degree   = pair.Value;

                if (variable is DerivedVariable <XDGField> xdgVar)
                {
                    this.DerivedVariableToXDGFieldMap.Add(xdgVar, new XDGField(new XDGBasis(this.LevelSetTracker, degree), variable.Name));
                }
                else if (variable is DerivedVariable <SinglePhaseField> singleVar)
                {
                    this.DerivedVariableToSinglePhaseFieldMap.Add(singleVar, new SinglePhaseField(new Basis(this.GridData, degree), variable.Name));
                }
            }

            // Register all fields for plotting
            // Fields for the conservative variables are plotted in any case
            this.m_IOFields.Add(LevelSet);
            this.m_IOFields.AddRange(ConservativeFields);
            this.m_IOFields.AddRange(DerivedVariableToXDGFieldMap.Values);
            this.m_IOFields.AddRange(DerivedVariableToSinglePhaseFieldMap.Values);

            // Register fields for, e.g. applying the initial conditions;
            this.m_RegisteredFields.Add(LevelSet);
            this.m_RegisteredFields.AddRange(ConservativeFields);
            this.m_RegisteredFields.AddRange(DerivedVariableToXDGFieldMap.Values);
            this.m_RegisteredFields.AddRange(DerivedVariableToSinglePhaseFieldMap.Values);

            // Add sensor
            if (this.Control.SensorVariable != null)
            {
                switch (this.Control.SensorType)
                {
                case SensorTypes.PerssonSensor:
                    this.Sensor = new XDGPerssonSensor(ConservativeFields.First(s => s.Identification.Equals(this.Control.SensorVariable)), this.Control.SensorLimit, this.LevelSetTracker, this.NonlinearQuadratureDegree);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }

            // Initialize artificial viscosity field, if artificial viscosity has been activated in the control file
            if (this.Control.VariableToDegreeMap.ContainsKey(XDGShockVariables.ArtificialViscosity))
            {
                this.ArtificialViscosityField = new SinglePhaseField(new Basis(this.GridData, 2), "artificialViscosity");

                switch (this.Control.ArtificialViscosityLawType)
                {
                case ArtificialViscosityLawTypes.SmoothedHeaviside:
                    this.ArtificialViscosityLaw = new SmoothedHeavisideArtificialViscosityLaw(this.Sensor, ConservativeFields.First(s => s.Identification.Equals(this.Control.SensorVariable)).Basis.Degree, this.Control.SensorLimit);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }