コード例 #1
0
ファイル: NECQuadratureLevelSet.cs プロジェクト: xyuan/BoSSS
        protected override void Evaluate(int i0, int Len, QuadRule QR, MultidimensionalArray EvalResult)
        {
            NodeSet QuadNodes = QR.Nodes;
            int     D         = gridData.SpatialDimension;
            int     NoOfNodes = QuadNodes.NoOfNodes;
            int     GAMMA     = m_CodomainMap.NoOfVariables; // GAMMA: number of codom variables


            // Evaluate Domain & Parameter fields
            // --------------------------------

            Field_Eval.Start();

            for (int i = 0; i < m_DomainAndParamFields.Length; i++)
            {
                if (m_ValueRequired[i])
                {
                    DGField _Field = m_DomainAndParamFields[i];
                    if (_Field != null)
                    {
                        if (_Field is XDGField)
                        {
                            // jump in parameter i at level-set: separate evaluation for both sides
                            var _xField = _Field as XDGField;

                            _xField.GetSpeciesShadowField(this.SpeciesA).Evaluate(i0, Len, QuadNodes, m_FieldValuesNeg[i]);
                            _xField.GetSpeciesShadowField(this.SpeciesB).Evaluate(i0, Len, QuadNodes, m_FieldValuesPos[i]);
                        }
                        else
                        {
                            // no jump at level set: positive and negative limit of parameter i are equal
                            _Field.Evaluate(i0, Len, QuadNodes, m_FieldValuesPos[i]);
                            m_FieldValuesNeg[i].Set(m_FieldValuesPos[i]);
                        }
                    }
                    else
                    {
                        m_FieldValuesPos[i].Clear();
                        m_FieldValuesNeg[i].Clear();
                    }
                }

                if (m_GradientRequired[i])
                {
                    DGField _Field = m_DomainAndParamFields[i];
                    if (_Field != null)
                    {
                        if (_Field is XDGField)
                        {
                            // jump in parameter i at level-set: separate evaluation for both sides
                            var _xField = _Field as XDGField;

                            _xField.GetSpeciesShadowField(this.SpeciesA).EvaluateGradient(i0, Len, QuadNodes, m_FieldGradientValuesNeg[i]);
                            _xField.GetSpeciesShadowField(this.SpeciesB).EvaluateGradient(i0, Len, QuadNodes, m_FieldGradientValuesPos[i]);
                        }
                        else
                        {
                            // no jump at level set: positive and negative limit of parameter i are equal
                            _Field.EvaluateGradient(i0, Len, QuadNodes, m_FieldGradientValuesPos[i]);
                            m_FieldGradientValuesNeg[i].Set(m_FieldGradientValuesPos[i]);
                        }
                    }
                    else
                    {
                        m_FieldGradientValuesPos[i].Clear();
                        m_FieldGradientValuesNeg[i].Clear();
                    }
                }
            }

            Field_Eval.Stop();

            // Evaluate level sets and normals
            // -------------------------------

            ParametersAndNormals.Start();
            var NoOfLevSets = m_lsTrk.LevelSets.Count;
            MultidimensionalArray Normals     = m_lsTrk.DataHistories[m_LevSetIdx].Current.GetLevelSetNormals(QuadNodes, i0, Len);
            MultidimensionalArray NodesGlobal = gridData.GlobalNodes.GetValue_Cell(QuadNodes, i0, Len);

            ParametersAndNormals.Stop();

            // Evaluate basis and test functions
            // ---------------------------------

            bool[] ReqV     = new bool[GAMMA];
            bool[] ReqGradV = new bool[GAMMA];

            for (int gamma = 0; gamma < GAMMA; gamma++)
            {
                if (Koeff_V[gamma] != null)
                {
                    ReqV[gamma] = true;
                }
                if (Koeff_GradV[gamma] != null)
                {
                    ReqGradV[gamma] = true;
                }
            }

            MultidimensionalArray[] TestValues;         //            index: codom variable/test function
            MultidimensionalArray[] TestGradientValues; //    index: codom variable/test function
            int[,] sectionsTest;
            Basis_Eval.Start();
            LECQuadratureLevelSet <IMutableMatrixEx, double[]>
            .EvalBasis(i0, Len, this.m_CodomainMap.BasisS, ReqV, ReqGradV, out TestValues, out TestGradientValues, out sectionsTest, QuadNodes);

            Basis_Eval.Stop();


            // Evaluate Integral components
            // ----------------------------


            // loop over codomain variables ...
            for (int gamma = 0; gamma < GAMMA; gamma++)
            {
                // prepare parameters
                // - - - - - - - - -

                // set Normal's
                LevSetIntParams _inParams = new LevSetIntParams();
                _inParams.Normal = Normals;
                // set Nodes Global
                _inParams.X     = NodesGlobal;
                _inParams.time  = this.time;
                _inParams.LsTrk = this.m_lsTrk;
                _inParams.i0    = i0;
                Debug.Assert(_inParams.Len == Len);


                // clear summation buffers
                // - - - - - - - - - - - -

                if (Koeff_V[gamma] != null)
                {
                    Koeff_V[gamma].Clear();
                }
                if (Koeff_GradV[gamma] != null)
                {
                    Koeff_GradV[gamma].Clear();
                }


                // Evaluate Bilin. forms
                // - - - - - - - - - - -

                {
                    EvalComponent(_inParams, gamma, this.m_NonlinLsForm_V[gamma], this.m_NonlinLsForm_V_Watches[gamma],
                                  Koeff_V[gamma],
                                  m_FieldValuesPos, m_FieldValuesNeg, m_FieldGradientValuesPos, m_FieldGradientValuesNeg,
                                  DELTA,
                                  Flux_Eval,
                                  delegate(INonlinLevelSetForm_V _comp, LevSetIntParams inp, MultidimensionalArray[] uA, MultidimensionalArray[] uB, MultidimensionalArray[] Grad_uA, MultidimensionalArray[] Grad_uB, MultidimensionalArray SumBuf) {
                        _comp.LevelSetForm_V(_inParams, uA, uB, Grad_uA, Grad_uB, SumBuf);
                    });
                }
                {
                    EvalComponent(_inParams, gamma, this.m_NonlinLsForm_GradV[gamma], this.m_NonlinLsForm_GradV_Watches[gamma],
                                  Koeff_GradV[gamma],
                                  m_FieldValuesPos, m_FieldValuesNeg, m_FieldGradientValuesPos, m_FieldGradientValuesNeg,
                                  DELTA,
                                  Flux_Eval,
                                  delegate(INonlinLevelSetForm_GradV _comp, LevSetIntParams inp, MultidimensionalArray[] uA, MultidimensionalArray[] uB, MultidimensionalArray[] Grad_uA, MultidimensionalArray[] Grad_uB, MultidimensionalArray SumBuf) {
                        _comp.LevelSetForm_GradV(_inParams, uA, uB, Grad_uA, Grad_uB, SumBuf);
                    });
                }
            }

            // Summation Loops: multiply with test and trial functions
            // -------------------------------------------------------

            int[] offsetCod = new int[GAMMA];
            LECQuadratureLevelSet <IMutableMatrixEx, double[]> .
            CompOffsets(i0, Len, offsetCod, m_CodomainMap);

            for (int gamma = 0; gamma < GAMMA; gamma++)
            {
                // Evaluate Integrand
                // - - - - - - - - -

                var TestVal     = TestValues[gamma];
                var TestGradVal = TestGradientValues[gamma];
                int N;
                if (TestVal != null)
                {
                    N = TestVal.GetLength(2);
                }
                else if (TestGradVal != null)
                {
                    N = TestGradVal.GetLength(2);
                }
                else
                {
                    N = 0;
                }

                Loops.Start();



                // affine offset


                for (int cr = 0; cr < 2; cr++)  // loop over negative/positive species
                {
                    int[] extr0  = new int[] { 0, 0, sectionsTest[gamma, cr] * N + offsetCod[gamma] };
                    int[] extrE  = new int[] { Len - 1, NoOfNodes - 1, extr0[2] + N - 1 };
                    var   SubRes = EvalResult.ExtractSubArrayShallow(extr0, extrE);

                    if (Koeff_V[gamma] != null)
                    {
                        var Sum_Koeff_V_Cr = Koeff_V[gamma].ExtractSubArrayShallow(-1, -1, cr);
                        SubRes.Multiply(1.0, Sum_Koeff_V_Cr, TestVal, 1.0, "jkn", "jk", "jkn");
                    }
                    if (Koeff_GradV[gamma] != null)
                    {
                        var Sum_Koeff_NablaV_Cr = Koeff_GradV[gamma].ExtractSubArrayShallow(-1, -1, cr, -1);
                        SubRes.Multiply(1.0, Sum_Koeff_NablaV_Cr, TestGradVal, 1.0, "jkn", "jkd", "jknd");
                    }
                }


                Loops.Stop();
            }
        }
コード例 #2
0
        /// <summary>
        /// Addition/Subtraction of DG fields on different grids
        /// </summary>
        /// <param name="A"></param>
        /// <param name="scaleA"></param>
        /// <param name="B"></param>
        /// <param name="scaleB"></param>
        /// <returns>
        /// <paramref name="scaleA"/>*<paramref name="A"/> + <paramref name="scaleB"/>*<paramref name="B"/>
        /// </returns>
        static public DGField ScaledSummation(this DGField A, double scaleA, DGField B, double scaleB)
        {
            if (object.ReferenceEquals(A.GridDat, B.GridDat))
            {
                // ++++++++++++++++++++++++++++
                // both fields on the same grid
                // ++++++++++++++++++++++++++++

                DGField sum;

                if (A.Basis.IsSubBasis(B.Basis))
                {
                    sum = (DGField)B.Clone();
                    sum.Scale(scaleB);
                    sum.AccLaidBack(1.0, A);
                }
                else if (B.Basis.IsSubBasis(A.Basis))
                {
                    sum = (DGField)A.Clone();
                    sum.Scale(scaleA);
                    sum.AccLaidBack(1.0, B);
                }
                else
                {
                    throw new ApplicationException("can't add the two fields, because their basis are incompatible");
                }


                sum.Identification = "(" + scaleA + "*" + A.Identification + "+" + scaleB + "*" + B.Identification + ")";

                return(sum);
            }
            else
            {
                // ++++++++++++++++++++++++++
                // fields on different grids
                // ++++++++++++++++++++++++++

                DGField fine, coarse;
                double  aF, aC;
                if (A.GridDat.CellPartitioning.TotalLength > B.GridDat.CellPartitioning.TotalLength)
                {
                    fine   = A;
                    coarse = B;
                    aF     = scaleA;
                    aC     = scaleB;
                }
                else
                {
                    coarse = A;
                    fine   = B;
                    aC     = scaleA;
                    aF     = scaleB;
                }

                Foundation.Grid.Classic.GridData fineGridData   = GridHelper.ExtractGridData(fine.GridDat);
                Foundation.Grid.Classic.GridData coarseGridData = GridHelper.ExtractGridData(coarse.GridDat);

                DGFieldComparison.ComputeFine2CoarseMap(
                    fineGridData,
                    coarseGridData,
                    out var Fine2CoarseMapS);

                DGField injected;
                if (coarse is ConventionalDGField)
                {
                    ConventionalDGField _injected = new SinglePhaseField(
                        new Basis(fine.GridDat, Math.Max(coarse.Basis.Degree, fine.Basis.Degree)),
                        coarse.Identification);

                    DGFieldComparison.InjectDGField(Fine2CoarseMapS, _injected, coarse as ConventionalDGField);
                    injected = _injected;
                }
                else if (coarse is XDGField)
                {
                    XDGField _injected = new XDGField(
                        new XDGBasis((fine as XDGField).Basis.Tracker, Math.Max(coarse.Basis.Degree, fine.Basis.Degree)),
                        coarse.Identification);

                    DGFieldComparison.InjectXDGField(Fine2CoarseMapS, _injected, coarse as XDGField);
                    injected = _injected;
                }
                else
                {
                    throw new NotSupportedException();
                }

                return(ScaledSummation(injected, aC, fine, aF));
            }
        }
コード例 #3
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];
                    }

                    FwdTrafo(data_j, Nj, 0, (GridData)m_OldGrid, j, f.Basis.Degree);

                    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++)  // loop over species
                    {
                        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++;
                        }

                        FwdTrafo(data_j, Np, (Np + 1) * iSpc + 2, (GridData)m_OldGrid, j, f.Basis.Degree);
                    }
                    Debug.Assert(data_j.Length == c);

                    oldFieldsData[j] = data_j;
                }
            }
            else
            {
                throw new NotSupportedException();
            }
        }
