private SinglePhaseField SpecFEMInterpolation(string fieldName, SpecFemBasis basis, MultidimensionalArray rho, MultidimensionalArray u, MultidimensionalArray v, MultidimensionalArray p, Func <double, double, double, double, double> func) { SpecFemField specFEMField = new SpecFemField(basis); int noOfNodesPerCell = noOfNodesPerEdge * noOfNodesPerEdge; int[,] cellNodeToNode = specFEMField.Basis.CellNode_To_Node; Debug.Assert(cellNodeToNode.GetLength(1) == noOfNodesPerCell); for (int i = 0; i < gridData.Grid.NoOfUpdateCells; i++) { for (int j = 0; j < noOfNodesPerCell; j++) { int matlabNodeIndex = GetLocalMatlabNodeIndex( basis.CellNodes[0][j, 0], basis.CellNodes[0][j, 1]); var indices = GetNodeIndices(i, matlabNodeIndex); specFEMField.Coordinates[cellNodeToNode[i, j]] = func( rho[indices.Item1, indices.Item2], u[indices.Item1, indices.Item2], v[indices.Item1, indices.Item2], p[indices.Item1, indices.Item2]); } } SinglePhaseField dgField = new SinglePhaseField(new Basis(gridData, dgDegree), fieldName); specFEMField.AccToDGField(1.0, dgField); return(dgField); }
/// <summary> /// Constructor /// </summary> /// <param name="gridData"></param> /// <param name="config"></param> public IBMFieldSet(IGridData gridData, IBMControl config) : base(gridData, config) { this.config = config; if (config.RestartInfo == null && !config.FieldOptions.ContainsKey(IBMVariables.LevelSet)) { throw new Exception( "Field 'levelSet' is required for IBM applications"); } LevelSet = new LevelSet( new Basis(gridData, config.FieldOptions[IBMVariables.LevelSet].Degree), IBMVariables.LevelSet); if (config.ContinuousLevelSet) { SpecFemBasis specFEMBasis = new SpecFemBasis((GridData)gridData, LevelSet.Basis.Degree); SpecFemField specFemField = new SpecFemField(specFEMBasis); specFemField.ProjectDGFieldMaximum(1.0, LevelSet); LevelSet.Clear(); specFemField.AccToDGField(1.0, LevelSet); } LevelSetGradient = new DGField[CompressibleEnvironment.NumberOfDimensions]; for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++) { LevelSetGradient[d] = DerivedFields[IBMVariables.LevelSetGradient[d]]; } }
public void MakeContinuous(SinglePhaseField DGLevelSet, SinglePhaseField LevelSet, CellMask Domain) { FEMLevSet.ProjectDGField(1.0, DGLevelSet, Domain); LevelSet.Clear(); FEMLevSet.AccToDGField(1.0, LevelSet, Domain); LevelSet.AccLaidBack(1.0, DGLevelSet, Domain.Complement()); }
private void UpdateArtificialViscosity() { // Determine piecewise constant viscosity this.ArtificialViscosityField.Clear(); // Cell masks CellMask cutCells = this.LevelSetTracker.Regions.GetCutCellMask(); CellMask speciesA_nonCut = this.LevelSetTracker.Regions.GetSpeciesMask("A").Except(cutCells); CellMask speciesB_nonCut = this.LevelSetTracker.Regions.GetSpeciesMask("B").Except(cutCells); // Calculate AV SetAVForSpecies(speciesA_nonCut, "A"); SetAVForSpecies(speciesB_nonCut, "B"); SetAVForCutCells(cutCells); // Set AV manually for testing //this.ArtificialViscosityField.Clear(); //this.ArtificialViscosityField.AccConstant(1.0); // Project visocsity onto continuous, multilinear space if (CompressibleEnvironment.NumberOfDimensions < 3) { // Standard version if (avSpecFEMBasis == null || !this.ArtificialViscosityField.Basis.Equals(avSpecFEMBasis.ContainingDGBasis)) { avSpecFEMBasis = new SpecFemBasis((GridData)this.GridData, 2); } SpecFemField specFemField = new SpecFemField(avSpecFEMBasis); specFemField.ProjectDGFieldMaximum(1.0, this.ArtificialViscosityField); this.ArtificialViscosityField.Clear(); specFemField.AccToDGField(1.0, this.ArtificialViscosityField); } else { throw new NotImplementedException("Artificial viscosity has only been tested for 2D"); } }
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); }
/// <summary> /// Deprecated utility, writes matrices for spectral element method. /// </summary> public void WriteSEMMatrices() { int kSEM; // nodes per edge if (this.Grid.RefElements[0] is Triangle) { kSEM = this.T.Basis.Degree + 1; } else if (this.Grid.RefElements[0] is Square) { switch (this.T.Basis.Degree) { case 2: kSEM = 2; break; case 3: kSEM = 2; break; case 4: kSEM = 3; break; case 5: kSEM = 3; break; case 6: kSEM = 4; break; default: throw new NotSupportedException(); } } else { throw new NotImplementedException(); } SpecFemBasis SEM_basis = new SpecFemBasis((GridData)(this.GridData), kSEM); SEM_basis.CellNodes[0].SaveToTextFile("NODES_SEM" + kSEM + ".txt"); SEM_basis.MassMatrix.SaveToTextFileSparse("MASS_SEM" + kSEM + ".txt"); var Mod2Nod = SEM_basis.GetModal2NodalOperator(this.T.Basis); var Nod2Mod = SEM_basis.GetNodal2ModalOperator(this.T.Basis); Mod2Nod.SaveToTextFileSparse("MODAL" + this.T.Basis.Degree + "_TO_NODAL" + kSEM + ".txt"); Nod2Mod.SaveToTextFileSparse("NODAL" + kSEM + "_TO_MODAL" + this.T.Basis.Degree + ".txt"); this.LaplaceMtx.SaveToTextFileSparse("OPERATOR" + this.T.Basis.Degree + ".txt"); { var TEST = this.T.CloneAs(); TEST.Clear(); TEST.ProjectField((_2D)((x, y) => x * y)); int J = this.GridData.iGeomCells.Count; int N = SEM_basis.NodesPerCell[0]; MultidimensionalArray TEST_at_NODES = MultidimensionalArray.Create(J, N); TEST.Evaluate(0, J, SEM_basis.CellNodes[0], TEST_at_NODES); double[] CompareAtNodes = new double[J * N]; Mod2Nod.SpMVpara(1.0, TEST.CoordinateVector, 0.0, CompareAtNodes); double[] gretchen = TEST_at_NODES.ResizeShallow(J * N).To1DArray(); double fdist = GenericBlas.L2Dist(gretchen, CompareAtNodes); Debug.Assert(fdist < 1.0e-8); double[] bak = new double[TEST.Mapping.LocalLength]; Nod2Mod.SpMVpara(1.0, CompareAtNodes, 0.0, bak); double hdist = GenericBlas.L2Dist(bak, TEST.CoordinateVector); Debug.Assert(hdist < 1.0e-8); } var Scatter = SEM_basis.GetNodeScatterMatrix(); Scatter.SaveToTextFileSparse("SCATTER_SEM" + kSEM + ".txt"); { var SEMTEST = new SpecFemField(SEM_basis); var csem = SEMTEST.Coordinates; Random r = new Random(666); for (int i = 0; i < csem.GetLength(0); i++) { csem[i] = r.NextDouble(); } var DG_TEST0 = new SinglePhaseField(SEMTEST.Basis.ContainingDGBasis); var DG_TEST = this.T.CloneAs(); DG_TEST.Clear(); SEMTEST.AccToDGField(1.0, DG_TEST0); DG_TEST.AccLaidBack(1.0, DG_TEST0); double[] S2 = new double[Scatter.RowPartitioning.LocalLength]; double[] S3 = new double[DG_TEST.Mapping.LocalLength]; Scatter.SpMVpara(1.0, csem.To1DArray(), 0.0, S2); Nod2Mod.SpMVpara(1.0, S2, 0.0, S3); double gdist = GenericBlas.L2Dist(S3, DG_TEST.CoordinateVector); Debug.Assert(gdist < 1.0e-8); } }