示例#1
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.");
             * }
             */
        }
        /// <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);
            }
        }
示例#3
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);
            }
        }
示例#4
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);
        }