コード例 #4
0
ファイル: ScalarFieldQuadrature.cs プロジェクト: xyuan/BoSSS
 public ScalarFieldQuadrature(IGridData gridData, DGField field, CellQuadratureScheme quadInstr, int quadOrder)
     : base(new int[] { 1 }, gridData, quadInstr.Compile(gridData, quadOrder))
 {
     this.field = field;
 }
コード例 #5
0
        public void UpdateSensorValues(CNSFieldSet fieldSet, ISpeciesMap speciesMap, CellMask cellMask)
        {
            DGField fieldToTest = fieldSet.ConservativeVariables.
                                  Concat(fieldSet.DerivedFields.Values).
                                  Where(f => f.Identification == sensorVariable.Name).
                                  Single();

            sensorValues = new SinglePhaseField(
                new Basis(fieldToTest.GridDat, 0));

            var quadrature = EdgeQuadrature.GetQuadrature(
                new int[] { 1 },
                (GridData)fieldToTest.GridDat,
                new EdgeQuadratureScheme().Compile(fieldToTest.GridDat, 2 * fieldToTest.Basis.Degree),
                delegate(int e0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                MultidimensionalArray gIn  = MultidimensionalArray.Create(Length, QR.NoOfNodes);
                MultidimensionalArray gOut = MultidimensionalArray.Create(Length, QR.NoOfNodes);
                fieldToTest.EvaluateEdge(
                    e0,
                    Length,
                    QR.Nodes,
                    gIn,
                    gOut,
                    MeanValueIN: null,
                    MeanValueOT: null,
                    GradientIN: null,
                    GradientOT: null,
                    ResultIndexOffset: 0,
                    ResultPreScale: 0.0);

                for (int e = 0; e < Length; e++)
                {
                    int edge = e + e0;

                    // Check if "out" neighbor exist; ignore boundary edges for now
                    int outCell = fieldToTest.GridDat.iLogicalEdges.CellIndices[edge, 1];
                    if (outCell < 0)
                    {
                        continue;
                    }

                    for (int node = 0; node < QR.NoOfNodes; node++)
                    {
                        double jump = gOut[e, node] - gIn[e, node];
                        double mean = 0.5 * (gOut[e, node] + gIn[e, node]);
                        double s    = jump / mean;
                        if (!double.IsNaN(s))
                        {
                            EvalResult[e, node, 0] = s * s / (Math.Sign(s) * s + 0.001);
                        }
                    }
                }
            },
                delegate(int e0, int Length, MultidimensionalArray ResultsOfIntegration) {
                for (int e = 0; e < Length; e++)
                {
                    int edge = e + e0;
                    for (int neighbor = 0; neighbor < 2; neighbor++)       // loop over IN/OUT cells
                    {
                        int jCell = fieldToTest.GridDat.iLogicalEdges.CellIndices[edge, neighbor];
                        if (jCell < 0)
                        {
                            break;
                        }

                        sensorValues.Coordinates[jCell, 0] += ResultsOfIntegration[e, 0];
                    }
                }
            });

            quadrature.Execute();
        }
コード例 #6
0
        /// <summary>
        /// ctor.
        /// </summary>
        /// <param name="context">the context which Bjoern loves so much</param>
        /// <param name="DiffOp">the spatial operator</param>
        /// <param name="_DomainFields">
        /// the mapping for the DG fields (variables) in the domain of the differential operator <paramref name="DiffOp"/>;
        /// </param>
        /// <param name="CodomainMapping">
        /// the mapping for the DG fields (variables) in the codomain of the differential operator <paramref name="DiffOp"/>;
        /// </param>
        /// <param name="ParamFields">
        /// the mapping for the DG fields (variables) in the parameter list of the differential operator <paramref name="DiffOp"/>;
        /// </param>
        protected NECQuadratureCommon(IGridData context,
                                      SpatialOperator DiffOp,
                                      IList <DGField> _DomainFields,
                                      IList <DGField> ParamFields,
                                      UnsetteledCoordinateMapping CodomainMapping)
        {
            // ---------------
            // check arguments
            // ---------------
            m_GrdDat          = context;
            m_CodomainMapping = CodomainMapping;
            if (ParamFields != null && ParamFields.Count > 0)
            {
                // concatenate parameters to domain mapping
                IList <DGField> dom = _DomainFields, param = ParamFields;
                DGField[]       fld = new DGField[dom.Count + param.Count];
                int             __i;
                for (__i = 0; __i < dom.Count; __i++)
                {
                    fld[__i] = dom[__i];
                }
                for (int j = 0; j < param.Count; j++)
                {
                    fld[j + __i] = param[j];
                }
                _DomainFields = fld;
            }

            m_CodomainBasisS = m_CodomainMapping.BasisS.ToArray();
            m_DomainFields   = _DomainFields.ToArray();

            _DomainFields = null;

            m_DifferentialOperator = DiffOp;

            if ((DiffOp.DomainVar.Count + DiffOp.ParameterVar.Count) != m_DomainFields.Length)
            {
                string extMsg;
                extMsg = "[DiffOp domain and parameter vars: ";
                for (int ii = 0; ii < DiffOp.DomainVar.Count; ii++)
                {
                    extMsg += (DiffOp.DomainVar[ii] + ", ");
                }
                extMsg += "; ";
                for (int ii = 0; ii < DiffOp.ParameterVar.Count; ii++)
                {
                    extMsg += (DiffOp.ParameterVar[ii] + ", ");
                }
                extMsg += "\n";
                extMsg += "Domain/Parameter mapping vars: ";
                for (int ii = 0; ii < m_DomainFields.Length; ii++)
                {
                    extMsg += (m_DomainFields[ii].Identification + ", ");
                }
                extMsg += "]";
                throw new ArgumentException("mismatch between number of domain variables: " + extMsg, "DomainMapping,DiffOp");
            }
            if (DiffOp.CodomainVar.Count != CodomainMapping.BasisS.Count)
            {
                throw new ArgumentException("mismatch between number of codomain variables", "CodomainMapping,DiffOp");
            }


            IList <Basis> CoDomBasisS = m_CodomainMapping.BasisS;

            m_NoOfTestFunctions = new int[CoDomBasisS.Count];
            m_MyMap             = new int[CoDomBasisS.Count];

            int i = 0;
            int c = 0;

            foreach (Basis b in CoDomBasisS)
            {
                m_NoOfTestFunctions[i] = b.Length;
                m_MyMap[i]             = c;
                c += m_NoOfTestFunctions[i];
                i++;
            }

            //m_MaxCodBasis = m_CodomainBasisS.ElementAtMax(bs => bs.Degree);
            //foreach(Basis bs in m_CodomainBasisS) {
            //    if(!bs.IsSubBasis(m_MaxCodBasis))
            //        throw new NotImplementedException();
            //}


            // ------------------------
            // sort equation components
            // ------------------------
            m_NonlinFluxes   = DiffOp.GetArgMapping <INonlinearFlux>(true);
            m_NonlinFluxesEx = DiffOp.GetArgMapping <INonlinearFluxEx>(true);
        }
コード例 #7
0
        /// <summary>
        /// Defines the force which is integrated over an immersed boundary,
        /// called by <see cref="IBMQueries.LiftOrDragForce"/>
        /// </summary>
        /// <param name="density"></param>
        /// <param name="momentum"></param>
        /// <param name="energy"></param>
        /// <param name="speciesMap"></param>
        /// <param name="direction">Direction of the force projection, e.g. 0=x-axis, 1=y-axis</param>
        /// <param name="cutCellMask">Cells intersected by the interface</param>
        /// <returns></returns>
        static ScalarFunctionEx GetSurfaceForce(
            DGField density, VectorField <DGField> momentum, DGField energy, ImmersedSpeciesMap speciesMap, int direction, CellMask cutCellMask)
        {
            return(delegate(int j0, int Len, NodeSet nodes, MultidimensionalArray result) {
                int noOfNodes = nodes.GetLength(0);
                int D = nodes.SpatialDimension;

                double Reynolds = speciesMap.Control.ReynoldsNumber;
                double Mach = speciesMap.Control.MachNumber;
                double gamma = speciesMap.Control.EquationOfState.HeatCapacityRatio;

                double MachScaling = gamma * Mach * Mach;


                MultidimensionalArray rho = MultidimensionalArray.Create(Len, noOfNodes);
                density.Evaluate(j0, Len, nodes, rho);

                MultidimensionalArray[] m = new MultidimensionalArray[CompressibleEnvironment.NumberOfDimensions];
                for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
                {
                    m[d] = MultidimensionalArray.Create(Len, noOfNodes);
                    momentum[d].Evaluate(j0, Len, nodes, m[d]);
                }

                MultidimensionalArray rhoE = MultidimensionalArray.Create(Len, noOfNodes);
                energy.Evaluate(j0, Len, nodes, rhoE);

                MultidimensionalArray gradRho = MultidimensionalArray.Create(Len, noOfNodes, D);
                density.EvaluateGradient(j0, Len, nodes, gradRho);

                MultidimensionalArray gradM = MultidimensionalArray.Create(Len, noOfNodes, D, D);
                for (int d = 0; d < D; d++)
                {
                    momentum[d].EvaluateGradient(
                        j0,
                        Len,
                        nodes,
                        gradM.ExtractSubArrayShallow(-1, -1, d, -1),
                        0,
                        0.0);
                }

                MultidimensionalArray normals = speciesMap.Tracker.DataHistories[0].Current.GetLevelSetNormals(nodes, j0, Len);

                Vector mVec = new Vector();
                for (int i = 0; i < Len; i++)
                {
                    for (int j = 0; j < noOfNodes; j++)
                    {
                        for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
                        {
                            mVec[d] = m[d][i, j];
                        }

                        Material material = speciesMap.GetMaterial(double.NaN);
                        StateVector state = new StateVector(material, rho[i, j], mVec, rhoE[i, j]);

                        double mu = 0.0;
                        if (Reynolds != 0.0)
                        {
                            mu = state.GetViscosity(j0 + j) / Reynolds;
                        }

                        double[,] gradU = new double[D, D];
                        for (int d1 = 0; d1 < D; d1++)
                        {
                            for (int d2 = 0; d2 < D; d2++)
                            {
                                // Apply chain rule
                                gradU[d1, d2] = (gradM[i, j, d1, d2] - state.Momentum[d1] / state.Density * gradRho[i, j, d2]) / state.Density;
                            }
                        }
                        double divU = gradU[0, 0] + gradU[1, 1];

                        switch (direction)
                        {
                        // Attention: Changed sign, because normal vector is pointing inwards, not outwards!
                        case 0:                                                                                // x-Direction
                            result[i, j, 0] = -state.Pressure / MachScaling * normals[i, j, 0]
                                              + mu * (2.0 * gradU[0, 0] - 2.0 / 3.0 * divU) * normals[i, j, 0] //tau_11 * n_1
                                              + mu * (gradU[0, 1] + gradU[1, 0]) * normals[i, j, 1];           //tau_12 * n_2
                            break;

                        case 1:                                                                                 // y-Direction
                            result[i, j, 0] = -state.Pressure / MachScaling * normals[i, j, 1]
                                              + mu * (gradU[0, 1] + gradU[1, 0]) * normals[i, j, 0]             //tau_12 * n_1
                                              + mu * (2.0 * gradU[1, 1] - 2.0 / 3.0 * divU) * normals[i, j, 1]; //tau_22*n_2
                            break;

                        default:
                            throw new ArgumentException("Lift and Drag currently only in 2D implemented");
                        }
                    }
                }
            });
        }
