Example #1
0
        private void Filter(SinglePhaseField FiltrdField, int NoOfSweeps, CellMask CC)
        {
            Basis patchRecoveryBasis = FiltrdField.Basis;

            L2PatchRecovery l2pr = new L2PatchRecovery(patchRecoveryBasis, patchRecoveryBasis, CC, true);

            SinglePhaseField F_org = FiltrdField.CloneAs();

            for (int pass = 0; pass < NoOfSweeps; pass++)
            {
                F_org.Clear();
                F_org.Acc(1.0, FiltrdField);
                FiltrdField.Clear();
                l2pr.Perform(FiltrdField, F_org);
            }
        }
Example #2
0
        static void PolynomialRestAndPrlgTestRec(int p, MultigridMapping[] MgMapSeq)
        {
            var AggBasis = MgMapSeq.First().AggBasis[0];
            //var AggBasis = aggBasisEs[1];
            //{
            var Orig = new SinglePhaseField(new Basis(grid, p));

            SetTestValue(Orig);
            var Test = Orig.CloneAs();

            double[] OrigVec = Orig.CoordinateVector.ToArray();
            double[] RestVec = new double[AggBasis.LocalDim];
            double[] PrlgVec = new double[OrigVec.Length];


            AggBasis.RestictFromFullGrid(OrigVec, RestVec);
            Test.Clear();
            AggBasis.ProlongateToFullGrid(PrlgVec, RestVec);

            BlockMsrMatrix RestOp = new BlockMsrMatrix(MgMapSeq[0], MgMapSeq[0].ProblemMapping);

            AggBasis.GetRestrictionMatrix(RestOp, MgMapSeq[0], 0);
            double[] RestVec2 = new double[RestVec.Length];
            RestOp.SpMV(1.0, OrigVec, 0.0, RestVec2);


            Test.Clear();
            Test.CoordinateVector.Acc(1.0, PrlgVec);


            Test.Acc(-1.0, Orig);
            double ErrNorm = Test.L2Norm();

            Console.WriteLine("Polynomial Restriction/Prolongation test (p={1}, level={2}): {0}", ErrNorm, p, -MgMapSeq.Length);
            Assert.Less(ErrNorm, 1.0e-8);

            if (MgMapSeq.Length > 1)
            {
                PolynomialRestAndPrlgTestRec(p, MgMapSeq.Skip(1).ToArray());
            }
        }
Example #3
0
        /// <summary>
        /// Setup and initial evaluation of RHS
        /// </summary>
        /// <param name="LevelSet"></param>
        /// <param name="Velocity"></param>
        /// <param name="bcMap">Boundary Conditions for LevelSet</param>
        /// <param name="AssumeDivergenceFreeVelocity">Switch for the source term on the rhs arising from a non divergence-free velocity</param>
        public BDFNonconservativeAdvection(SinglePhaseField LevelSet, VectorField <SinglePhaseField> Velocity, IncompressibleBoundaryCondMap bcMap, int BDForder, SubGrid subGrid = null, bool AssumeDivergenceFreeVelocity = false)
            : base(LevelSet, bcMap, AssumeDivergenceFreeVelocity)
        {
            this.Velocity = Velocity;
            this.OldRHS   = LevelSet.CloneAs();
            this.SO       = CreateAdvectionSpatialOperator(bcMap);

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

            MeanVelocity = new VectorField <SinglePhaseField>(D.ForLoop(d => new SinglePhaseField(new Basis(GridDat, 0), VariableNames.Velocity0MeanVector(D)[d])));
            MeanVelocity.Clear();
            MeanVelocity.AccLaidBack(1.0, Velocity);

            myBDFTimestepper = new BDFTimestepper(SO, new List <DGField>()
            {
                LevelSet
            }, ArrayTools.Cat(this.Velocity, this.MeanVelocity, this.divU), BDForder, () => new ilPSP.LinSolvers.MUMPS.MUMPSSolver(), false, subGrid);
        }
