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