コード例 #8
0
        /// <summary>
        /// still a hack...
        /// </summary>
        static object InstantiateFromAttribute(FieldInfo f, InstantiateFromControlFileAttribute at, Type type,
                                               ICollection <DGField> IOFields, ICollection <DGField> RegisteredFields,
                                               //AppControl ctrl,
                                               IDictionary <string, FieldOpts> FieldOptions,
                                               IGridData ctx, LevelSetTracker lstrk)
        {
            // create instance
            // ===============

            object member_value = null;

            Type HistoryType   = null;
            Type VectorType    = null;
            Type ComponentType = null;

            GetTypes(f, out HistoryType, out VectorType, out ComponentType);


            if (VectorType != null)
            {
                // vector field branch
                // +++++++++++++++++++

                if (at.m_IsScalarField)
                {
                    throw new ApplicationException("illegal use of 'InstantiateFromControlFileAttribute' (with Scalar Declaration) on a Vector class");
                }


                int      D     = ctx.SpatialDimension;
                string[] cName = at.GetControlFileNames(f, D);
                string[] iName = at.GetInCodeIdentifications(f, D);


                // determine DG polynomial degree of basis
                int[] Deg = new int[D];
                for (int d = 0; d < D; d++)
                {
                    Deg[d] = GetDegree(cName[d], iName[d], FieldOptions);
                }

                if (at.m_DegreesMustBeEqual)
                {
                    int deg0 = Deg[0];
                    for (int d = 1; d < D; d++)
                    {
                        if (Deg[d] != deg0)
                        {
                            StringWriter errMsg = new StringWriter();
                            errMsg.Write("DG Polynomial degree of fields {");
                            for (int dd = 0; dd < D; dd++)
                            {
                                errMsg.Write(cName[dd]);
                                if (dd < D - 1)
                                {
                                    errMsg.Write(", ");
                                }
                            }
                            errMsg.Write("} must be equal, but found {");
                            for (int dd = 0; dd < D; dd++)
                            {
                                errMsg.Write(Deg[dd]);
                                if (dd < D - 1)
                                {
                                    errMsg.Write(", ");
                                }
                            }
                            errMsg.Write("} in control file.");


                            throw new ApplicationException(errMsg.ToString());
                        }
                    }
                }

                // create instance: components
                SinglePhaseField[] fld  = new SinglePhaseField[D];
                XDGField[]         xfld = new XDGField[D];
                DGField[]          _fld = new DGField[D];
                for (int d = 0; d < D; d++)
                {
                    if (ComponentType == typeof(SinglePhaseField))
                    {
                        fld[d]  = new SinglePhaseField(new Basis(ctx, Deg[d]), iName[d]);
                        _fld[d] = fld[d];
                    }
                    else if (ComponentType == typeof(XDGField))
                    {
                        xfld[d] = new XDGField(new XDGBasis(lstrk, Deg[d]), iName[d]);
                        _fld[d] = xfld[d];
                        fld     = null;
                    }
                    else
                    {
                        throw new NotSupportedException("unknown type.");
                    }
                    RegisteredFields.Add(_fld[d]);
                }

                // create instance: Vector-Field container
                var ci = VectorType.GetConstructor(new Type[] { ComponentType.MakeArrayType() });
                member_value = ci.Invoke(new object[] { (fld != null) ? ((object)fld) : ((object)xfld) });
                //member_value = ci.Invoke( new object[] { ((object)fld)  });

                // io
                for (int d = 0; d < D; d++)
                {
                    AddToIO(iName[d], _fld[d], FieldOptions, IOFields, at);
                }
            }
            else
            {
                // scalar field branch
                // +++++++++++++++++++

                if (at.m_IsVectorField)
                {
                    throw new ApplicationException("illegal use of 'InstantiateFromControlFileAttribute' (with Vector Declaration) on a Non-Vector class");
                }

                // identification
                string cName = at.GetControlFileName(f);
                string iName = at.GetInCodeIdentification(f);

                // create basis
                int   Deg = GetDegree(cName, iName, FieldOptions);
                Basis b   = new Basis(ctx, Deg);

                // create instance
                DGField fld = null;
                if (ComponentType == typeof(SinglePhaseField))
                {
                    fld = new SinglePhaseField(b, iName);
                }
                else if (ComponentType == typeof(LevelSet))
                {
                    fld = new LevelSet(b, iName);
                }
                else if (ComponentType == typeof(XDGField))
                {
                    fld = new XDGField(new XDGBasis(lstrk, Deg), iName);
                }
                else
                {
                    throw new NotImplementedException();
                }

                RegisteredFields.Add(fld);
                AddToIO(iName, fld, FieldOptions, IOFields, at);

                member_value = fld;
            }

            // History, if desired
            if (HistoryType != null)
            {
                member_value = (HistoryType.GetConstructors()[0]).Invoke(new object[] { member_value });
            }

            return(member_value);
        }
コード例 #9
0
        static double JumpNorm(DGField f, CellMask mask = null)
        {
            GridData grd      = (GridData)f.GridDat;
            int      D        = grd.SpatialDimension;
            var      e2cTrafo = grd.Edges.Edge2CellTrafos;

            if (mask == null)
            {
                mask = CellMask.GetFullMask(grd);
            }
            SubGrid  maskSG  = new SubGrid(mask);
            EdgeMask innerEM = maskSG.InnerEdgesMask;

            f.MPIExchange();

            double Unorm = 0;

            EdgeQuadrature.GetQuadrature(
                new int[] { D + 1 }, grd,
                (new EdgeQuadratureScheme(true, innerEM)).Compile(grd, f.Basis.Degree * 2),
                delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {  // Evaluate
                NodeSet NS = QR.Nodes;
                EvalResult.Clear();
                int NoOfNodes = NS.NoOfNodes;
                for (int j = 0; j < Length; j++)
                {
                    int iEdge    = j + i0;
                    int jCell_IN = grd.Edges.CellIndices[iEdge, 0];
                    int jCell_OT = grd.Edges.CellIndices[iEdge, 1];
                    var uDiff    = EvalResult.ExtractSubArrayShallow(new int[] { j, 0, 0 }, new int[] { j, NoOfNodes - 1, -1 });

                    if (jCell_OT >= 0)
                    {
                        int iTrafo_IN = grd.Edges.Edge2CellTrafoIndex[iEdge, 0];
                        int iTrafo_OT = grd.Edges.Edge2CellTrafoIndex[iEdge, 1];

                        MultidimensionalArray uIN = MultidimensionalArray.Create(1, NoOfNodes);
                        MultidimensionalArray uOT = MultidimensionalArray.Create(1, NoOfNodes);

                        NodeSet NS_IN = NS.GetVolumeNodeSet(grd, iTrafo_IN);
                        NodeSet NS_OT = NS.GetVolumeNodeSet(grd, iTrafo_OT);

                        f.Evaluate(jCell_IN, 1, NS_IN, uIN);
                        f.Evaluate(jCell_OT, 1, NS_OT, uOT);

                        uDiff.Acc(+1.0, uIN);
                        uDiff.Acc(-1.0, uOT);

                        //Console.WriteLine("Diff at edge {0} between cell {1} and cell {2}: {3}", iEdge, jCell_IN, jCell_OT, uDiff.L2Norm());
                    }
                    else
                    {
                        uDiff.Clear();
                    }
                }

                EvalResult.ApplyAll(x => x * x);
            },
                delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {  // SaveIntegrationResults
                Unorm += ResultsOfIntegration.Sum();
            }).Execute();

            Unorm = Unorm.MPISum();

            return(Unorm.Sqrt());
        }
コード例 #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="jCell">
        /// Local index of cell which should be recalculated.
        /// </param>
        /// <param name="AcceptedMask">
        /// Bitmask which marks accepted cells - if any neighbor of
        /// <paramref name="jCell"/> is _accepted_, this defines a Dirichlet
        /// boundary; otherwise, the respective cell face is a free boundary.
        /// </param>
        /// <param name="Phi">
        /// Input and output:
        /// - input for _accepted_ cells, i.e. Dirichlet boundary values
        /// - input and output for <paramref name="jCell"/>: an initial value for the iterative procedure, resp. on exit the result of the iteration.
        /// </param>
        /// <param name="gradPhi">
        /// Auxillary variable to store the gradient of the level-set-field.
        /// </param>
        /// <returns></returns>
        public bool LocalSolve(int jCell, BitArray AcceptedMask, SinglePhaseField Phi, VectorField <SinglePhaseField> gradPhi)
        {
            Stpw_tot.Start();

            int    N           = this.LevelSetBasis.GetLength(jCell);
            int    i0G         = this.LevelSetMapping.GlobalUniqueCoordinateIndex(0, jCell, 0);
            int    i0L         = this.LevelSetMapping.LocalUniqueCoordinateIndex(0, jCell, 0);
            double penaltyBase = ((double)(this.LevelSetBasis.Degree + 2)).Pow2();
            double CellVolume  = this.GridDat.Cells.GetCellVolume(jCell);
            int    p           = Phi.Basis.Degree;

            // subgrid on which we are working, consisting only of one cell
            SubGrid jCellGrid = new SubGrid(new CellMask(this.GridDat, Chunk.GetSingleElementChunk(jCell)));
            var     VolScheme = new CellQuadratureScheme(domain: jCellGrid.VolumeMask);
            var     EdgScheme = new EdgeQuadratureScheme(domain: jCellGrid.AllEdgesMask);
            var     VolRule   = VolScheme.SaveCompile(GridDat, 3 * p);
            var     EdgRule   = EdgScheme.SaveCompile(GridDat, 3 * p);

            // parameter list for operator
            DGField[] Params = new DGField[] { Phi };
            gradPhi.ForEach(f => f.AddToArray(ref Params));

            // build operator
            var comp = new EllipticReinitForm(AcceptedMask, jCell, penaltyBase, this.GridDat.Cells.cj);

            comp.LhsSwitch = 1.0;  // matrix is constant -- Lhs Matrix only needs to be computed once
            comp.RhsSwitch = -1.0; //                   Rhs must be updated in every iteration
            var op = comp.Operator();


            // iteration loop:
            MultidimensionalArray Mtx = MultidimensionalArray.Create(N, N);

            double[] Rhs        = new double[N];
            double   ChangeNorm = 0;
            int      iIter;

            for (iIter = 0; iIter < 100; iIter++)
            {
                // update gradient
                gradPhi.Clear(jCellGrid.VolumeMask);
                gradPhi.Gradient(1.0, Phi, jCellGrid.VolumeMask);

                // assemble matrix and rhs
                {
                    // clear
                    for (int n = 0; n < N; n++)
                    {
                        if (iIter == 0)
                        {
                            m_LaplaceMatrix.ClearRow(i0G + n);
                        }
                        this.m_LaplaceAffine[i0L + n] = 0;
                    }

                    // compute matrix (only in iteration 0) and rhs
                    if (iIter == 0)
                    {
                        Stpw_Mtx.Start();
                    }
                    Stpw_Rhs.Start();
                    op.ComputeMatrixEx(this.LevelSetMapping, Params, this.LevelSetMapping,
                                       iIter == 0 ? this.m_LaplaceMatrix : null, this.m_LaplaceAffine,
                                       OnlyAffine: iIter > 0,
                                       //volQrCtx: VolScheme, edgeQrCtx: EdgScheme,
                                       volRule: VolRule, edgeRule: EdgRule,
                                       ParameterMPIExchange: false);
                    //op.Internal_ComputeMatrixEx(this.GridDat,
                    //    this.LevelSetMapping, Params, this.LevelSetMapping,
                    //    iIter == 0 ? this.m_LaplaceMatrix : default(MsrMatrix), this.m_LaplaceAffine, iIter > 0,
                    //    0.0,
                    //    EdgRule, VolRule,
                    //    null, false);


                    if (iIter == 0)
                    {
                        Stpw_Mtx.Stop();
                    }
                    Stpw_Rhs.Stop();

                    // extract matrix for 'jCell'
                    for (int n = 0; n < N; n++)
                    {
#if DEBUG
                        int      Lr;
                        int[]    row_cols = null;
                        double[] row_vals = null;
                        Lr = this.m_LaplaceMatrix.GetRow(i0G + n, ref row_cols, ref row_vals);
                        for (int lr = 0; lr < Lr; lr++)
                        {
                            int    ColIndex = row_cols[lr];
                            double Value    = row_vals[lr];
                            Debug.Assert((ColIndex >= i0G && ColIndex < i0G + N) || (Value == 0.0), "Matrix is expected to be block-diagonal.");
                        }
#endif
                        if (iIter == 0)
                        {
                            for (int m = 0; m < N; m++)
                            {
                                Mtx[n, m] = this.m_LaplaceMatrix[i0G + n, i0G + m];
                            }
                        }
                        else
                        {
#if DEBUG
                            for (int m = 0; m < N; m++)
                            {
                                Debug.Assert(Mtx[n, m] == this.m_LaplaceMatrix[i0G + n, i0G + m]);
                            }
#endif
                        }
                        Rhs[n] = -this.m_LaplaceAffine[i0L + n];
                    }
                }

                // solve
                double[] sol = new double[N];
                Mtx.Solve(sol, Rhs);
                ChangeNorm = GenericBlas.L2Dist(sol, Phi.Coordinates.GetRow(jCell));
                Phi.Coordinates.SetRow(jCell, sol);

                if (ChangeNorm / CellVolume < 1.0e-10)
                {
                    break;
                }
            }


            //Console.WriteLine("Final change norm: {0}, \t iter: {1}", ChangeNorm, iIter );

            if (ChangeNorm > 1.0e-6)
            {
                Console.WriteLine("  local solver funky in cell: " + jCell + ", last iteration change norm = " + ChangeNorm);
            }


            Stpw_tot.Stop();
            return(true);
        }