Example #4
0
        /// <summary>
        /// computes derivatives in various ways and compares them against known values.
        /// </summary>
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            base.EndTime       = 0.0;
            base.NoOfTimesteps = 0;

            int D = this.GridData.SpatialDimension;
            int J = this.GridData.iLogicalCells.NoOfLocalUpdatedCells;

            Console.WriteLine("DerivativeTest.exe, test case #" + GRID_CASE + " ******************************");

            //var Fix = this.GridData.iGeomEdges.FaceIndices;
            //for(int iEdge = 0; iEdge < Fix.GetLength(0); iEdge++) {
            //    Debug.Assert(Fix[iEdge, 0] >= 0);
            //    Debug.Assert(Fix[iEdge, 1] >= 0);
            //}

            // sealing test
            // =================

            if (this.GridData is Foundation.Grid.Classic.GridData)
            {
                TestSealing(this.GridData);
            }

            // cell volume and edge area check, if possible
            // ===============================================


            if (this.CellVolume > 0)
            {
                double err      = 0;
                double Treshold = 1.0e-10;


                for (int j = 0; j < J; j++)
                {
                    err += Math.Abs(this.GridData.iLogicalCells.GetCellVolume(j) - this.CellVolume);
                }

                bool passed = (err < Treshold);
                m_passed = m_passed && passed;
                Console.WriteLine("Cell volume error: " + err + " passed? " + passed);
                Console.WriteLine("--------------------------------------------");
            }

            if (this.EdgeArea > 0)
            {
                double err      = 0;
                double Treshold = 1.0e-10;

                int E = this.GridData.iLogicalEdges.Count;

                for (int e = 0; e < E; e++)
                {
                    err += Math.Abs(this.GridData.iLogicalEdges.GetEdgeArea(e) - this.EdgeArea);
                }

                bool passed = (err < Treshold);
                m_passed = m_passed && passed;
                Console.WriteLine("Edge area error: " + err + " passed? " + passed);
                Console.WriteLine("--------------------------------------------");
            }

            // Orthonormality of basis in physical coords
            // ==========================================

            {
                Basis Bs      = this.f1.Basis;
                int   N       = Bs.Length;
                int   degQuad = this.GridData.iLogicalCells.GetInterpolationDegree(0) * D + Bs.Degree + 3;
                int[] jG2jL   = this.GridData.iGeomCells.GeomCell2LogicalCell;


                // mass matrix: should be identity!
                MultidimensionalArray MassMatrix = MultidimensionalArray.Create(J, N, N);

                // compute mass matrix by quadrature.
                var quad = CellQuadrature.GetQuadrature(new int[] { N, N }, base.GridData,
                                                        (new CellQuadratureScheme()).Compile(base.GridData, degQuad),
                                                        delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                    NodeSet QuadNodes = QR.Nodes;
                    MultidimensionalArray BasisVals = Bs.CellEval(QuadNodes, i0, Length);
                    EvalResult.Multiply(1.0, BasisVals, BasisVals, 0.0, "jknm", "jkn", "jkm");
                },
                                                        delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                    if (jG2jL != null)
                    {
                        for (int i = 0; i < Length; i++)
                        {
                            int jG = i + i0;
                            MassMatrix.ExtractSubArrayShallow(jG2jL[jG], -1, -1)
                            .Acc(1.0, ResultsOfIntegration.ExtractSubArrayShallow(i, -1, -1));
                        }
                    }
                    else
                    {
                        MassMatrix.SetSubArray(ResultsOfIntegration, new int[] { i0, 0, 0 }, new int[] { i0 + Length - 1, N - 1, N - 1 });
                    }
                },
                                                        cs: CoordinateSystem.Physical);
                quad.Execute();

                // check that mass matrix is Id.
                int    MaxErrorCell = -1;
                double MaxError     = -1;
                for (int j = 0; j < J; j++)
                {
                    MultidimensionalArray MassMatrix_j = MassMatrix.ExtractSubArrayShallow(j, -1, -1);
                    MassMatrix_j.AccEye(-1.0);

                    double Norm_j = MassMatrix_j.InfNorm();
                    if (Norm_j > MaxError)
                    {
                        MaxError     = Norm_j;
                        MaxErrorCell = j;
                    }
                }

                bool passed = (MaxError < 1.0e-8);
                m_passed = m_passed && passed;
                Console.WriteLine("Mass Matrix, maximum error in Cell #" + MaxErrorCell + ", mass matrix error norm: " + MaxError + " passed? " + passed);
            }

            // Broken Derivatives
            // =================

            double totalVolume = (new SubGrid(CellMask.GetFullMask(this.GridData))).Volume;

            for (int d = 0; d < D; d++)
            {
                // compute
                f1Gradient_Numerical[d].Clear();
                f1Gradient_Numerical[d].Derivative(1.0, f1, d);
                f2Gradient_Numerical[d].Clear();
                f2Gradient_Numerical[d].Derivative(1.0, f2, d);

                // subtract analytical
                var Errfield1 = f1Gradient_Numerical[d].CloneAs();
                Errfield1.Acc(-1, f1Gradient_Analytical[d]);

                var Errfield2 = f2Gradient_Numerical[d].CloneAs();
                Errfield2.Acc(-1, f2Gradient_Analytical[d]);

                Console.WriteLine("Broken Derivatives: ");

                double Treshold = 1.0e-10;
                if (AltRefSol)
                {
                    Treshold = 1.0e-4; // not exactly polynomial, therefore a higher threshold
                }
                double err1_dx = Errfield1.L2Norm() / totalVolume;
                bool   passed  = (err1_dx < Treshold);
                m_passed = m_passed && passed;
                Console.WriteLine(string.Format("|| df1/dx{0}_Numerical - df1/dx{0}_Analytical ||_2 = {1}, passed? {2}", d, err1_dx, passed));

                double err2_dx = Errfield2.L2Norm() / totalVolume;
                passed   = (err2_dx < Treshold);
                m_passed = m_passed && passed;
                Console.WriteLine(string.Format("|| df2/dx{0}_Numerical - df2/dx{0}_Analytical ||_2 = {1}, passed? {2}", d, err2_dx, passed));

                Console.WriteLine("--------------------------------------------");
            }

            // Flux Derivatives
            // =================
            for (int d = 0; d < D; d++)
            {
                // compute
                f1Gradient_Numerical[d].Clear();
                f1Gradient_Numerical[d].DerivativeByFlux(1.0, f1, d);
                f2Gradient_Numerical[d].Clear();
                f2Gradient_Numerical[d].DerivativeByFlux(1.0, f2, d);

                f1Gradient_Numerical[d].CheckForNanOrInf(true, true, true);
                f2Gradient_Numerical[d].CheckForNanOrInf(true, true, true);

                // subtract analytical
                var Errfield1 = f1Gradient_Numerical[d].CloneAs();
                Errfield1.Acc(-1, f1Gradient_Analytical[d]);

                var Errfield2 = f2Gradient_Numerical[d].CloneAs();
                Errfield2.Acc(-1, f2Gradient_Analytical[d]);

                Console.WriteLine("Flux Derivatives: ");

                double Treshold = 1.0e-10;
                if (AltRefSol)
                {
                    Treshold = 1.0e-4; // not exactly polynomial, therefore a higher threshold
                }
                double err1_dx = Errfield1.L2Norm() / totalVolume;
                bool   passed  = (err1_dx < Treshold);
                m_passed = m_passed && passed;
                Console.WriteLine(string.Format("|| df1/dx{0}_Numerical - df1/dx{0}_Analytical ||_2 = {1}, passed? {2}", d, err1_dx, passed));

                double err2_dx = Errfield2.L2Norm() / totalVolume;
                passed   = (err2_dx < Treshold);
                m_passed = m_passed && passed;
                Console.WriteLine(string.Format("|| df2/dx{0}_Numerical - df2/dx{0}_Analytical ||_2 = {1}, passed? {2}", d, err2_dx, passed));

                Console.WriteLine("--------------------------------------------");
            }


            // Linear flux Derivatives
            // =======================
            for (int d = 0; d < D; d++)
            {
                double[] korrekto = f1Gradient_Numerical[d].CoordinateVector.ToArray();

                // compute
                DerivativeByFluxLinear(f1, f1Gradient_Numerical[d], d, f1);
                DerivativeByFluxLinear(f2, f2Gradient_Numerical[d], d, f2);

                // subtract analytical
                var Errfield1 = f1Gradient_Numerical[d].CloneAs();
                Errfield1.Acc(-1, f1Gradient_Analytical[d]);

                var Errfield2 = f2Gradient_Numerical[d].CloneAs();
                Errfield2.Acc(-1, f2Gradient_Analytical[d]);

                Console.WriteLine("Linear Flux Derivatives: ");

                double Treshold = 1.0e-10;
                if (AltRefSol)
                {
                    Treshold = 1.0e-4; // not exactly polynomial, therefore a higher threshold
                }
                double err1_dx = Errfield1.L2Norm() / totalVolume;
                bool   passed  = (err1_dx < Treshold);
                m_passed = m_passed && passed;
                Console.WriteLine(string.Format("|| df1/dx{0}_Numerical - df1/dx{0}_Analytical ||_2 = {1}, passed? {2}", d, err1_dx, passed));

                double err2_dx = Errfield2.L2Norm() / totalVolume;
                passed   = (err2_dx < Treshold);
                m_passed = m_passed && passed;
                Console.WriteLine(string.Format("|| df2/dx{0}_Numerical - df2/dx{0}_Analytical ||_2 = {1}, passed? {2}", d, err2_dx, passed));

                Console.WriteLine("--------------------------------------------");
            }

            // Laplacian, nonlinear
            // ====================

            if (!AltRefSol)
            {
                var Laplace = (new ipLaplace()).Operator(1);

                Laplace.Evaluate(new DGField[] { this.f1 }, new DGField[] { this.Laplace_f1_Numerical });
                Laplace.Evaluate(new DGField[] { this.f2 }, new DGField[] { this.Laplace_f2_Numerical });

                double Treshold = 1.0e-8;

                // subtract analytical
                var Errfield1 = Laplace_f1_Numerical.CloneAs();
                Errfield1.Acc(-1, Laplace_f1_Analytical);

                var Errfield2 = Laplace_f2_Numerical.CloneAs();
                Errfield2.Acc(-1, Laplace_f2_Analytical);

                double err_Lf1 = Errfield1.L2Norm() / totalVolume;
                bool   passed  = (err_Lf1 < Treshold);
                m_passed = m_passed && passed;
                Console.WriteLine(string.Format("|| /\\f1 Numerical - /\\f1 Analytical ||_2 = {0} (nonlinear evaluation), passed? {1}", err_Lf1, passed));

                double err_Lf2 = Errfield2.L2Norm() / totalVolume;
                passed   = (err_Lf2 < Treshold);
                m_passed = m_passed && passed;
                Console.WriteLine(string.Format("|| /\\f2 Numerical - /\\f2 Analytical ||_2 = {0} (nonlinear evaluation), passed? {1}", err_Lf2, passed));

                Console.WriteLine("--------------------------------------------");
            }


            // Laplacian, linear
            // ====================

            if (!AltRefSol)
            {
                var Laplace = (new ipLaplace()).Operator(1);

                var LaplaceMtx    = new BlockMsrMatrix(this.f1.Mapping, this.Laplace_f1_Numerical.Mapping);
                var LaplaceAffine = new double[LaplaceMtx.RowPartitioning.LocalLength];

                Laplace.ComputeMatrix(this.f1.Mapping, null, this.Laplace_f1_Numerical.Mapping,
                                      LaplaceMtx, LaplaceAffine, false);

                this.Laplace_f1_Numerical.CoordinateVector.SetV(LaplaceAffine);
                LaplaceMtx.SpMV(1.0, this.f1.CoordinateVector, 1.0, this.Laplace_f1_Numerical.CoordinateVector);

                this.Laplace_f2_Numerical.CoordinateVector.SetV(LaplaceAffine);
                LaplaceMtx.SpMV(1.0, this.f2.CoordinateVector, 1.0, this.Laplace_f2_Numerical.CoordinateVector);

                // subtract analytical
                var Errfield1 = Laplace_f1_Numerical.CloneAs();
                Errfield1.Acc(-1, Laplace_f1_Analytical);

                var Errfield2 = Laplace_f2_Numerical.CloneAs();
                Errfield2.Acc(-1, Laplace_f2_Analytical);


                double Treshold = 1.0e-8;

                double err_Lf1 = Errfield1.L2Norm() / totalVolume;
                bool   passed  = (err_Lf1 < Treshold);
                m_passed = m_passed && passed;
                Console.WriteLine(string.Format("|| /\\f1 Numerical - /\\f1 Analytical ||_2 = {0} (linear evaluation), passed? {1}", err_Lf1, passed));

                double err_Lf2 = Errfield2.L2Norm() / totalVolume;
                passed   = (err_Lf2 < Treshold);
                m_passed = m_passed && passed;
                Console.WriteLine(string.Format("|| /\\f2 Numerical - /\\f2 Analytical ||_2 = {0} (linear evaluation), passed? {1}", err_Lf2, passed));


                // comparison of finite difference Jacobian and Operator matrix
                if (TestFDJacobian)
                {
                    this.f1.Clear();
                    var FDJbuilder = Laplace.GetFDJacobianBuilder(this.f1.Mapping.Fields, null, this.f1.Mapping,
                                                                  delegate(IEnumerable <DGField> U0, IEnumerable <DGField> Params) {
                        return;
                    });
                    var CheckMatrix = new BlockMsrMatrix(FDJbuilder.CodomainMapping, FDJbuilder.DomainMapping);
                    var CheckAffine = new double[FDJbuilder.CodomainMapping.LocalLength];
                    FDJbuilder.ComputeMatrix(CheckMatrix, CheckAffine);

                    var ErrMatrix = LaplaceMtx.CloneAs();
                    var ErrAffine = LaplaceAffine.CloneAs();
                    ErrMatrix.Acc(-1.0, CheckMatrix);
                    ErrAffine.AccV(-1.0, CheckAffine);
                    double LinfMtx = ErrMatrix.InfNorm();
                    double L2Aff   = ErrAffine.L2NormPow2().MPISum().Sqrt();
                    bool   passed1 = (LinfMtx < 1.0e-3);
                    bool   passed2 = (L2Aff < Treshold);
                    Console.WriteLine("Finite Difference Jacobian: Matrix/Affine delta norm {0} {1}, passed? {2} {3}", LinfMtx, L2Aff, passed1, passed2);
                    m_passed = m_passed && passed1;
                    m_passed = m_passed && passed2;
                }
                Console.WriteLine("--------------------------------------------");
            }



            // finally...
            // =================

            if (m_passed)
            {
                Console.WriteLine("All tests passed. *****************************");
            }
            else
            {
                Console.WriteLine("Some error above threshold. *******************");
            }

            return(0.0); // return some artificial timestep
        }