コード例 #11
0
ファイル: CNSQueries.cs プロジェクト: rohitvuppala/BoSSS
        /// <summary>
        /// Calculates the lift and drag force on given edges, e.g edges around an airfoil.
        /// Currently only in 2D!!!
        /// </summary>
        /// <param name="edgeTagName">EdgeTag on which the drag force will be calculated</param>
        /// <returns>total drag force</returns>
        /// <remarks>It assumes that pressure and velocity fields exists</remarks>
        public static Query LiftAndDragForce(String edgeTagName)
        {
            return(delegate(IApplication <AppControl> app, double time) {
                if (dragIntegral == null)
                {
                    densityField = app.IOFields.SingleOrDefault((f) => f.Identification == "rho");
                    m0Field = app.IOFields.SingleOrDefault((f) => f.Identification == "m0");
                    m1Field = app.IOFields.SingleOrDefault((f) => f.Identification == "m1");
                    energyField = app.IOFields.SingleOrDefault((f) => f.Identification == "rhoE");

                    DrhoDx = new SinglePhaseField(densityField.Basis);
                    DrhoDy = new SinglePhaseField(densityField.Basis);

                    Dm0Dx = new SinglePhaseField(m0Field.Basis);
                    Dm0Dy = new SinglePhaseField(m0Field.Basis);
                    Dm1Dx = new SinglePhaseField(m1Field.Basis);
                    Dm1Dy = new SinglePhaseField(m1Field.Basis);

                    CNSControl c = app.Control as CNSControl;
                    Program prog = app as Program;

                    byte edgeTag = app.Grid.EdgeTagNames.First(item => item.Value.Equals(edgeTagName)).Key;

                    CoordinateMapping mapping = new CoordinateMapping(
                        densityField, m0Field, m1Field, energyField, DrhoDx, DrhoDy, Dm0Dx, Dm0Dy, Dm1Dx, Dm1Dy);

                    dragIntegral = new EdgeIntegral((BoSSS.Foundation.Grid.Classic.GridData)(app.GridData), edgeTag, new ForceFlux(
                                                        c.ReynoldsNumber, prog.SpeciesMap.GetMaterial(double.NaN), 0), mapping);
                    liftIntegral = new EdgeIntegral((BoSSS.Foundation.Grid.Classic.GridData)(app.GridData), edgeTag, new ForceFlux(
                                                        c.ReynoldsNumber, prog.SpeciesMap.GetMaterial(double.NaN), 1), mapping);

                    if (logger == null && app.CurrentSessionInfo.ID != Guid.Empty && app.MPIRank == 0)
                    {
                        logger = app.DatabaseDriver.FsDriver.GetNewLog("LiftAndDragForce", app.CurrentSessionInfo.ID);
                        string header = "PhysTime\t LiftForce\t DragForce";
                        logger.WriteLine(header);
                    }
                }

                DrhoDx.Clear();
                DrhoDy.Clear();

                DrhoDx.Derivative(1.0, densityField, 0);
                DrhoDy.Derivative(1.0, densityField, 1);

                Dm0Dx.Clear();
                Dm0Dy.Clear();
                Dm1Dx.Clear();
                Dm1Dy.Clear();

                Dm0Dx.Derivative(1.0, m0Field, 0);
                Dm0Dy.Derivative(1.0, m0Field, 1);
                Dm1Dx.Derivative(1.0, m1Field, 0);
                Dm1Dy.Derivative(1.0, m1Field, 1);

                double lift = liftIntegral.Evaluate();
                double drag = dragIntegral.Evaluate();

                if (logger != null && app.MPIRank == 0)
                {
                    string line = time + "\t" + lift + "\t" + drag;
                    logger.WriteLine(line);
                    logger.Flush();
                }
                return drag;
            });
        }
コード例 #12
0
        /// <summary>
        /// Computes L2 norms between DG fields on different grid resolutions, i.e. for a
        /// convergence study, where the solution on the finest grid is assumed to be exact.
        /// </summary>
        /// <param name="FieldsToCompare">
        /// Identification (<see cref="DGField.Identification"/>) of the fields which should be compared.
        /// </param>
        /// <param name="timestepS">
        /// A collection of solutions on different grid resolutions.
        /// </param>
        /// <param name="GridRes">
        /// On exit, the resolution of the different grids.
        /// </param>
        /// <param name="L2Errors">
        /// On exit, the L2 error
        /// (for each field specified in <paramref name="FieldsToCompare"/>)
        /// in comparison to the solution on the finest grid.
        /// </param>
        /// <param name="timestepIds">
        /// on exit, the timestep id which correlate with the resolutions <paramref name="GridRes"/>
        /// (remarks: <paramref name="timestepIds"/> may be re-sorted internally according to grid resolution).
        /// </param>
        public static void ComputeErrors(IEnumerable <string> FieldsToCompare, IEnumerable <ITimestepInfo> timestepS,
                                         out double[] GridRes, out Dictionary <string, double[]> L2Errors, out Guid[] timestepIds)
        {
            // load the DG-Fields
            List <IEnumerable <DGField> > fields = new List <IEnumerable <DGField> >();
            int i = 1;

            foreach (var timestep in timestepS)
            {
                Console.WriteLine("Loading timestep {0} of {1}, ({2})...", i, timestepS.Count(), timestep.ID);
                fields.Add(timestep.Fields);
                i++;
                Console.WriteLine("done (Grid has {0} cells).", fields.Last().First().GridDat.CellPartitioning.TotalLength);
            }


            // sort according to grid resolution
            {
                var s = fields.OrderBy(f => f.First().GridDat.CellPartitioning.TotalLength).ToArray();
                timestepIds = new Guid[s.Length];
                for (int z = 0; z < timestepIds.Length; z++)
                {
                    int idx = fields.IndexOf(s[z], (f1, f2) => object.ReferenceEquals(f1, f2));
                    timestepIds[z] = timestepS.ElementAt(idx).ID;
                }

                fields.Clear();
                fields.AddRange(s);
            }


            // Grids and coarse-to-fine -- mappings.
            GridData[] gDataS = fields.Select(fc => (GridData)(fc.First().GridDat)).ToArray();

            int[][] Fine2CoarseMapS = new int[gDataS.Length - 1][];
            for (int iLevel = 0; iLevel < Fine2CoarseMapS.Length; iLevel++)
            {
                ComputeFine2CoarseMap(gDataS.Last(), gDataS[iLevel], out Fine2CoarseMapS[iLevel]);
            }

            // extrapolate to fine grid
            Dictionary <string, List <DGField> > injectedFields = new Dictionary <string, List <DGField> >();

            foreach (string Identification in FieldsToCompare)
            {
                List <DGField> blabla = new List <DGField>();

                DGField finestSolution = fields.Last().Single(f => f.Identification == Identification);

                for (int iLevel = 0; iLevel < gDataS.Length - 1; iLevel++)
                {
                    Console.WriteLine("Injecting '{0}' from level {1} to finest grid...", Identification, iLevel);

                    DGField coarseSolution = fields[iLevel].Single(f => f.Identification == Identification);

                    if (finestSolution.GetType() != coarseSolution.GetType())
                    {
                        throw new NotSupportedException();
                    }
                    if (coarseSolution.Basis.Degree != finestSolution.Basis.Degree)
                    {
                        throw new NotSupportedException();
                    }

                    if (finestSolution is XDGField)
                    {
                        XDGField _coarseSolution  = (XDGField)coarseSolution;
                        XDGField _finestSolution  = (XDGField)finestSolution;
                        XDGField injectedSolution = new XDGField(_finestSolution.Basis, Identification + "-inj-" + iLevel);

                        InjectXDGField(Fine2CoarseMapS[iLevel], injectedSolution, _coarseSolution);

                        blabla.Add(injectedSolution);
                    }
                    else if (finestSolution is SinglePhaseField)
                    {
                        SinglePhaseField _coarseSolution  = (SinglePhaseField)coarseSolution;
                        SinglePhaseField _finestSolution  = (SinglePhaseField)finestSolution;
                        SinglePhaseField injectedSolution = new SinglePhaseField(_finestSolution.Basis, Identification + "-inj-" + iLevel);

                        InjectDGField(Fine2CoarseMapS[iLevel], injectedSolution, _coarseSolution);

                        blabla.Add(injectedSolution);
                    }
                    else
                    {
                        throw new NotSupportedException("DG field type '" + finestSolution.GetType().FullName + "' not supported, Identification is '" + finestSolution.Identification + "'");
                    }

                    Console.WriteLine("done.");
                }

                blabla.Add(finestSolution);
                injectedFields.Add(Identification, blabla);
            }

            // compute the errors
            L2Errors = new Dictionary <string, double[]>();
            foreach (string Identification in FieldsToCompare)
            {
                double[] L2Error = new double[gDataS.Length - 1];

                for (int iLevel = 0; iLevel < gDataS.Length - 1; iLevel++)
                {
                    Console.WriteLine("Computing L2 error of '{0}' on level {1} ...", Identification, iLevel);

                    DGField Error  = injectedFields[Identification].Last().CloneAs();
                    DGField injSol = injectedFields[Identification].ElementAt(iLevel);
                    Error.Acc(-1.0, injSol);

                    L2Error[iLevel] = Error.L2Norm();

                    Console.WriteLine("done (Error is {0:0.####E-00}).", L2Error[iLevel]);
                }

                L2Errors.Add(Identification, L2Error);
            }

            GridRes = gDataS.Take(gDataS.Length - 1).Select(gd => gd.Cells.h_minGlobal).ToArray();
        }
コード例 #13
0
        /// <summary>
        /// assigns the cell index of the aggregated cell <em>j</em> to all (fine) grid cells that
        /// the aggregated cell <em>j</em> consists of.
        /// </summary>
        static public void ColorDGField(this AggregationGridData ag, DGField f)
        {
            IGridData Anc = f.GridDat;

            if (!IsAnc(Anc, ag))
            {
                throw new ArgumentException("Field 'f' must be defined on an ancestor grid of 'ag'.");
            }


            f.Clear();
            int Jag  = ag.iLogicalCells.NoOfLocalUpdatedCells;
            int Janc = Anc.iLogicalCells.NoOfLocalUpdatedCells;

            Debug.Assert(Anc.iGeomCells.Count == ag.iGeomCells.Count);

            int[] jG2jL = Anc.iGeomCells.GeomCell2LogicalCell;

            int[]    Colors = new int[Jag];
            BitArray Marked = new BitArray(Janc);

            for (int j = 0; j < Jag; j++)   // loop over logical/aggregate cells

            // determine colors of neighbor cells
            {
                int[] Neighs      = ag.iLogicalCells.CellNeighbours[j];
                var   NeighColors = Neighs.Select(jN => Colors[jN]);

                // select color for cell 'j'
                int iCol = 1;
                for (iCol = 1; iCol < 2 * Jag; iCol++)
                {
                    if (!NeighColors.Contains(iCol))
                    {
                        break;
                    }
                }
                Colors[j] = iCol;

                // color all logical cells in ancestor grid
                // idea: convert to geometrical and back to logical
                //    in this way we can e.g. skip multiple grid levels
                foreach (int jGeom in ag.iLogicalCells.AggregateCellToParts[j])
                {
                    int jLogAnc;
                    if (jG2jL != null)
                    {
                        jLogAnc = jG2jL[jGeom];
                    }
                    else
                    {
                        jLogAnc = jGeom;
                    }
                    if (!Marked[jLogAnc])
                    {
                        f.SetMeanValue(jLogAnc, iCol);
                        Marked[jLogAnc] = true;
                    }
                    else
                    {
                        // nop
                    }
                }
            }
        }
コード例 #14
0
        /// <summary>
        /// Computes the maximum admissible step-size according to
        /// GassnerEtAl2008, equation 67.
        /// </summary>
        /// <param name="i0"></param>
        /// <param name="Length"></param>
        /// <returns></returns>
        protected override double GetCFLStepSize(int i0, int Length)
        {
            BoSSS.Foundation.Grid.Classic.GridData __gridData = (BoSSS.Foundation.Grid.Classic.GridData)(this.gridData);

            int    iKref                = __gridData.Cells.GetRefElementIndex(i0);
            int    noOfNodesPerCell     = base.EvaluationPoints[iKref].NoOfNodes;
            double scaling              = Math.Max(4.0 / 3.0, config.EquationOfState.HeatCapacityRatio / config.PrandtlNumber);
            MultidimensionalArray hmin  = __gridData.Cells.h_min;
            DGField artificialViscosity = workingSet.ParameterFields.Where(c => c.Identification.Equals(Variables.ArtificialViscosity)).Single();
            double  cfl = double.MaxValue;

            switch (speciesMap)
            {
            case ImmersedSpeciesMap ibmMap: {
                MultidimensionalArray levelSetValues = ibmMap.Tracker.DataHistories[0].Current.GetLevSetValues(base.EvaluationPoints[iKref], i0, Length);
                SpeciesId             species        = ibmMap.Tracker.GetSpeciesId(ibmMap.Control.FluidSpeciesName);
                MultidimensionalArray hminCut        = ibmMap.CellAgglomeration.CellLengthScales[species];

                //ibmMap.Agglomerator.AggInfo.SourceCells

                // cutCellsThatAreNotSourceCells =
                //    ibmMap.Tracker.Regions.GetCutCellMask().Except(ibmMap.Agglomerator.AggInfo.SourceCells);

                for (int i = 0; i < Length; i++)           // loop over cells...
                {
                    int cell = i0 + i;

                    double hminLocal = double.NaN;
                    if (ibmMap.cutCellsThatAreNotSourceCells[cell])
                    {
                        hminLocal = hminCut[cell];
                    }
                    else
                    {
                        hminLocal = hmin[cell];
                    }
                    Debug.Assert(double.IsNaN(hminLocal) == false, "Hmin is NaN");
                    Debug.Assert(double.IsInfinity(hminLocal) == false, "Hmin is Inf");

                    double nu = artificialViscosity.GetMeanValue(cell) / config.ReynoldsNumber;
                    Debug.Assert(!double.IsNaN(nu), "IBM ArtificialViscosityCFLConstraint: nu is NaN");

                    bool setCFL = false;
                    for (int node = 0; node < noOfNodesPerCell; node++)
                    {
                        if (levelSetValues[i, node].Sign() != (double)ibmMap.Control.FluidSpeciesSign)
                        {
                            continue;
                        }
                        else if (setCFL == false)
                        {
                            setCFL = true;
                        }
                    }

                    if (nu != 0 && setCFL)
                    {
                        double cflhere = hminLocal * hminLocal / scaling / nu;
                        Debug.Assert(!double.IsNaN(cflhere), "Could not determine CFL number");

                        cfl = Math.Min(cfl, cflhere);
                    }
                }
            }
            break;

            default: {
                for (int i = 0; i < Length; i++)
                {
                    int    cell      = i0 + i;
                    double hminLocal = hmin[cell];
                    Debug.Assert(double.IsNaN(hminLocal) == false, "Hmin is NaN");
                    Debug.Assert(double.IsInfinity(hminLocal) == false, "Hmin is Inf");

                    double nu = artificialViscosity.GetMeanValue(cell) / config.ReynoldsNumber;
                    Debug.Assert(!double.IsNaN(nu), "ArtificialViscosityCFLConstraint: nu is NaN");

                    if (nu != 0)
                    {
                        double cflhere = hminLocal * hminLocal / scaling / nu;
                        Debug.Assert(!double.IsNaN(cflhere), "Could not determine CFL number");

                        cfl = Math.Min(cfl, cflhere);
                    }
                }
            }
            break;
            }

            if (cfl == double.MaxValue)
            {
                return(cfl);
            }
            else
            {
                int degree      = workingSet.ConservativeVariables.Max(f => f.Basis.Degree);
                int twoNPlusOne = 2 * degree + 1;
                return(cfl * GetBetaMax(degree) / twoNPlusOne / twoNPlusOne / Math.Sqrt(CNSEnvironment.NumberOfDimensions));
            }
        }
コード例 #15
0
 /// <summary>
 /// L2Error w.r.t. a function <paramref name="f"/> of a DG-Field
 /// </summary>
 public static double L2Error(this DGField u, Func <double[], double> f)
 {
     return(u.L2Error(f.Vectorize()));
 }
コード例 #16
0
        public void UpdateSensorValues(IEnumerable <DGField> fieldSet, ISpeciesMap speciesMap, CellMask cellMask)
        {
            using (new FuncTrace()) {
                DGField fieldToTest = fieldSet.
                                      Where(f => f.Identification == m_sensorVariableName).
                                      Single();
                int degree    = fieldToTest.Basis.Degree;
                int noOfCells = fieldToTest.GridDat.iLogicalCells.NoOfLocalUpdatedCells;

                if (sensorValues == null || sensorValues.Length != noOfCells)
                {
                    sensorValues = new double[noOfCells];
                }

                IMatrix coordinatesTimesMassMatrix;
                IMatrix coordinatesTruncatedTimesMassMatrix;

                if (speciesMap is ImmersedSpeciesMap ibmMap)
                {
                    // Note: This has to be the _non_-agglomerated mass matrix
                    // because we still live on the non-agglomerated mesh at this point
                    BlockMsrMatrix massMatrix = ibmMap.GetMassMatrixFactory(fieldToTest.Mapping).NonAgglomeratedMassMatrix;

                    // Old
                    DGField temp = fieldToTest.CloneAs();
                    massMatrix.SpMV(1.0, fieldToTest.CoordinateVector, 0.0, temp.CoordinateVector);
                    coordinatesTimesMassMatrix = temp.Coordinates;

                    // Neu
                    DGField uTruncated = fieldToTest.CloneAs();

                    // Set all coordinates to zero
                    for (int cell = 0; cell < uTruncated.Coordinates.NoOfRows; cell++)
                    {
                        for (int coordinate = 0; coordinate < uTruncated.Coordinates.NoOfCols; coordinate++)
                        {
                            uTruncated.Coordinates[cell, coordinate] = 0;
                        }
                    }

                    // Copy only the coordiantes that belong to the highest modes
                    foreach (int cell in cellMask.ItemEnum)
                    {
                        foreach (int coordinate in fieldToTest.Basis.GetPolynomialIndicesForDegree(cell, degree))
                        {
                            uTruncated.Coordinates[cell, coordinate] = fieldToTest.Coordinates[cell, coordinate];
                        }
                    }

                    // Calculate M times u
                    DGField vecF_Field = fieldToTest.CloneAs();
                    massMatrix.SpMV(1.0, uTruncated.CoordinateVector, 0.0, vecF_Field.CoordinateVector);
                    coordinatesTruncatedTimesMassMatrix = vecF_Field.Coordinates;
                }
                else
                {
                    // Mass matrix is identity
                    coordinatesTimesMassMatrix          = fieldToTest.Coordinates;
                    coordinatesTruncatedTimesMassMatrix = fieldToTest.Coordinates;
                }
                //IMatrix coordinatesTimesMassMatrix = fieldToTest.Coordinates;

                //cellMask.SaveToTextFile("fluidCells.txt");

                // This is equivalent to norm(restrictedField) / norm(originalField)
                // Note: THIS WILL FAIL IN TRUE XDG CUT CELLS WITH TWO SPECIES
                foreach (int cell in cellMask.ItemEnum)
                {
                    double numerator = 0.0;
                    foreach (int coordinate in fieldToTest.Basis.GetPolynomialIndicesForDegree(cell, degree))
                    {
                        //numerator += fieldToTest.Coordinates[cell, coordinate] * fieldToTest.Coordinates[cell, coordinate];
                        numerator += fieldToTest.Coordinates[cell, coordinate] * coordinatesTruncatedTimesMassMatrix[cell, coordinate];
                    }

                    double denominator = 0.0;
                    for (int coordinate = 0; coordinate < fieldToTest.Basis.Length; coordinate++)
                    {
                        //denominator += fieldToTest.Coordinates[cell, coordinate] * fieldToTest.Coordinates[cell, coordinate];
                        denominator += fieldToTest.Coordinates[cell, coordinate] * coordinatesTimesMassMatrix[cell, coordinate];
                    }

                    double result;
                    if (denominator == 0.0)
                    {
                        result = 0.0;
                    }
                    else
                    {
                        result = numerator / denominator;
                    }

                    //Debug.Assert(denominator != 0, "Persson sensor: Denominator is zero!");
                    //Debug.Assert(!(numerator / denominator).IsNaN(), "Persson sensor: Sensor value is NaN!");
                    //Debug.Assert(numerator / denominator >= 0, "Persson sensor: Sensor value is negative!");

                    sensorValues[cell] = result;
                }
            }
        }
コード例 #17
0
        public void LimitFieldValues(IEnumerable <DGField> ConservativeVariables, IEnumerable <DGField> DerivedFields)
        {
            var GridData = ConservativeVariables.First().GridDat;

            // Make sure primitive fields are up-to-date
            for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
            {
                CNSVariables.Velocity[d].UpdateFunction(
                    DerivedFields.Single(f => f.Identification == CNSVariables.Velocity[d].Name),
                    CellMask.GetFullMask(GridData),
                    program);
            }
            CNSVariables.Pressure.UpdateFunction(
                DerivedFields.Single(f => f.Identification == CNSVariables.Pressure.Name),
                CellMask.GetFullMask(GridData),
                program);

            // Limit and store primitive fields
            string[]  primitiveFieldNames = { CompressibleVariables.Density, CNSVariables.Velocity.xComponent, CNSVariables.Velocity.yComponent, CNSVariables.Pressure };
            DGField[] primitiveFields     = new DGField[primitiveFieldNames.Length];
            CellMask  shockedCells        = Sensor.GetShockedCellMask(GridData, sensorLimit, cellSize, dgDegree);
            int       k = 0;

            foreach (string name in primitiveFieldNames)
            {
                DGField field = ConservativeVariables.
                                Concat(DerivedFields).
                                Where(f => f.Identification.Equals(name)).
                                Single();

                foreach (Chunk chunk in shockedCells)
                {
                    foreach (int cell in chunk.Elements)
                    {
                        for (int j = 1; j < field.Coordinates.NoOfCols; j++)
                        {
                            field.Coordinates[cell, j] = 0.0;
                        }
                    }
                }

                primitiveFields[k] = field;
                k++;
            }

            // Update conservative variables by using limited primitive variables only in shocked cells
            int D = CompressibleEnvironment.NumberOfDimensions;

            for (int d = 0; d < D; d++)
            {
                DGField mom_d = ConservativeVariables.Single(f => f.Identification == CompressibleVariables.Momentum[d].Name);
                mom_d.Clear(shockedCells);
                mom_d.ProjectFunction(
                    1.0,
                    (X, U, j) => U[0] * U[1 + d],
                    new CellQuadratureScheme(true, shockedCells),
                    primitiveFields);
            }

            // Update total energy
            DGField Energy = ConservativeVariables.Single(f => f.Identification == CompressibleVariables.Energy.Name);

            Energy.Clear(shockedCells);
            Energy.ProjectFunction(
                1.0,
                delegate(double[] X, double[] U, int jCell) {
                double K = 0.0;
                for (int d = 0; d < D; d++)
                {
                    K += U[d + 1] * U[d + 1];
                }
                return(U[D + 1] / (program.Control.EquationOfState.HeatCapacityRatio - 1.0) + 0.5 * U[0] * K);
            },
                new CellQuadratureScheme(true, shockedCells),
                primitiveFields);
        }