Example #5
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);
            ILevelSetForm 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);
        }
Example #6
0
        /// <summary>
        /// Version for XDG
        /// </summary>
        /// <param name="fieldToTest"></param>
        /// <param name="massMatrix"></param>
        /// <param name="cellMask"></param>
        public void UpdateSensorValues(SinglePhaseField fieldToTest, BlockMsrMatrix massMatrix, CellMask cellMask)
        {
            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;

            // Note: This has to be the _non_-agglomerated mass matrix
            // because we still live on the non-agglomerated mesh at this point

            // 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;
            //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;
            }
        }
Example #7
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            //origin.ProjectField((x, y) => 1-x*x);
            origin.ProjectField((x, y) => x * x + y * y * y - x * y);

            specField.ProjectDGFieldCheaply(1.0, origin);
            //specField.ProjectDGField(1.0, origin);

            /*
             * if (this.MPIRank >= 0) {
             *  // specField.Coordinates[46] = 1;
             *  // specField.Coordinates[48] = -1;
             *  ilPSP.Environment.StdoutOnlyOnRank0 = false;
             *
             *  Random R = new Random();
             *
             *  for (int t = 1; t <= 2; t++) {
             *      int i0 = spec_basis.GetLocalOwnedNodesOffset(t);
             *      int L = spec_basis.GetNoOfOwnedNodes(t);
             *
             *
             *      for (int l = 0; l < L; l++) {
             *          double x = specField.Basis.GlobalNodes[i0 + l, 0];
             *          double y = specField.Basis.GlobalNodes[i0 + l, 1];
             *
             *          specField.Coordinates[i0 + l] = R.NextDouble();
             *
             *          //if (Math.Abs(x - (+2.0)) < 1.0e-8) {
             *          //    Console.WriteLine("Hi! R" + this.MPIRank + ", " + (l + i0) + " (" + x + "," + y + ")");
             *          //    specField.Coordinates[i0 + l] = y;
             *          //}
             *
             *      }
             *  }
             *
             *  //ilPSP.Environment.StdoutOnlyOnRank0 = true;
             *
             * }*/


            using (var m_transciever = new Foundation.SpecFEM.Transceiver(spec_basis)) {
                m_transciever.Scatter(specField.Coordinates);
            }

            specField.AccToDGField(1.0, Result);

            var ERR = origin.CloneAs();

            ERR.Acc(-1.0, Result);

            double L2Err  = ERR.L2Norm();
            double L2Jump = JumpNorm(Result);

            Console.WriteLine("L2 Error: " + L2Err);
            Console.WriteLine("L2 Norm of [[u]]: " + L2Jump);
            if ((L2Err < 1.0e-10 || this.Grid.PeriodicTrafo.Count > 0) && L2Jump < 1.0e-10)
            {
                Console.WriteLine("Test PASSED");
                Passed = true;
            }
            else
            {
                Console.WriteLine("Test FAILED");
                Passed = false;
            }

            Passed = true;

            base.TerminationKey = true;
            return(0.0);
        }