コード例 #18
0
        /// <summary>
        /// Starts the export.
        /// </summary>
        public override string YouMust()
        {
            Console.Write("Starting export process... ");
            //// BoSSS.PlotGenerator currently does not support plots without a
            //// session...
            //FieldStateConfiguration fsConfig = new FieldStateConfiguration();
            //fsConfig.BasePaths = new string[] { Grid.Database.Path };
            //fsConfig.SessionGuid = Guid.Empty;
            //fsConfig.FieldNames = new List<string>();
            //fsConfig.TimeSteps = new List<TimestepNumber>();
            //fsConfig.SuperSampling = SuperSampling;
            //fsConfig.ReconstructionType = FieldStateConfiguration.ReconstructionTypes.None;
            //fsConfig.GhostLevel = GhostLevels;
            //fsConfig.NumberOfProcesses = NumberOfProcesses;
            //fsConfig.ExportFormat = ExportFormat;

            //string sRootpath = Utils.GetExportOutputPath();
            //string plotDirPath = Path.Combine(
            //    sRootpath, "grids", Grid.ID.ToString());

            //Perform(fsConfig, plotDirPath);

            //
            // Temporary hack
            //

            string plotDirPath = AlternativeDirectoryName;

            if (AlternativeDirectoryName == null)
            {
                plotDirPath = Path.Combine(
                    Utils.GetExportOutputPath(),
                    "grids",
                    Grid.ID.ToString());
            }

            // create the subdirectory if necessary
            if (!Directory.Exists(plotDirPath))
            {
                Directory.CreateDirectory(plotDirPath);
            }


            // Calculate sum of edge tags for each cell (for bc debugging)
            int[] tagSum = new int[GridDat.Cells.NoOfLocalUpdatedCells];
            for (int e = 0; e < GridDat.Edges.Count; e++)
            {
                byte tag = GridDat.Edges.EdgeTags[e];
                if (tag != 0)
                {
                    Debug.Assert(GridDat.Edges.CellIndices[e, 1] < 0);

                    int cell = GridDat.Edges.CellIndices[e, 0];
                    if (cell < GridDat.Cells.NoOfLocalUpdatedCells)
                    {
                        tagSum[cell] += tag;
                    }
                }
            }

            DGField tagSumField = new SinglePhaseField(new Basis(GridDat, 0), "edgeTagSum");

            for (int i = 0; i < tagSum.Length; i++)
            {
                tagSumField.SetMeanValue(i, tagSum[i]);
            }

            DGField[] partitioningFields = new DGField[GridDat.Grid.PredefinedGridPartitioning.Count];
            int       fieldIndex         = 0;

            foreach (var namePartitioningPair in GridDat.Grid.PredefinedGridPartitioning)
            {
                Partitioning currentPartitioning = GridDat.Grid.CellPartitioning;
                var          cellToRankMap       = dbDriver.LoadVector <int>(namePartitioningPair.Value.Guid, ref currentPartitioning);

                DGField partitioningField = new SinglePhaseField(
                    new Basis(GridDat, 0),
                    "partitioning_" + namePartitioningPair.Key);

                for (int i = 0; i < cellToRankMap.Count(); i++)
                {
                    partitioningField.SetMeanValue(i, cellToRankMap[i]);
                }

                partitioningFields[fieldIndex] = partitioningField;
                fieldIndex++;
            }

            Tecplot.PlotFields(
                partitioningFields.Concat(tagSumField).ToArray(),
                Path.Combine(plotDirPath, "grid"),
                0.0,
                SuperSampling);

            Console.WriteLine(" Data will be written to the following directory:");
            return(plotDirPath);
        }
コード例 #19
0
        /// <summary>
        /// L2 error of some quantity derived from the state vector (e.g.,
        /// entropy) with respect to given reference solution. The quadrature
        /// is determined from the settings in <see cref="IBMControl"/>
        /// </summary>
        /// <param name="quantityOfInterest"></param>
        /// <param name="referenceSolution"></param>
        /// <returns></returns>
        public static Query L2Error(Func <StateVector, double> quantityOfInterest, Func <double[], double, double> referenceSolution)
        {
            return(delegate(IApplication <AppControl> app, double time) {
                IProgram <CNSControl> program = app as IProgram <CNSControl>;
                if (program == null)
                {
                    throw new Exception();
                }

                ImmersedSpeciesMap speciesMap = program.SpeciesMap as ImmersedSpeciesMap;
                IBMControl control = program.Control as IBMControl;
                if (speciesMap == null || control == null)
                {
                    throw new Exception(
                        "Query is only valid for immersed boundary runs");
                }

                SpeciesId species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName);
                int order = control.LevelSetQuadratureOrder;
                CellQuadratureScheme scheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme(
                    species, true, speciesMap.SubGrid.VolumeMask);
                var composititeRule = scheme.Compile(program.GridData, order);
                IChunkRulePair <QuadRule>[] chunkRulePairs = composititeRule.ToArray();

                DGField density = program.WorkingSet.Density;
                VectorField <DGField> momentum = program.WorkingSet.Momentum;
                DGField energy = program.WorkingSet.Energy;

                // Construct dummy field since L2Error is currently only supported
                // for Field's; However, _avoid_ a projection.
                DGField dummy = new SinglePhaseField(new Basis(program.GridData, 0));
                Material material = speciesMap.GetMaterial(double.NaN);
                int index = 0;
                double value = dummy.LxError(
                    (ScalarFunctionEx) delegate(int j0, int Len, NodeSet nodes, MultidimensionalArray result) {
                    MultidimensionalArray input = program.GridData.GlobalNodes.GetValue_Cell(nodes, j0, Len);

                    Chunk chunk = chunkRulePairs[index].Chunk;
                    QuadRule rule = chunkRulePairs[index].Rule;

                    if (chunk.i0 != j0 || chunk.Len != Len)
                    {
                        throw new Exception();
                    }

                    if (rule.NoOfNodes != nodes.GetLength(0))
                    {
                        throw new Exception();
                    }

                    MultidimensionalArray rho = MultidimensionalArray.Create(chunk.Len, rule.NoOfNodes);
                    density.Evaluate(chunk.i0, chunk.Len, nodes, rho);

                    MultidimensionalArray[] m = new MultidimensionalArray[CompressibleEnvironment.NumberOfDimensions];
                    for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
                    {
                        m[d] = MultidimensionalArray.Create(chunk.Len, rule.NoOfNodes);
                        momentum[d].Evaluate(chunk.i0, chunk.Len, nodes, m[d]);
                    }

                    MultidimensionalArray rhoE = MultidimensionalArray.Create(chunk.Len, rule.NoOfNodes);
                    energy.Evaluate(chunk.i0, chunk.Len, nodes, rhoE);

                    double[] X = new double[CompressibleEnvironment.NumberOfDimensions];
                    Vector mVec = new Vector(CompressibleEnvironment.NumberOfDimensions);
                    for (int i = 0; i < chunk.Len; i++)
                    {
                        for (int j = 0; j < rule.NoOfNodes; j++)
                        {
                            for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
                            {
                                X[d] = input[i, j, d];
                                mVec[d] = m[d][i, j];
                            }

                            StateVector state = new StateVector(material, rho[i, j], mVec, rhoE[i, j]);
                            double qoi = quantityOfInterest(state);

                            Debug.Assert(
                                !double.IsNaN(qoi),
                                "Encountered node with unphysical state"
                                + " (not able to determine quantity of interest)");

                            result[i, j] = qoi - referenceSolution(X, time);
                        }
                    }

                    index++;
                },
                    (X, a, b) => (a - b) * (a - b),
                    composititeRule);

                // No value is NaN, but the results. How can this be?
                // => All values around 0, but values in void region are a little
                // farther away from the exact solution
                // => weights in the void zone sum up to something slightly negative
                Debug.Assert(
                    value >= 0,
                    "Encountered unphysical norm even though individual values where valid."
                    + " This indicates a problem with cut-cell quadrature.");

                return Math.Sqrt(value);
            });
        }
コード例 #20
0
        protected override void PlotCurrentState(double physTime, TimestepNumber timestepNo, int susamp)
        {
            var Fields = new DGField[] { this.Phi, this.u, this.rhs, this.Residual, this.V[0], this.V[1], this.CutMarker, this.DOFMarker, this.NearMarker };

            Tecplot.PlotFields(Fields, "XdgTimesteppingTest" + timestepNo.ToString(), physTime, susamp);
        }
コード例 #21
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) 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];
            }

            // 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
            if (OpMatrix != null)
            {
                //Op.ComputeMatrixEx(Tracker,
                //    ColMapping, Params, RowMapping,
                //    OpMatrix, OpAffine, false, time, true,
                //    AgglomeratedCellLengthScales,
                //    InterfaceLengths, SlipLengths,
                //    SpcToCompute);

                XSpatialOperator.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
            {
                XSpatialOperator.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.");
             * }
             */
        }
コード例 #22
0
ファイル: PatchRecovery.cs プロジェクト: xj361685640/BoSSS
        static MultidimensionalArray NodalPatchRecovery(int jCell, double[] Nodes, DGField Phi, out AffineTrafo Trafilein)
        {
            GridData GridData = (GridData)Phi.GridDat;

            int[] Neighbours, Edges;
            GridData.GetCellNeighbours(jCell, GetCellNeighbours_Mode.ViaVertices, out Neighbours, out Edges);
            if (Neighbours.Length != 8)
            {
                throw new NotSupportedException();
            }

            int[] JS = Neighbours;
            jCell.AddToArray(ref JS);

            MultidimensionalArray CellCoordinates = MultidimensionalArray.Create(JS.Length, 4, 2); // 1st index: jcell, top, bottom, left, right
            var Kref = GridData.iGeomCells.RefElements[0];

            if (GridData.iGeomCells.RefElements.Length != 1 || Kref.GetType() != typeof(BoSSS.Foundation.Grid.RefElements.Square))
            {
                throw new NotImplementedException();
            }
            for (int f = 0; f < JS.Length; f++)
            {
                GridData.TransformLocal2Global(Kref.Vertices, CellCoordinates.ExtractSubArrayShallow(f, -1, -1), JS[f]);
            }

            double xMin = CellCoordinates.ExtractSubArrayShallow(-1, -1, 0).Min();
            double xMax = CellCoordinates.ExtractSubArrayShallow(-1, -1, 0).Max();
            double yMin = CellCoordinates.ExtractSubArrayShallow(-1, -1, 1).Min();
            double yMax = CellCoordinates.ExtractSubArrayShallow(-1, -1, 1).Max();

            int N = Nodes.Length;

            double[] xNodes = new double[N];
            double[] yNodes = new double[N];
            for (int i = 0; i < N; i++)
            {
                xNodes[i] = (xMax - xMin) * 0.5 * (Nodes[i] + 1) + xMin;
                yNodes[i] = (yMax - yMin) * 0.5 * (Nodes[i] + 1) + yMin;
            }
            var TrChey2Glob = new AffineTrafo(2);

            TrChey2Glob.Matrix[0, 0] = (xMax - xMin) * 0.5; TrChey2Glob.Affine[0] = (xMax - xMin) * 0.5 + xMin;
            TrChey2Glob.Matrix[1, 1] = (yMax - yMin) * 0.5; TrChey2Glob.Affine[1] = (yMax - yMin) * 0.5 + yMin;


            MultidimensionalArray[] NodeSets_global = new MultidimensionalArray[JS.Length];
            NodeSet[]     NodeSets   = new NodeSet[JS.Length];
            List <double> xNodesCell = new List <double>();
            List <double> yNodesCell = new List <double>();

            int[][] MapTo_i = new int[JS.Length][];
            int[][] MapTo_j = new int[JS.Length][];


            for (int f = 0; f < JS.Length; f++)
            {
                MultidimensionalArray CellCoords = CellCoordinates.ExtractSubArrayShallow(f, -1, -1);
                double xMinCell = CellCoords.ExtractSubArrayShallow(-1, 0).Min();
                double xMaxCell = CellCoords.ExtractSubArrayShallow(-1, 0).Max();
                double yMinCell = CellCoords.ExtractSubArrayShallow(-1, 1).Min();
                double yMaxCell = CellCoords.ExtractSubArrayShallow(-1, 1).Max();

                int iMin   = xNodes.FirstIndexWhere(x => x >= xMinCell);
                int iMax   = xNodes.LastIndexWhere(x => x < xMaxCell);
                int jMin   = yNodes.FirstIndexWhere(y => y >= yMinCell);
                int jMax   = yNodes.LastIndexWhere(y => y < yMaxCell);
                int NxCell = iMax - iMin + 1;
                int NyCell = jMax - jMin + 1;

                int K = NxCell * NyCell;
                NodeSets_global[f] = MultidimensionalArray.Create(K, 2);

                MapTo_i[f] = new int[K];
                MapTo_j[f] = new int[K];

                int k = 0;
                for (int i = iMin; i <= iMax; i++)
                {
                    for (int j = jMin; j <= jMax; j++)
                    {
                        MapTo_i[f][k]            = i;
                        MapTo_j[f][k]            = j;
                        NodeSets_global[f][k, 0] = xNodes[i];
                        NodeSets_global[f][k, 1] = yNodes[j];

                        Debug.Assert(GridData.Cells.IsInCell(new double[] { xNodes[i], yNodes[j] }, JS[f], null));

                        k++;
                    }
                }

                NodeSets[f] = new NodeSet(GridData.Cells.GetRefElement(jCell), NxCell * NyCell, 2);
                GridData.TransformGlobal2Local(NodeSets_global[f], NodeSets[f], JS[f], null);
                NodeSets[f].LockForever();
            }

            var TrGl2Loc = AffineTrafo.FromPoints(NodeSets_global.Last().ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { 2, 1 }), NodeSets.Last().ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { 2, 1 }));

            Trafilein = (TrGl2Loc * TrChey2Glob).Invert();



            var Return = MultidimensionalArray.Create(N, N);

            for (int f = 0; f < JS.Length; f++)
            {
                int K      = NodeSets[f].GetLength(0);
                var Result = MultidimensionalArray.Create(1, K);
                Phi.Evaluate(JS[f], 1, NodeSets[f], Result);

                for (int k = 0; k < K; k++)
                {
                    //double x_i = xNodes[MapTo_i[f][k]];
                    //double y_j = yNodes[MapTo_j[f][k]];
                    //double val = (x_i*0.3).Pow2()  - (y_j*0.3).Pow2();



                    Debug.Assert(Return[MapTo_i[f][k], MapTo_j[f][k]] == 0.0);
                    Return[MapTo_i[f][k], MapTo_j[f][k]] = Result[0, k];
                }
            }

            // ----------------------------------

            return(Return);
        }
コード例 #23
0
        static private void DoCellj(int j, DGField f, GridData NewGrid, int pDeg, int[] TargMappingIdx_j, double[][] ReDistDGCoords_j, int l, GridCorrelation Old2NewCorr, int N0rcv, int N0acc, int Np, double[] ReDistDGCoords_jl, double[] Coords_j)
        {
            Debug.Assert(ReDistDGCoords_j.Length == TargMappingIdx_j.Length);
            Debug.Assert(object.ReferenceEquals(NewGrid, f.GridDat));

            int iKref = NewGrid.Cells.GetRefElementIndex(j);

            Debug.Assert(Coords_j.Length == Np);
            Debug.Assert(ReDistDGCoords_jl.Length == Np);

            for (int n = 0; n < Np; n++)
            {
                Coords_j[n] = f.Coordinates[j, N0acc + n]; // for coarsening, we 'touch' each cell multiple times -- therefore, values must be accumulated
            }

            int L = ReDistDGCoords_j.Length;


            if (TargMappingIdx_j.Length == 1)
            {
                // ++++++++++
                // refinement
                // ++++++++++
                Debug.Assert(l == 0);
                MultidimensionalArray Trafo = Old2NewCorr.GetSubdivBasisTransform(iKref, TargMappingIdx_j[0], pDeg).Item1;
                double scale = Old2NewCorr.GetSubdivBasisTransform(iKref, TargMappingIdx_j[0], pDeg).Item2;

                for (int n = 0; n < Np; n++)
                {
                    ReDistDGCoords_jl[n] = ReDistDGCoords_j[0][N0rcv + n];
                }
                Trafo.gemv(1.0, ReDistDGCoords_jl, 1.0, Coords_j, transpose: false);
                BckTrafo(Coords_j, Np, 0, NewGrid, j, pDeg, scale.Sqrt());
            }
            else
            {
                // ++++++++++
                // coarsening
                // ++++++++++
                var    Trafo = Old2NewCorr.GetSubdivBasisTransform(iKref, TargMappingIdx_j[l], pDeg).Item1;
                double scale = Old2NewCorr.GetSubdivBasisTransform(iKref, TargMappingIdx_j[l], pDeg).Item2;

                for (int n = 0; n < Np; n++)
                {
                    ReDistDGCoords_jl[n] = ReDistDGCoords_j[l][N0rcv + n];
                }
                //if (!Oasch) {
                //    Trafo.gemv(1.0, ReDistDGCoords_jl, 1.0, Coords_j, transpose: true);
                //} else {
                double[] buf = new double[Np];
                Trafo.gemv(1.0, ReDistDGCoords_jl, 1.0, buf, transpose: true);
                BckTrafo(buf, Np, 0, NewGrid, j, pDeg, 1.0 / scale.Sqrt());

                Coords_j.AccV(1.0, buf);
                //}
            }

            for (int n = 0; n < Np; n++)
            {
                f.Coordinates[j, N0acc + n] = Coords_j[n];
            }
        }
コード例 #24
0
        /// <summary>
        /// common for all constructors
        /// </summary>
        protected void Setup1(ISparseSolverExt solver, bool[] temporalOp, MsrMatrix spatialOpMtx, IList <double> spatialOpAffine, CoordinateMapping fields)
        {
            // check operator and arguments
            if (spatialOpMtx.NoOfRows != spatialOpMtx.NoOfCols)
            {
                throw new ArgumentException("matrix must be quadratic.", "spatialOpMtx");
            }
            if (spatialOpMtx.NoOfRows != fields.GlobalCount)
            {
                throw new ArgumentException("matrix size must be equal to the GlobalCount of fields mapping", "fields,spatialOpMtx");
            }
            if (spatialOpMtx.RowPartitioning.LocalLength != fields.LocalLength)
            {
                throw new ArgumentException("number of locally stored matrix rows nust be equal to NUpdate of fields mapping.", "fields,spatialOpMtx");
            }
            if (spatialOpAffine.Count < fields.LocalLength)
            {
                throw new ArgumentException("length affine offset vector must be equal or larger than NUpdate of the mapping", "spatialOpAffine");
            }

            m_Solver        = solver;
            m_Mapping       = fields;
            m_AffineOffset1 = spatialOpAffine.ToArray();

            //Setup2(spatialOpMtx, temporalOp);
            //}

            ///// <summary>
            ///// Common to all constructors; Passes the Matrix <paramref name="eM"/>
            ///// to the solver and initializes <see cref="m_diagVecOneSec"/>;
            ///// </summary>
            ///// <param name="eM"><see cref="eM"/></param>
            ///// <param name="temporalOp"><see cref="ImplicitTimeStepper"/></param>
            //private void _Setup2(MsrMatrix eM, bool[] temporalOp) {

            {
                // check temporal operator
                // -----------------------
                if (m_Mapping.Fields.Count != temporalOp.Length)
                {
                    throw new ArgumentException(
                              "length of temporalOp must be equal to number of domain/codomain variables of the spatial differential operator",
                              "temporalOp");
                }
                m_DGCoordinates = new CoordinateVector(m_Mapping);

                bool timedep      = false;
                bool fullyTimeDep = true;
                foreach (bool b in temporalOp)
                {
                    timedep      = timedep || b;
                    fullyTimeDep = fullyTimeDep & b;
                }
                if (!timedep)
                {
                    throw new ArgumentException("at least one equation must be time-dependent; one entry in temporalOp must be true;", "temporalOp");
                }

                // Construct diagonal matrix vector
                // --------------------------------
                m_diagVecOneSec = new double[m_Mapping.MaxTotalNoOfCoordinatesPerCell];
                IList <DGField> _fields = m_Mapping.Fields;
                for (int g = 0; g < temporalOp.Length; g++)
                {
                    if (temporalOp[g])
                    {
                        DGField gamma = _fields[g];
                        for (int n = 0; n < gamma.Basis.MaximalLength; n++)
                        {
                            m_diagVecOneSec[m_Mapping.LocalUniqueCoordinateIndex(g, 0, n)] = 1.0;
                        }
                    }
                }

                // initialize linear solver
                m_Solver.DefineMatrix(spatialOpMtx);
            }
        }
コード例 #25
0
ファイル: HilbertTest.cs プロジェクト: rohitvuppala/BoSSS
        static private bool TestingGridDistributionDynamic()
        {
            //string dbPath = @"D:\Weber\BoSSS\test_db";
            //TestCase: 5x4 grid, Timesteps, LTS-Cluster, PartOn,recInt,AV=false, dgdegree=0, Timestepping=LTS
            CNSControl control = ShockTube_PartTest_Dynamic(5, 4, 1, 2, true, 1);

            using (var solver = new HilbertTest()) {
                solver.Init(control);
                solver.RunSolverMode();
                bool result = false;

                List <DGField> listOfDGFields = (List <DGField>)solver.IOFields;
                DGField        field          = listOfDGFields[12];
                int            D = field.GridDat.SpatialDimension;
                int            J = field.GridDat.iLogicalCells.NoOfLocalUpdatedCells;

                //intention:Checking if BoundaryBox of LTSCluster==1 is as expected
                //Therefore Computing BoundaryBox of LTSCluster==1
                var BB     = new BoSSS.Platform.Utils.Geom.BoundingBox(D);
                var CellBB = new BoSSS.Platform.Utils.Geom.BoundingBox(D);
                for (int i = 0; i < J; i++)
                {
                    if (field.GetMeanValue(i) == 1)
                    {
                        //Cell cj=solver.GridData.Cells.GetCell(i);
                        solver.GridData.iLogicalCells.GetCellBoundingBox(i, CellBB);
                        BB.AddBB(CellBB);
                    }
                }
                BB.Max = BB.Max.MPIMax();
                BB.Min = BB.Min.MPIMin();
                for (int i = 0; i < D; i++)
                {
                    BB.Max[i] = Math.Round(BB.Max[i] * 100) / 100;
                    BB.Min[i] = Math.Round(BB.Min[i] * 100) / 100;
                }
                double[] MaxRef = { 0.6, 1 };
                double[] MinRef = { 0, 0 };

                if (ItemsAreEqual(BB.Max, MaxRef) && ItemsAreEqual(BB.Min, MinRef))
                {
                    //Comparing checkLTS to Distribution along HilbertCurve of Testcase
                    int[] checkLTS = { 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 0, 0, 2, 2, 2, 3, 3, 3 };
                    //result = ItemsAreEqual(solver.Grid.GetHilbertSortedRanks(),checkLTS);
                    int J0 = solver.GridData.CellPartitioning.i0;
                    int JE = solver.GridData.CellPartitioning.iE;

                    ulong[] discreteCenter     = new ulong[D];
                    ulong[] local_HilbertIndex = new ulong[JE - J0];
                    int[]   local_RankIndex    = new int[JE - J0];

                    var _Grid = (GridCommons)(solver.Grid);

                    for (int j = J0; j < JE; j++)
                    {
                        Cell Cj        = _Grid.Cells[j - J0];
                        int  NoOfNodes = Cj.TransformationParams.NoOfRows;
                        for (int d = 0; d < D; d++)
                        {
                            double center = 0;
                            for (int k = 0; k < NoOfNodes; k++)
                            {
                                center += Cj.TransformationParams[k, d];
                            }

                            center = center / ((double)NoOfNodes);
                            double centerTrf = center * Math.Pow(2, 32);

                            centerTrf = Math.Round(centerTrf);
                            if (centerTrf < 0)
                            {
                                centerTrf = 0;
                            }
                            if (centerTrf > ulong.MaxValue)
                            {
                                centerTrf = ulong.MaxValue;
                            }
                            discreteCenter[d] = (ulong)centerTrf;
                        }
                        ulong iH = ilPSP.HilbertCurve.HilbertCurve.hilbert_c2i(32, discreteCenter);
                        local_HilbertIndex[j - J0] = iH;
                        local_RankIndex[j - J0]    = solver.MPIRank;
                    }
                    int[]   CellsPerRank = { 5, 5, 5, 5 };
                    ulong[] HilbertIndex = local_HilbertIndex.MPIAllGatherv(CellsPerRank);
                    int[]   RankIndex    = local_RankIndex.MPIAllGatherv(CellsPerRank);
                    Array.Sort(HilbertIndex, RankIndex);
                    result = ItemsAreEqual(RankIndex, checkLTS);
                }
                else
                {
                    //catching error caused by changes to LTS-Clustering
                    Console.WriteLine("Unexpected result for LTS Clusters! Computation of LTS Clusters changed. Test aborted.");
                    result = false;
                }
                Console.WriteLine("Test Grid Distribution Dynamic LTS");
                Console.WriteLine("Testresult: {0}", result);
                return(result);
            }
        }
コード例 #26
0
 /// <summary>
 /// Projection of a function <paramref name="f"/> onto a DG-Field
 /// </summary>
 public static void ProjectField(this DGField u, Func <double[], double> f)
 {
     u.ProjectField(f.Vectorize());
 }
コード例 #27
0
        public ExtensionVelocityBDFMover(LevelSetTracker LSTrk,
                                         SinglePhaseField LevelSet,
                                         VectorField <SinglePhaseField> LevelSetGradient,
                                         VectorField <DGField> Velocity,
                                         EllipticExtVelAlgoControl Control,
                                         IncompressibleBoundaryCondMap bcMap,
                                         int BDForder,
                                         VectorField <SinglePhaseField> VectorExtension,
                                         double[] Density = null,
                                         bool AssumeDivergenceFreeVelocity = false, SubGrid subGrid = null)
        {
            this.GridDat          = LSTrk.GridDat;
            D                     = GridDat.SpatialDimension;
            this.LevelSetGradient = LevelSetGradient;
            this.LSTrk            = LSTrk;
            this.LevelSet         = LevelSet;

            this.Velocity = Velocity;
            this.OldRHS   = LevelSet.CloneAs();
            this.AdvectionSpatialOperator = CreateAdvectionSpatialOperator(bcMap);

            this.subGrid   = subGrid;
            this.nearfield = subGrid != null;

            Basis NonXVelocityBasis;

            if (Velocity == null)
            {
                throw new ArgumentException("Velocity Field not initialized!");
            }

            // Initialize Extension Velocity Algorithm
            double             PenaltyBase = Control.PenaltyMultiplierInterface * ((double)((LevelSet.Basis.Degree + 1) * (LevelSet.Basis.Degree + D))) / ((double)D);
            ILevelSetComponent InterfaceFlux;



            //VectorExtension = new VectorField<SinglePhaseField>(D, Velocity[0].Basis, "ExtVel", SinglePhaseField.Factory);
            if (Velocity[0].GetType() == typeof(SinglePhaseField))
            {
                NonXVelocityBasis = ((SinglePhaseField)Velocity[0]).Basis;
                InterfaceFlux     = new SingleComponentInterfaceForm(PenaltyBase, LSTrk);
            }
            else if (Velocity[0].GetType() == typeof(XDGField))
            {
                NonXVelocityBasis = ((XDGField)Velocity[0]).Basis.NonX_Basis;
                InterfaceFlux     = new DensityWeightedExtVel(PenaltyBase, LSTrk, Density);
            }
            else
            {
                throw new ArgumentException("VelocityField must be either a SinglePhaseField or a XDGField!");
            };
            //VectorExtension = new VectorField<SinglePhaseField>(D, NonXVelocityBasis, "ExtVel", SinglePhaseField.Factory);
            this.VectorExtension = VectorExtension;



            VelocityExtender = new Extender[D];
            for (int d = 0; d < D; d++)
            {
                VelocityExtender[d] = new Extender(VectorExtension[d], LSTrk, InterfaceFlux, new List <DGField> {
                    Velocity[d]
                }, LevelSetGradient, Control);
                VelocityExtender[d].ConstructExtension(new List <DGField> {
                    Velocity[d]
                }, Control.subGridRestriction);
            }
#if DEBUG
            VectorExtension.CheckForNanOrInf();
#endif

            // Initialize Advection Algorithm
            divU = new SinglePhaseField(NonXVelocityBasis);
            divU.Identification = "Divergence";
            divU.Clear();
            divU.Divergence(1.0, VectorExtension);
            MeanVelocity = new VectorField <SinglePhaseField>(D.ForLoop(d => new SinglePhaseField(new Basis(GridDat, 0), VariableNames.Velocity0MeanVector(D)[d])));
            MeanVelocity.Clear();
            MeanVelocity.AccLaidBack(1.0, VectorExtension);
            myBDFTimestepper = new BDFTimestepper(AdvectionSpatialOperator, new List <DGField>()
            {
                LevelSet
            }, ArrayTools.Cat(VectorExtension, this.MeanVelocity, this.divU), BDForder, Control.solverFactory, false, subGrid);
        }
コード例 #28
0
 /// <summary>
 /// Projection of a function <paramref name="f"/> onto a DG-Field
 /// </summary>
 public static void ProjectField(this DGField u, double alpha, Func <double[], double> f, CellQuadratureScheme scheme = null)
 {
     u.ProjectField(alpha, f.Vectorize(), scheme);
 }
コード例 #29
0
        /// <summary>
        /// Loads the DG coordinates after grid adaptation.
        /// </summary>
        /// <param name="f"></param>
        /// <param name="Reference">
        /// Unique string reference under which data has been stored before grid-redistribution.
        /// </param>
        public override void RestoreDGField(DGField f, string Reference)
        {
            using (new FuncTrace()) {
                //if(f.Identification == "TestData") {
                //    Console.WriteLine("using oasch");
                //    Oasch = true;
                //} else {
                //    Oasch = false;
                //}



                int      newJ    = this.m_newJ;
                GridData NewGrid = (GridData)m_NewGrid;
                int      pDeg    = f.Basis.Degree; //  Refined_TestData.Basis.Degree;

                if (!object.ReferenceEquals(NewGrid, f.Basis.GridDat))
                {
                    throw new ArgumentException("DG field must be assigned to new grid.");
                }

                f.Clear();

                int[][]      TargMappingIdx = m_Old2NewCorr.GetTargetMappingIndex(NewGrid.CellPartitioning);
                double[][][] ReDistDGCoords = m_newDGFieldData_GridAdapta[Reference];
                Debug.Assert(ReDistDGCoords.Length == newJ);

                if (f is ConventionalDGField)
                {
                    // +++++++++++++++
                    // normal DG field
                    // +++++++++++++++

                    int Np = f.Basis.Length;

                    double[] temp = new double[Np];
                    double[] acc  = new double[Np];

                    for (int j = 0; j < newJ; j++)
                    {
                        if (TargMappingIdx[j] == null)
                        {
                            // unchanged cell
                            Debug.Assert(ReDistDGCoords[j].Length == 1);
                            double[] Coord = ReDistDGCoords[j][0];
                            Debug.Assert(Coord.Length == Np);

                            BckTrafo(Coord, Np, 0, NewGrid, j, pDeg, 1.0);

                            f.Coordinates.SetRow(j, Coord);
                        }
                        else
                        {
                            int L = ReDistDGCoords[j].Length;
                            for (int l = 0; l < L; l++)
                            {
                                DoCellj(j, f, NewGrid, pDeg, TargMappingIdx[j], ReDistDGCoords[j], l, m_Old2NewCorr, 0, 0, Np, temp, acc);
                            }
                        }
                    }
                }
                else if (f is XDGField)
                {
                    // +++++++++++++++++++++++
                    // treatment of XDG fields
                    // +++++++++++++++++++++++

                    // (as always, more difficult)

                    XDGField        xf    = f as XDGField;
                    LevelSetTracker lsTrk = xf.Basis.Tracker;
                    int             Np    = xf.Basis.NonX_Basis.Length;
                    double[]        temp  = new double[Np];
                    double[]        acc   = new double[Np];

                    if (!object.ReferenceEquals(m_NewTracker, lsTrk))
                    {
                        throw new ArgumentException("LevelSetTracker seems duplicate, or something.");
                    }

                    for (int j = 0; j < newJ; j++)
                    {
                        int NoOfSpc = lsTrk.Regions.GetNoOfSpecies(j);
                        f.Coordinates.ClearRow(j);

                        if (TargMappingIdx[j] == null)
                        {
                            // + + + + + + + + +
                            // unchanged cell
                            // + + + + + + + + +

                            Debug.Assert(ReDistDGCoords[j].Length == 1);
                            double[] ReDistDGCoords_jl = ReDistDGCoords[j][0];
                            //Debug.Assert(ReDistDGCoords_jl.Length == NoOfSpc*Np + NoOfSpc + 1);
                            //Debug.Assert(ReDistDGCoords_jl[0] == NoOfSpc);


                            int NoOfSpcR = (int)(ReDistDGCoords_jl[0]); // Number of species received!

                            int c = 1;
                            for (int iSpcR = 0; iSpcR < NoOfSpcR; iSpcR++)  // loop over received species...
                                                                            //#if DEBUG
                                                                            //                                SpeciesId rcvSpc;
                                                                            //                                rcvSpc.cntnt = (int) ReDistDGCoords_jl[c];
                                                                            //                                Debug.Assert(rcvSpc == lsTrk.Regions.GetSpeciesIdFromIndex(j, iSpc));
                                                                            //#endif
                            {
                                SpeciesId rcvSpc;
                                rcvSpc.cntnt = (int)ReDistDGCoords_jl[c];
                                c++;
                                int iSpcTarg = lsTrk.Regions.GetSpeciesIndex(rcvSpc, j);


                                if (iSpcTarg >= 0)
                                {
                                    for (int n = 0; n < Np; n++)
                                    {
                                        f.Coordinates[j, n + Np * iSpcTarg] = ReDistDGCoords_jl[c];
                                        c++;
                                    }
                                }
                                else
                                {
                                    //double testNorm = 0;
                                    for (int n = 0; n < Np; n++)
                                    {
                                        //testNorm += ReDistDGCoords_jl[c].Pow2();
                                        c++;
                                    }
                                }
                            }
                            Debug.Assert(c == ReDistDGCoords_jl.Length);
                        }
                        else
                        {
                            // + + + + + + + + + + + + +
                            // coarsening or refinement
                            // + + + + + + + + + + + + +

                            int L = ReDistDGCoords[j].Length;
                            for (int l = 0; l < L; l++)
                            {
                                double[] ReDistDGCoords_jl = ReDistDGCoords[j][l];
                                int      NoSpcOrg          = (int)ReDistDGCoords_jl[0]; // no of species in original cells

                                int c = 1;
                                for (int iSpcRecv = 0; iSpcRecv < NoSpcOrg; iSpcRecv++)  // loop over species in original cell

                                {
                                    SpeciesId rcvSpc;
                                    rcvSpc.cntnt = (int)ReDistDGCoords_jl[c];
                                    c++;

                                    int iSpc = lsTrk.Regions.GetSpeciesIndex(rcvSpc, j); // species index in new cell
                                    //Debug.Assert(iSpcRecv == iSpc || L > 1);

                                    int N0rcv = c;
                                    c += Np;
                                    if (iSpc >= 0)
                                    {
                                        DoCellj(j, xf, NewGrid, pDeg, TargMappingIdx[j], ReDistDGCoords[j], l, m_Old2NewCorr, N0rcv, Np * iSpc, Np, temp, acc);
                                    }
                                }
                                Debug.Assert(c == ReDistDGCoords_jl.Length);
                            }
                        }
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
        }
コード例 #30
0
        public void AdjustVerticesParamters_Fast(bool CellPosSure)
        {
            DGField[] Fields = new DGField[1 + SpatialDimension];
            Fields[0] = Interface;
            for (int dim = 0; dim < SpatialDimension; dim++)
            {
                Fields[1 + dim] = InterfaceLevelSetGradient[dim];
            }
            MultidimensionalArray Results;

            foreach (VerticesofCell CellObj in Points)
            {
                int TotalNbrOfPoints = 0;
                Dictionary <int, int> NbrofPointsperType = new Dictionary <int, int>();
                foreach (KeyValuePair <int, List <SingleVertice> > DictEntry in CellObj.ItemList)
                {
                    TotalNbrOfPoints += DictEntry.Value.Count;
                    NbrofPointsperType.Add(DictEntry.Key, DictEntry.Value.Count);
                }
                MultidimensionalArray PointsCoordinates = MultidimensionalArray.Create(TotalNbrOfPoints, SpatialDimension);
                int indx = 0;
                foreach (KeyValuePair <int, List <SingleVertice> > DictEntry in CellObj.ItemList)
                {
                    for (int k = 0; k < NbrofPointsperType[DictEntry.Key]; k++)
                    {
                        for (int dim = 0; dim < SpatialDimension; dim++)
                        {
                            PointsCoordinates[indx, dim] = DictEntry.Value[k].Coordinates[0, dim];
                        }
                        indx++;
                    }
                }
                Results = MultiEvaluatePointsInCell(Fields, PointsCoordinates, CellObj.CellIndex, CellPosSure);
                indx    = 0;
                foreach (KeyValuePair <int, List <SingleVertice> > DictEntry in CellObj.ItemList)
                {
                    foreach (SingleVertice SingleVertice in DictEntry.Value)
                    {
                        // Set Phi
                        if (SingleVertice.Phi == null)
                        {
                            SingleVertice.Phi = MultidimensionalArray.Create(1, 1);
                        }
                        SingleVertice.Phi[0, 0] = Results[0, indx];

                        //Set Normal
                        MultidimensionalArray Normal_new = MultidimensionalArray.Create(1, SpatialDimension);
                        for (int dim = 0; dim < SpatialDimension; dim++)
                        {
                            Normal_new[0, dim] = Results[dim + 1, indx];
                        }
                        Normal_new = NormalizeVector(Normal_new);
                        if (SingleVertice.Normal == null)
                        {
                            SingleVertice.Normal = Normal_new;
                        }
                        else
                        {
                            if (DotProduct(SingleVertice.Normal, Normal_new) < 0.0)
                            {
                                SingleVertice.Active = false;
                            }
                            SingleVertice.Normal = Normal_new;
                        }
                        indx++;
                    }
                }
            }
        }