public void ComputeStronglyConnectedComponents_LongLine_HaveCorrectLength() { var g = new DependencyGraph <int>(i => i == 5 ? new[] { 12, 4 } : i <= 0 ? ArrayTools.Empty <int>() : new[] { i - 1 }); var a = new TarjanStronglyConnectedComponentsAlgorithm <DependencyGraph <int>, int, DependencyGraph <int> .Edge>(g); var scc = a.ComputeStronglyConnectedComponents(100); Assert.That(scc.Length, Is.EqualTo(94)); Assert.That(scc[5].Length, Is.EqualTo(8)); var scc2 = a.ComputeStronglyConnectedComponents(105); Assert.That(scc2.Length, Is.EqualTo(5)); }
public void Init(MultigridOperator op) { using (new FuncTrace()) { if (m_MgOp != null) { // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // someone is trying to re-use this solver: see if the settings permit that // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if (op.LevelIndex != m_MgOp.LevelIndex) { throw new ArgumentException("Re-use on different level not possible."); } if (!this.MtxFull._RowPartitioning.EqualsPartition(op.OperatorMatrix._RowPartitioning)) { throw new ArgumentException("Matrix has changed, unable to re-use"); } if (!this.MtxFull._ColPartitioning.EqualsPartition(op.OperatorMatrix._ColPartitioning)) { throw new ArgumentException("Matrix has changed, unable to re-use"); } #if DEBUG if (!object.ReferenceEquals(this.MtxFull, op.OperatorMatrix)) { BlockMsrMatrix Check = this.MtxFull.CloneAs(); Check.Acc(-1.0, op.OperatorMatrix); if (Check.InfNorm() != 0.0) { throw new ArgumentException("Matrix has changed, unable to re-use"); } } #endif if (this.m_BlockingStrategy.GetNoOfBlocks(op) != this.blockSolvers.Count()) { throw new ArgumentException("Blocking, unable to re-use"); } return; } var Mop = op.OperatorMatrix; var MgMap = op.Mapping; this.m_MgOp = op; int myMpiRank = MgMap.MpiRank; int myMpisize = MgMap.MpiSize; if (!Mop.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!Mop.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } var ag = MgMap.AggGrid; int JComp = ag.iLogicalCells.NoOfLocalUpdatedCells; int JGhost = ag.iLogicalCells.NoOfExternalCells; #if DEBUG ilPSP.Connectors.Matlab.BatchmodeConnector matlab; if (m_MatlabParalellizationCheck) { matlab = new ilPSP.Connectors.Matlab.BatchmodeConnector(); } else { matlab = null; } #endif //Mop.Clear(); //for(int i = Mop.RowPartitioning.i0; i < Mop.RowPartitioning.iE; i++) { // Mop[i, i] = i + 1; //} // get cell blocks // =============== var _Blocks = this.m_BlockingStrategy.GetBlocking(op); int NoOfSchwzBlocks = _Blocks.Count(); // test cell blocks // ================ #if DEBUG { // ensure that each cell is used exactly once, among all blocks bool[] test = new bool[ag.iLogicalCells.NoOfLocalUpdatedCells]; foreach (var bi in _Blocks) { foreach (int j in bi) { Debug.Assert(test[j] == false); test[j] = true; } ; } for (int i = 0; i < test.Length; i++) { Debug.Assert(test[i] == true); } } #endif // extend blocks according to desired overlap // ========================================== { BitArray marker = new BitArray(JComp + JGhost); if (Overlap < 0) { throw new ArgumentException(); } if (Overlap > 0) { if (Overlap > 1 && Mop.RowPartitioning.MpiSize > 1) { throw new NotSupportedException("In MPI parallel runs, the maximum supported overlap for the Schwarz preconditioner is 1."); } foreach (List <int> bi in _Blocks) // loop over blocks... { marker.SetAll(false); // marks all cells which are members of the block foreach (int jcomp in bi) { marker[jcomp] = true; } // determine overlap regions for (int k = 0; k < Overlap; k++) { int Jblock = bi.Count; for (int j = 0; j < Jblock; j++) { int jCell = bi[j]; int[] Neighs = ag.iLogicalCells.CellNeighbours[jCell]; foreach (int jNeigh in Neighs) { if (marker[jNeigh] == false) { // neighbor cell is not already a member of the block // => add it. bi.Add(jNeigh); marker[jNeigh] = true; } } } } bi.Sort(); } } BlockCells = _Blocks.Select(list => list.ToArray()).ToArray(); } // convert cell blocks to DOF blocks // ================================= List <int>[] BlkIdx_gI_lR; // for each Schwarz block, (global) indices in the local range List <int>[] BlkIdx_gI_eR; // for each Schwarz block, (global) indices of external rows and columns List <int>[] TempRowIdx_gI; // for each Schwarz block, (global) indices into the temporary matrix List <int>[] BlkIdx_lI_eR; // for each Schwarz block, (local) indices of external rows and columns List <int>[] LocalBlocks_i0, LocalBlocks_N; // blocking of the Schwarz-Blocks. // for matrix 'ExternalRowsTemp': which rows of 'Mop' are required locally List <int> ExternalRowsIndices, ExternalRows_BlockI0, ExternalRows_BlockN; { int Jup = MgMap.AggGrid.iLogicalCells.NoOfLocalUpdatedCells; int Jgh = MgMap.AggGrid.iLogicalCells.NoOfExternalCells; int LocalizedBlockCounter = 0; BlkIdx_gI_lR = NoOfSchwzBlocks.ForLoop(iPart => new List <int>(BlockCells[iPart].Length * MgMap.MaximalLength)); BlkIdx_gI_eR = NoOfSchwzBlocks.ForLoop(iPart => new List <int>()); LocalBlocks_i0 = NoOfSchwzBlocks.ForLoop(iPart => new List <int>()); LocalBlocks_N = NoOfSchwzBlocks.ForLoop(iPart => new List <int>()); TempRowIdx_gI = NoOfSchwzBlocks.ForLoop(iPart => new List <int>()); BlkIdx_lI_eR = NoOfSchwzBlocks.ForLoop(iPart => new List <int>()); ExternalRowsIndices = new List <int>(); ExternalRows_BlockI0 = new List <int>(); ExternalRows_BlockN = new List <int>(); for (int iPart = 0; iPart < NoOfSchwzBlocks; iPart++) // loop over parts... { int[] bc = BlockCells[iPart]; var biI = BlkIdx_gI_lR[iPart]; var biE = BlkIdx_gI_eR[iPart]; var l1 = TempRowIdx_gI[iPart]; var l2 = BlkIdx_lI_eR[iPart]; var LBBi0 = LocalBlocks_i0[iPart]; var LBBN = LocalBlocks_N[iPart]; int Jblock = bc.Length; int anotherCounter = 0; for (int jblk = 0; jblk < Jblock; jblk++) // loop over cells in blocks... { int j = bc[jblk]; int N = MgMap.GetLength(j); if (j < Jup) { // locally updated cell int i0 = MgMap.GlobalUniqueIndex(0, j, 0); for (int n = 0; n < N; n++) { biI.Add(i0 + n); } } else { // external cell int i0E = MgMap.GlobalUniqueIndex(0, j, 0); // int i0L = MgMap.LocalUniqueIndex(0, j, 0); // ExternalRows_BlockI0.Add(LocalizedBlockCounter); ExternalRows_BlockN.Add(N); //LEBi0.Add(LocalizedBlockCounter); //LEBn.Add(N); for (int n = 0; n < N; n++) { biE.Add(i0E + n); ExternalRowsIndices.Add(i0E + n); l1.Add(LocalizedBlockCounter + n); l2.Add(i0L + n); Debug.Assert(Mop._RowPartitioning.FindProcess(i0E + n) != myMpiRank); } LocalizedBlockCounter += N; } LBBi0.Add(anotherCounter); LBBN.Add(N); anotherCounter += N; } } //this.BlockIndices = _LocallyStoredBlockIndices.Select(bi => bi.ToArray()).ToArray(); } // get rows for blocks that use external cells // =========================================== #if DEBUG { if (Overlap == 0) { Debug.Assert(ExternalRowsIndices.Count == 0); Debug.Assert(ExternalRows_BlockI0.Count == 0); Debug.Assert(ExternalRows_BlockN.Count == 0); } foreach (var bi in BlkIdx_gI_lR) { foreach (int idx in bi) { Debug.Assert(idx >= m_MgOp.Mapping.i0); Debug.Assert(idx < m_MgOp.Mapping.iE); } } foreach (var ei in BlkIdx_gI_eR) { foreach (int idx in ei) { Debug.Assert(idx < m_MgOp.Mapping.i0 || idx >= m_MgOp.Mapping.iE); } } int LL = m_MgOp.Mapping.LocalLength; int jMax = m_MgOp.Mapping.AggGrid.iLogicalCells.NoOfCells - 1; int LE = m_MgOp.Mapping.LocalUniqueIndex(0, jMax, 0) + m_MgOp.Mapping.GetLength(jMax); foreach (var ci in BlkIdx_lI_eR) { foreach (int idx in ci) { Debug.Assert(idx >= LL); Debug.Assert(idx < LE); } } if (m_MatlabParalellizationCheck) { int globalBlockCounter = 0; for (int rankCounter = 0; rankCounter < myMpisize; rankCounter++) { int rank_NoBlks = NoOfSchwzBlocks.MPIBroadcast(rankCounter); if (rankCounter == myMpiRank) { Debug.Assert(rank_NoBlks == NoOfSchwzBlocks); } for (int iBlock = 0; iBlock < rank_NoBlks; iBlock++) { double[] vec; if (rankCounter == myMpiRank) { vec = ArrayTools.Cat(BlkIdx_gI_lR[iBlock], BlkIdx_gI_eR[iBlock]).Select(ii => ((double)(ii + 1))).ToArray(); } else { vec = new double[0]; } matlab.PutVector(vec, string.Format("BlockIdx{0}", globalBlockCounter)); globalBlockCounter++; csMPI.Raw.Barrier(csMPI.Raw._COMM.WORLD); } } } } #endif BlockMsrMatrix ExternalRowsTemp; if (myMpisize > 1 && Overlap > 0) { //int NoOfLocalRows = _ExternalBlockIndices.Sum(L => L.Count); BlockPartitioning PermRow = new BlockPartitioning(ExternalRowsIndices.Count, ExternalRows_BlockI0, ExternalRows_BlockN, Mop.MPI_Comm, i0isLocal: true); // Remark: we use a permutation matrix for MPI-exchange of rows BlockMsrMatrix Perm = new BlockMsrMatrix(PermRow, Mop._RowPartitioning); for (int iRow = 0; iRow < ExternalRowsIndices.Count; iRow++) { Debug.Assert(Mop._RowPartitioning.IsInLocalRange(ExternalRowsIndices[iRow]) == false); Perm[iRow + PermRow.i0, ExternalRowsIndices[iRow]] = 1; } ExternalRowsTemp = BlockMsrMatrix.Multiply(Perm, Mop); #if DEBUG if (m_MatlabParalellizationCheck) { matlab.PutSparseMatrix(Perm, "Perm"); matlab.PutSparseMatrix(ExternalRowsTemp, "ExternalRowsTemp"); } #endif } else { ExternalRowsTemp = null; } ExternalRowsIndices = null; ExternalRows_BlockI0 = null; ExternalRows_BlockN = null; // create solvers // ============== { blockSolvers = new ISparseSolver[NoOfSchwzBlocks]; #if DEBUG List <BlockMsrMatrix> Blocks = new List <BlockMsrMatrix>(); #endif for (int iPart = 0; iPart < NoOfSchwzBlocks; iPart++) { var bi = BlkIdx_gI_lR[iPart]; int Bsz; if (MgMap.MinimalLength == MgMap.MaximalLength) { Bsz = MgMap.MaximalLength; } else { Bsz = 1; } var l1 = TempRowIdx_gI[iPart]; //if (M.RowPartitioning.MpiSize > 1) { // int i0Proc = M.RowPartitioning.i0; // bi = bi.CloneAs(); // for (int i = 0; i < bi.Length; i++) { // bi[i] += i0Proc; // } //} BlockPartitioning localBlocking = new BlockPartitioning(bi.Count + l1.Count, LocalBlocks_i0[iPart], LocalBlocks_N[iPart], csMPI.Raw._COMM.SELF); if (l1.Count > 0) { // convert the indices into 'ExternalRowsTemp' to global indices int l1L = l1.Count; int offset = ExternalRowsTemp._RowPartitioning.i0; for (int i = 0; i < l1L; i++) { l1[i] += offset; } } BlockMsrMatrix Block = new BlockMsrMatrix(localBlocking, localBlocking);// bi.Length, bi.Length, Bsz, Bsz); Mop.WriteSubMatrixTo(Block, bi, default(int[]), bi, default(int[])); if (l1.Count > 0) { int offset = bi.Count; int[] targRows = l1.Count.ForLoop(i => i + offset); var biE = BlkIdx_gI_eR[iPart]; int[] extTargCols = biE.Count.ForLoop(i => i + offset); Mop.AccSubMatrixTo(1.0, Block, bi, default(int[]), new int[0], default(int[]), biE, extTargCols); ExternalRowsTemp.AccSubMatrixTo(1.0, Block, l1, targRows, bi, default(int[]), biE, extTargCols); } #if DEBUG if (m_MatlabParalellizationCheck) { Blocks.Add(Block); } #endif blockSolvers[iPart] = new PARDISOSolver() { CacheFactorization = true, UseDoublePrecision = false }; //blockSolvers[iPart] = new FullDirectSolver(); //blockSolvers[iPart] = new ilPSP.LinSolvers.MUMPS.MUMPSSolver(); blockSolvers[iPart].DefineMatrix(Block); } #if DEBUG if (m_MatlabParalellizationCheck) { int globalBlockCounter = 0; for (int rankCounter = 0; rankCounter < myMpisize; rankCounter++) { int rank_NoBlks = NoOfSchwzBlocks.MPIBroadcast(rankCounter); for (int iBlock = 0; iBlock < rank_NoBlks; iBlock++) { BlockMsrMatrix Block; if (rankCounter == myMpiRank) { Block = Blocks[iBlock]; } else { Block = null; } matlab.PutSparseMatrix(Block, string.Format("Block{0}", globalBlockCounter)); globalBlockCounter++; csMPI.Raw.Barrier(csMPI.Raw._COMM.WORLD); } } } #endif } // Record required indices // ======================= { this.BlockIndices_Local = new int[NoOfSchwzBlocks][]; this.BlockIndices_External = new int[NoOfSchwzBlocks][]; int LocalI0 = MgMap.i0; int LocalLength = MgMap.LocalLength; for (int iBlock = 0; iBlock < NoOfSchwzBlocks; iBlock++) { var _bi = BlkIdx_gI_lR[iBlock]; int L = _bi.Count; int[] bil = new int[L]; this.BlockIndices_Local[iBlock] = bil; for (int l = 0; l < L; l++) { bil[l] = _bi[l] - LocalI0; Debug.Assert(bil[l] >= 0); Debug.Assert(bil[l] < MgMap.LocalLength); } var _biE = BlkIdx_lI_eR[iBlock]; if (_biE.Count > 0) { this.BlockIndices_External[iBlock] = _biE.ToArray(); } } } this.MtxFull = Mop; if (CoarseSolver != null) { CoarseSolver.Init(op.CoarserLevel); } // Debug & Test-Code // ================= #if DEBUG if (m_MatlabParalellizationCheck) { Console.WriteLine("Matlab dir: " + matlab.WorkingDirectory); matlab.PutSparseMatrix(Mop, "Full"); int GlobalNoOfBlocks = NoOfSchwzBlocks.MPISum(); for (int iGlbBlock = 0; iGlbBlock < GlobalNoOfBlocks; iGlbBlock++) { matlab.Cmd("BlockErr({0} + 1, 1) = norm( Block{0} - Full( BlockIdx{0}, BlockIdx{0} ), inf );", iGlbBlock); } Random rnd = new Random(myMpiRank); double[] testRHS = new double[MgMap.LocalLength]; for (int i = 0; i < testRHS.Length; i++) { testRHS[i] = rnd.NextDouble(); } matlab.PutVector(testRHS, "testRHS"); MPIexchange <double[]> ResExchange = new MPIexchange <double[]>(MgMap, testRHS); ResExchange.TransceiveStartImReturn(); ResExchange.TransceiveFinish(0.0); int offset = MgMap.LocalLength; int g = 0; for (int rankCounter = 0; rankCounter < myMpisize; rankCounter++) { int rank_NoBlks = NoOfSchwzBlocks.MPIBroadcast(rankCounter); for (int iBlock = 0; iBlock < rank_NoBlks; iBlock++) { double[] SubVec; if (rankCounter == myMpiRank) { int LL = this.BlockIndices_Local[iBlock].Length; int LE; if (this.BlockIndices_External[iBlock] != null) { LE = this.BlockIndices_External[iBlock].Length; } else { LE = 0; } int L = LL + LE; SubVec = new double[L]; for (int i = 0; i < LL; i++) { SubVec[i] = testRHS[this.BlockIndices_Local[iBlock][i]]; } if (LE > 0) { for (int i = 0; i < LE; i++) { SubVec[i + LL] = ResExchange.Vector_Ext[this.BlockIndices_External[iBlock][i] - offset]; } } } else { SubVec = new double[0]; } matlab.PutVector(SubVec, "SubVec" + g); g++; } } for (int iGlbBlock = 0; iGlbBlock < GlobalNoOfBlocks; iGlbBlock++) { matlab.Cmd("RhsErr({0} + 1, 1) = norm( SubVec{0} - testRHS( BlockIdx{0} ), inf );", iGlbBlock); } double[] testX = new double[testRHS.Length]; MPIexchangeInverse <double[]> XExchange = new MPIexchangeInverse <double[]>(MgMap, testX); g = 0; for (int rankCounter = 0; rankCounter < myMpisize; rankCounter++) { int rank_NoBlks = NoOfSchwzBlocks.MPIBroadcast(rankCounter); for (int iBlock = 0; iBlock < rank_NoBlks; iBlock++) { if (rankCounter == myMpiRank) { int LL = this.BlockIndices_Local[iBlock].Length; int LE; if (this.BlockIndices_External[iBlock] != null) { LE = this.BlockIndices_External[iBlock].Length; } else { LE = 0; } int L = LL + LE; for (int i = 0; i < LL; i++) { testX[this.BlockIndices_Local[iBlock][i]] += (g + 1); } if (LE > 0) { for (int i = 0; i < LE; i++) { XExchange.Vector_Ext[this.BlockIndices_External[iBlock][i] - offset] += (g + 1); } } } else { //nop } g++; } } XExchange.TransceiveStartImReturn(); XExchange.TransceiveFinish(1.0); matlab.Cmd("testXref = zeros({0},1);", MgMap.TotalLength); for (int iGlbBlock = 0; iGlbBlock < GlobalNoOfBlocks; iGlbBlock++) { matlab.Cmd("testXref(BlockIdx{0},1) = testXref(BlockIdx{0},1) + ({0} + 1);", iGlbBlock); } matlab.PutVector(testX, "testX"); matlab.Cmd("testXErr = norm(testX - testXref, inf);"); MultidimensionalArray BlockErr = MultidimensionalArray.Create(GlobalNoOfBlocks, 1); MultidimensionalArray RhsErr = MultidimensionalArray.Create(GlobalNoOfBlocks, 1); MultidimensionalArray testXErr = MultidimensionalArray.Create(1, 1); matlab.GetMatrix(BlockErr, "BlockErr"); matlab.GetMatrix(RhsErr, "RhsErr"); matlab.GetMatrix(testXErr, "testXErr"); matlab.Execute(); for (int iGlbBlock = 0; iGlbBlock < GlobalNoOfBlocks; iGlbBlock++) { Console.WriteLine("Block #{0} Error (external? ) " + BlockErr[iGlbBlock, 0], iGlbBlock); Console.WriteLine("RHS #{0} Error " + RhsErr[iGlbBlock, 0], iGlbBlock); Debug.Assert(BlockErr[iGlbBlock, 0] == 0); Debug.Assert(RhsErr[iGlbBlock, 0] == 0); } Console.WriteLine("X Error " + testXErr[0, 0]); Debug.Assert(testXErr[0, 0] == 0.0); matlab.Dispose(); } #endif } }
object Wavefunction(float xmin, float xmax, int num_points, int num_elevel, float[] PE) { float HBAR = 6.62606957E-34f; float NM2M = 1E-9f; float EV2J = 1.6E-19f; float mass = 9.10938291E-31f; float C = (-HBAR * HBAR / (2 * mass)) / (NM2M * NM2M * EV2J); float[] xx = numeric.linspace(xmin, xmax, num_points - 2); float dx = (xmax - xmin) / (num_points); int factor = (int)Mathf.Round(C / (dx * dx)); int[] a = new int[1] { num_points - 2 }; float[][] melement = numeric.rep(a, -2 * factor); float[][] K = numeric.diag(melement[0]); for (int i = 0; i < num_points - 3; i++) { K[i][i + 1] = factor; K[i + 1][i] = factor; } //kinetic energy matrix //float[][] P = new float[][]; float[] P1 = ArrayTools.SubArray(PE, 1, num_points - 1); int shift = 0; float min_pe = Mathf.Min(P1); bool shift_flag = false; //The min PE val is a lowerbound on the eigenvalues(Gershgorin). //If too close to negative values shift eigenvalues to guarentee positivity. if (min_pe < numeric.epsilon) { shift = (int)Mathf.Round(Mathf.Abs(min_pe) + 1); shift_flag = true; } float[][] P = numeric.diag(P1); float[][] H = new float[K.Length][]; for (int i = 0; i < K.Length; i++) { H[i] = new float[K[i].Length]; for (int j = 0; j < K[i].Length; j++) { H[i][j] = K[i][j] + P[i][j]; } } if (shift_flag) { float[][] element = numeric.rep(a, shift); float[][] Hadd = numeric.diag(element[0]); for (int i = 0; i < H.Length; i++) { for (int j = 0; j < H[0].Length; j++) { H[i][j] = Hadd[i][j] + H[i][j]; } } } object[] eigen = (object[])numeric.svd(H); float[][] U = numeric.transpose((float[][])eigen[0]); float[] S = (float[])eigen[1]; if (shift_flag) { for (int i = 0; i < S.Length; i++) { S[i] = S[i] - shift; } } float[][] psi_array = new float[num_points - 2][]; for (int i = 0; i < num_points - 2; i++) { float[] psi = U[i]; ArrayTools.Push(psi, 0); ArrayTools.PushLast(psi, 0); float area = trapz(dx, prob(psi)); for (int j = 0; j < psi.Length; j++) { psi[j] = psi[j] / Mathf.Sqrt(area); } psi_array[i] = psi; } //Collect the desired number of energy levels. float[][] wave_eqs = new float[num_elevel][]; float[] eng_lvls = new float[num_elevel]; for (int i = 0; i < num_elevel; i++) { wave_eqs[i] = psi_array[num_points - 3 - i]; eng_lvls[i] = S[num_points - 3 - i]; } object[] obj = new object[2]; obj[0] = eng_lvls; obj[1] = wave_eqs; return(obj); }
public void ApplyToVector <I>(IList <I> input, IList <I[]> output, IPartitioning outputPartitioning) { using (new FuncTrace()) { Debug.Assert(DestGlobalId.Length == MappingIndex.Length); Debug.Assert(OldGlobalId.Length == MappingIndex.Length); int oldJ = DestGlobalId.Length; if (input.Count != oldJ) { throw new ArgumentException("Mismatch between input vector length and current data length."); } if (output.Count != outputPartitioning.LocalLength) { throw new ArgumentException("Length mismatch of output list and output partition."); } int j0Dest = outputPartitioning.i0; // keys: processors which should receive data from this processor Dictionary <int, ApplyToVector_Helper <I> > AllSendData = new Dictionary <int, ApplyToVector_Helper <I> >(); for (int j = 0; j < oldJ; j++) { I data_j = input[j]; foreach (int jDest in TargetIdx[j]) { if (outputPartitioning.IsInLocalRange(jDest)) { I[] destCollection = output[jDest - j0Dest]; ArrayTools.AddToArray(data_j, ref destCollection); output[jDest - j0Dest] = destCollection; } else { int targProc = outputPartitioning.FindProcess(jDest); ApplyToVector_Helper <I> dataTargPrc; if (!AllSendData.TryGetValue(targProc, out dataTargPrc)) { dataTargPrc = new ApplyToVector_Helper <I>(); AllSendData.Add(targProc, dataTargPrc); } dataTargPrc.TargetIndices.Add(jDest); dataTargPrc.Items.Add(data_j); } } } var AllRcvData = SerialisationMessenger.ExchangeData(AllSendData, outputPartitioning.MPI_Comm); foreach (var kv in AllRcvData) { int rcvProc = kv.Key; j0Dest = outputPartitioning.GetI0Offest(rcvProc); var TIdxs = kv.Value.TargetIndices; var TVals = kv.Value.Items; Debug.Assert(TIdxs.Count == TVals.Count); int L = TIdxs.Count; for (int l = 0; l < L; l++) { int idx = TIdxs[l] - j0Dest; Debug.Assert(outputPartitioning.IsInLocalRange(idx)); I[] destCollection = output[idx]; ArrayTools.AddToArray(TVals[idx], ref destCollection); output[idx] = destCollection; } } } }
static public IBM_Control IBMCylinderFlow(string _DbPath = null, int k = 2, bool only_channel = true, bool pardiso = true, int no_p = 1, int no_it = 1, bool load_Grid = false, string _GridGuid = null) { // int cells_x, int cells_yz IBM_Control C = new IBM_Control(); bool xPeriodic = false; int i = 2; const double BaseSize = 1.0; // basic database options // ====================== //C.DbPath = _DbPath; C.DbPath = @"\\dc1\userspace\stange\HiWi_database\PerformanceTests"; C.savetodb = true; bool restart = false; string restartSession = "67a29dcc-ade9-4704-b198-b3380e774f5a"; string restartGrid = "42e1ede0-40fc-4267-9d48-94c0397ac9a5"; bool startFromGivenGrid = true; string startGrid = "42e1ede0-40fc-4267-9d48-94c0397ac9a5"; switch (i) { case 1: C.MeshFactor = 1.258; // was 1.33 break; case 2: C.MeshFactor = 3.0; //1.77; //0.92; break; case 3: C.MeshFactor = 0.7; // was 07 break; default: throw new ApplicationException(); } if (pardiso) { if (only_channel) { C.SessionName = "2DChannel_Pardiso_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it; } else { C.SessionName = "Cylinder_Pardiso_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it; } } else { if (only_channel) { C.SessionName = "2DChannel_Mumps_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it; } else { C.SessionName = "Cylinder_Mumps_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it; } } C.saveperiod = 1; //C.SessionName = "Sphere_k" + k + "_h" + h+"Re100"; C.Tags.Add("Pardiso " + pardiso); C.Tags.Add("only channel " + only_channel); C.Tags.Add("k " + k); C.Tags.Add("no_p" + no_p); C.Tags.Add("run " + no_it); C.Tags.Add("MeshFactor " + C.MeshFactor); C.ProjectName = "FixedCylinderRe100_k" + i + "_CellAgglo02_penalty4_newMesh2"; C.ProjectDescription = "Cylinder"; // DG degrees // ========== C.FieldOptions.Add("VelocityX", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("VelocityY", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); //Console.WriteLine("Achtung: equal order!!!!"); C.FieldOptions.Add("Pressure", new FieldOpts() { Degree = k - 1, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("PhiDG", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Phi", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); // restart options // =============== if (restart) { C.RestartInfo = new Tuple <Guid, TimestepNumber>(new Guid(restartSession), -1); C.GridGuid = new Guid(restartGrid); } //grid and boundary conditions // ============================ // Initial Values // ============== double radius = 0.5; C.PhysicalParameters.rho_A = 1.0; C.PhysicalParameters.mu_A = 1.0 / 100.0; if (!restart) { if (!startFromGivenGrid) { C.GridFunc = delegate { var _xNodes1 = Grid1D.TanhSpacing(-2.0, -1.0, Convert.ToInt32(10.0 * C.MeshFactor), 0.5, false); //10 _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1)); var _xNodes2 = GenericBlas.Linspace(-1.0, 2.0, Convert.ToInt32(35.0 * C.MeshFactor)); //35 _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1)); var _xNodes3 = Grid1D.TanhSpacing(2.0, 20.0, Convert.ToInt32(60.0 * C.MeshFactor), 1.5, true); //60 var xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3); var _yNodes1 = Grid1D.TanhSpacing(-2.0, -1.0, Convert.ToInt32(7.0 * C.MeshFactor), 0.9, false); //7 _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1)); var _yNodes2 = GenericBlas.Linspace(-1.0, 1.0, Convert.ToInt32(25.0 * C.MeshFactor)); //25 _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1)); var _yNodes3 = Grid1D.TanhSpacing(1.0, 2.1, Convert.ToInt32(7.0 * C.MeshFactor), 1.1, true); //7 var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3); //double[] xNodes = GenericBlas.Linspace(0 * BaseSize, 22 * BaseSize, 25); //double[] yNodes = GenericBlas.Linspace(0 * BaseSize, 4.1 * BaseSize, 25); var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: xPeriodic); grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper"); grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower"); if (!xPeriodic) { grd.EdgeTagNames.Add(3, "Velocity_Inlet_left"); grd.EdgeTagNames.Add(4, "Pressure_Outlet_right"); } grd.DefineEdgeTags(delegate(double[] X) { byte et = 0; if (Math.Abs(X[1] - (-2.0 * BaseSize)) <= 1.0e-8) { et = 1; } if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8) { et = 2; } if (!xPeriodic && Math.Abs(X[0] - (-2.0 * BaseSize)) <= 1.0e-8) { et = 3; } if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8) { et = 4; } Debug.Assert(et != 0); return(et); }); Console.WriteLine("Cells: {0}", grd.NumberOfCells); return(grd); }; } else { C.GridGuid = new Guid(startGrid); } if (only_channel) { C.InitialValues_Evaluators.Add("Phi", X => - 1); } else { C.InitialValues_Evaluators.Add("Phi", X => - (X[0]).Pow2() + -(X[1]).Pow2() + radius.Pow2()); } //C.InitialValues.Add("Phi", X => -1); C.InitialValues_Evaluators.Add("VelocityX", X => 4.0 * 1.5 * (X[1] + 2.0) * (4.1 - (X[1] + 2.0)) / (4.1 * 4.1)); } //C.GridFunc = delegate { // // Box1 // var box1_p1 = new double[2] { -2, -2 }; // var box1_p2 = new double[2] { 20, 2.1 }; // var box1 = new GridBox(box1_p1, box1_p2, 46, 20); //k1: 70,25 ; k2: 46,20 ; k3: 35,15 // // Box2 // var box2_p1 = new double[2] { -2, -2 }; // var box2_p2 = new double[2] { 3, 2.1 }; // var box2 = new GridBox(box2_p1, box2_p2, 26, 40); //k1: 40,50 ; k2: 26,40; k3: 20, 30 // // Box3 // var box3_p1 = new double[2] { -2, -1 }; // var box3_p2 = new double[2] { 1, 1 }; // var box3 = new GridBox(box3_p1, box3_p2, 32, 38); //k1: 48,58 ; k2: 32,38; k3: 24, 30 // // Box4 // var box4_p1 = new double[2] { -0.7, -0.72 }; // var box4_p2 = new double[2] { 0.7, 0.7 }; // var box4 = new GridBox(box4_p1, box4_p2, 30, 56); //k1: 44,84 ; k2: 30,56; k3: 22, 42 // var grd = Grid2D.HangingNodes2D(box1, box2, box3,box4); // grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper"); // grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower"); // if (!xPeriodic) { // grd.EdgeTagNames.Add(3, "Velocity_Inlet_left"); // grd.EdgeTagNames.Add(4, "Pressure_Outlet_right"); // } // grd.DefineEdgeTags(delegate (double[] X) { // byte et = 0; // if (Math.Abs(X[1] - (-2 * BaseSize)) <= 1.0e-8) // et = 1; // if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8) // et = 2; // if (!xPeriodic && Math.Abs(X[0] - (-2 * BaseSize)) <= 1.0e-8) // et = 3; // if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8) // et = 4; // Debug.Assert(et != 0); // return et; // }); // Console.WriteLine("Cells: {0}", grd.NumberOfCells); // return grd; //}; C.AddBoundaryCondition("Velocity_Inlet_upper", "VelocityX", X => 0.0); C.AddBoundaryCondition("Velocity_Inlet_lower", "VelocityX", X => 0.0); //-(4 * 1.5 * X[1] * (4.1 - X[1]) / (4.1 * 4.1)) if (!xPeriodic) { C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX", X => (4.0 * 1.5 * (X[1] + 2.0) * (4.1 - (X[1] + 2.0)) / (4.1 * 4.1))); //C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX#A", X => 1); } C.AddBoundaryCondition("Pressure_Outlet_right"); //C.InitialValues.Add("Phi", X => phi(X, 0)); //C.InitialValues.Add("Phi", X => ((X[0] / (radius * BaseSize)) - mPx) * (X[0] / (radius * BaseSize)) - mPx) + ((X[1]) / (radius * BaseSize)) - 2.)Pow2() - radius.Pow2())); // quadratic form // ); //C.InitialValues.Add("VelocityX", delegate (double[] X) //{ // double x = X[0]; // double y = X[1]; // double R = Math.Sqrt((x + 1).Pow2() + y.Pow2()); // double xVel = 0; // if (R < 0.75) // { // xVel = 1; // } // return xVel; //}); //C.InitialValues.Add("VelocityY", delegate (double[] X) { // double x = X[0]; // double y = X[1]; // double R = Math.Sqrt((x + 1).Pow2() + (y).Pow2()); // double yVel = 0; // if (R < 0.75) { // yVel = 1; // } // return yVel; //}); // For restart //C.RestartInfo = new Tuple<Guid, TimestepNumber>(new Guid("8f5cfed9-31c7-4be8-aa56-e92e5348e08b"), 95); //C.GridGuid = new Guid("71ffc0c4-66aa-4762-b07e-45385f34b03f"); // Physical Parameters // =================== C.PhysicalParameters.IncludeConvection = true; // misc. solver options // ==================== C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2; C.AdvancedDiscretizationOptions.PenaltySafety = 4; C.LevelSetSmoothing = false; //C.option_solver = "direct"; C.MaxKrylovDim = 20; C.MaxSolverIterations = 50; C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite; //C.NoOfMultigridLevels = 0; if (pardiso) { C.whichSolver = DirectSolver._whichSolver.PARDISO; } else { C.whichSolver = DirectSolver._whichSolver.MUMPS; } // Timestepping // ============ C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.BDF2; double dt = 0.1; C.dtMax = dt; C.dtMin = dt; C.Endtime = 70; C.NoOfTimesteps = 10; // haben fertig... // =============== return(C); }
public static void DragCurve(Curve curve) /// Backup curve to return the removed nodes when dragging cursor returned to curve field { if (UI.current.layout) { return; } if (UI.current.optimizeElements && !UI.current.IsInWindow()) { return; } //moving bool isDragging = false; bool isReleased = false; int dragNum = -1; Curve.Node[] originalPoints = null; for (int i = 0; i < curve.points.Length; i++) { bool newDragging = false; bool newReleased = false; Vector2 newPos = DragPoint(curve, i, ref newDragging, ref newReleased); if (newDragging) { originalPoints = new Curve.Node[curve.points.Length]; //curve.GetPositions(); for (int p = 0; p < originalPoints.Length; p++) { originalPoints[p] = new Curve.Node(curve.points[p]); } curve.points[i].pos = newPos; } if (newDragging || newReleased) { dragNum = i; } isDragging = isDragging || newDragging; isReleased = isReleased || newReleased; } //adding if (ClickedNearCurve(curve)) { Vector2 addPos = ToCurve(UI.current.mousePos); int addedNum = AddPoint(curve, addPos); //starting drag DragPoint(curve, addedNum, ref isDragging, ref isReleased); //just to start drag } //removing if (isDragging) { //calc if node should be removed bool isRemoved = false; if (dragNum != 0 && dragNum != curve.points.Length - 1) //ignoring first and last { Vector2 pos = ToCell(curve.points[dragNum].pos); if (!Cell.current.InternalRect.Extended(10).Contains(pos)) { isRemoved = true; } } //removing if (isRemoved) { UI.current.MarkChanged(completeUndo: true); ArrayTools.RemoveAt(ref curve.points, dragNum); } //clamping if cursor is too close to the field to remove else { ClampPoint(curve, dragNum); } } //if returned dragging to field else if (DragDrop.obj != null && DragDrop.obj.GetType() == typeof((Curve, Curve.Node, int))) { (Curve curve, Curve.Node node, int num)dragObj = ((Curve, Curve.Node, int))DragDrop.obj; if (dragObj.curve == curve && !curve.points.Contains(dragObj.node)) { DragDrop.TryDrag(dragObj, UI.current.mousePos); //to make it repaint if (Cell.current.InternalRect.Extended(10).Contains(UI.current.mousePos)) { ArrayTools.Insert(ref curve.points, dragObj.num, dragObj.node); dragObj.node.pos = ToCurve(UI.current.mousePos); ClampPoint(dragObj.curve, dragObj.num); //this will place it between prev and next points } DragDrop.TryRelease(dragObj, UI.current.mousePos); //otherwise it will not be released forever } } if (Cell.current.valChanged) { curve.Refresh(); } }
void UpdateAgglom(bool ReplaceTop) { if (m_RequiredTimeLevels == 0) { m_Versions.Clear(); } if (m_RequiredTimeLevels == 0 && ReplaceTop == true) { throw new NotSupportedException(); } if (!ReplaceTop) { m_RequiredTimeLevels++; m_Versions.Add(m_LsTrk.Regions.Version); } else { m_Versions[m_Versions.Count - 1] = m_LsTrk.Regions.Version; } Debug.Assert(m_RequiredTimeLevels == m_Versions.Count); for (int i = 0; i < m_Versions.Count; i++) { if (m_Versions[m_Versions.Count - 1 - i] != m_LsTrk.RegionsHistory[1 - i].Version) { throw new ApplicationException("Internal Error, level-set-tracker history stack messed up."); // cheap test, also affordable in release } } double[] oldAggTrsh; if (m_RequiredTimeLevels > 1) { oldAggTrsh = new double[m_RequiredTimeLevels - 1]; ArrayTools.SetAll(oldAggTrsh, this.Config_AgglomerationThreshold); } else { oldAggTrsh = null; } Debug.Assert(m_LsTrk.PopulatedHistoryLength >= m_RequiredTimeLevels - 1); //#if DEBUG // if(m_RequiredTimeLevels > 1) { // Debug.Assert(m_OldSources != null); // } else { // m_OldSources = null; // m_OldVolumes = null; // } //#endif m_CurrentAgglomeration = m_LsTrk.GetAgglomerator(Config_SpeciesToCompute, Config_CutCellQuadratureOrder, this.Config_AgglomerationThreshold, AgglomerateNewborn: oldAggTrsh != null, AgglomerateDecased: (oldAggTrsh != null), ExceptionOnFailedAgglomeration: true, oldTs__AgglomerationTreshold: oldAggTrsh); //#if DEBUG // int[][] NewSources = new int[Config_SpeciesToCompute.Length][]; // { // for(int iSpc = 0; iSpc < NewSources.Length; iSpc++) { // var Spc = Config_SpeciesToCompute[iSpc]; // NewSources[iSpc] = m_CurrentAgglomeration.GetAgglomerator(Spc).AggInfo.SourceCells.ItemEnum.ToArray(); // } // } // double[][][] NewVolumes = new double[m_RequiredTimeLevels][][]; // for(int iTs = 0; iTs < m_RequiredTimeLevels; iTs++) { // NewVolumes[iTs] = new double[Config_SpeciesToCompute.Length][]; // for(int iSpc = 0; iSpc < NewSources.Length; iSpc++) { // var Spc = Config_SpeciesToCompute[iSpc]; // NewVolumes[iTs][iSpc] = m_LsTrk.GetXDGSpaceMetrics(Config_SpeciesToCompute, Config_CutCellQuadratureOrder, 1 - iTs).CutCellMetrics.CutCellVolumes[Spc].To1DArray(); // } // } // if(m_RequiredTimeLevels > 1) { // for(int iSpc = 0; iSpc < NewSources.Length; iSpc++) { // var Spc = Config_SpeciesToCompute[iSpc]; // int[] _OldSources_spc = m_OldSources[iSpc]; // int[] _NewSources_spc = NewSources[iSpc]; // Debug.Assert(_OldSources_spc.IsSubsetOf(_NewSources_spc)); // } // } // m_OldSources = NewSources; // m_OldVolumes = NewVolumes; //#endif //foreach (var spId in m_CurrentAgglomeration.SpeciesList) { // string SpName = m_LsTrk.GetSpeciesName(spId); // int NoOfAgg = m_CurrentAgglomeration.GetAgglomerator(spId).AggInfo.AgglomerationPairs.Length; // Console.WriteLine("Species {0}, time {2}, number of agglomerations: {1}", SpName, NoOfAgg, m_RequiredTimeLevels); //} }
/// <summary> /// Calculated topology of the grid, i.e creating the boundarySubgrids /// for each sub-grid /// </summary> protected void GetBoundaryTopology() { // NumOfSgrd - 1, because largest grid (id=0) don't need a boundary cells BoundaryTopology = new int[CurrentClustering.NumberOfClusters - 1, gridData.iLogicalCells.NoOfLocalUpdatedCells]; ArrayTools.SetAll(BoundaryTopology, -1); BoundarySgrds = new SubGrid[CurrentClustering.NumberOfClusters - 1]; jSub2jCell = new int[CurrentClustering.NumberOfClusters - 1][]; int[][] LocalCells2SubgridIndex = new int[CurrentClustering.NumberOfClusters][]; BitArray[] SgrdWithGhostCells = new BitArray[CurrentClustering.NumberOfClusters]; // prepare the calculation and save temporarily all array which involve MPI communication for (int id = 0; id < CurrentClustering.NumberOfClusters; id++) { LocalCells2SubgridIndex[id] = CurrentClustering.Clusters[id].LocalCellIndex2SubgridIndex; SgrdWithGhostCells[id] = CurrentClustering.Clusters[id].VolumeMask.GetBitMaskWithExternal(); } for (int id = 1; id < CurrentClustering.NumberOfClusters; id++) { SubGrid sgrd = CurrentClustering.Clusters[id]; BitArray BoBA = new BitArray(gridData.iLogicalCells.NoOfLocalUpdatedCells); //BitArray SgrdWithGhostCell = sgrd.VolumeMask.GetBitMaskWithExternal(); //int[] LocalCellIndex2SubgridIndex = sgrd.LocalCellIndex2SubgridIndex; foreach (BoSSS.Foundation.Grid.Chunk chunk in sgrd.BoundaryEdgesMask) { foreach (int edge in chunk.Elements) { int cell1 = gridData.iLogicalEdges.CellIndices[edge, 0]; int cell2 = gridData.iLogicalEdges.CellIndices[edge, 1]; if (cell2 >= gridData.iLogicalCells.NoOfLocalUpdatedCells) //special case: cell2 is "ghost-cell" at MPI border { if (SgrdWithGhostCells[id][cell2]) { int gridId = GetClusterIDOf(cell1, ABevolver); if (gridId != -1) // cell is not in void area of IBM { BoundaryTopology[id - 1, cell1] = gridId; BoBA[cell1] = true; } } } else if (cell1 >= 0 && cell2 >= 0 && LocalCells2SubgridIndex[id][cell1] >= 0 && LocalCells2SubgridIndex[id][cell2] < 0) { //BoT[id - 1, cell2] = getSgrdIdOf(cell2, LocalCells2SubgridIndex); //BoBA[cell2] = true; int gridId = GetClusterIDOf(cell2, ABevolver); if (gridId != -1) // cell is not in void area of IBM { BoundaryTopology[id - 1, cell2] = gridId; BoBA[cell2] = true; } } else if (cell1 >= 0 && cell2 >= 0 && LocalCells2SubgridIndex[id][cell2] >= 0 && LocalCells2SubgridIndex[id][cell1] < 0) { //BoT[id - 1, cell1] = getSgrdIdOf(cell1, LocalCells2SubgridIndex); //BoBA[cell1] = true; int gridId = GetClusterIDOf(cell1, ABevolver); if (gridId != -1) // cell is not in void area of IBM { BoundaryTopology[id - 1, cell1] = gridId; BoBA[cell1] = true; } } } } //Creating the Boundary sub-grid BoundarySgrds[id - 1] = new SubGrid(new CellMask(gridData, BoBA)); jSub2jCell[id - 1] = BoundarySgrds[id - 1].SubgridIndex2LocalCellIndex; } // Debugging the boundary topology with MPI //int ii = 0; //SgrdField.Clear(); //foreach (SubGrid Sgrd in BoSgrd) { // foreach (BoSSS.Foundation.Grid.Chunk chunk in Sgrd.VolumeMask) { // foreach (int cell in chunk.Elements) { // SgrdField.SetMeanValue(cell, ii + 1); // } // } // ii++; //} }
/// <summary> /// /// </summary> public void AssembleMatrix_Timestepper <T>( int CutCellQuadOrder, BlockMsrMatrix OpMatrix, double[] OpAffine, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, IEnumerable <T> CurrentState, VectorField <SinglePhaseField> SurfaceForce, VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature, UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping, double time, IEnumerable <T> CoupledCurrentState = null, IEnumerable <T> CoupledParams = null) where T : DGField { if (ColMapping.BasisS.Count != this.Op.DomainVar.Count) { throw new ArgumentException(); } if (RowMapping.BasisS.Count != this.Op.CodomainVar.Count) { throw new ArgumentException(); } // check: var Tracker = this.LsTrk; int D = Tracker.GridDat.SpatialDimension; if (CurrentState != null && CurrentState.Count() != (D + 1)) { throw new ArgumentException(); } if (OpMatrix == null && CurrentState == null) { throw new ArgumentException(); } DGField[] U0; if (CurrentState != null) { U0 = CurrentState.Take(D).ToArray(); } else { U0 = null; } LevelSet Phi = (LevelSet)(Tracker.LevelSets[0]); SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray(); IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea; // advanced settings for the navier slip boundary condition // ======================================================== CellMask SlipArea; switch (this.dntParams.GNBC_Localization) { case NavierSlip_Localization.Bulk: { SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask; break; } case NavierSlip_Localization.ContactLine: { SlipArea = null; break; } case NavierSlip_Localization.Nearband: { SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth)); break; } case NavierSlip_Localization.Prescribed: { throw new NotImplementedException(); } default: throw new ArgumentException(); } MultidimensionalArray SlipLengths; SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs(); SlipLengths.Clear(); //SlipLengths.AccConstant(-1.0); if (SlipArea != null) { foreach (Chunk cnk in SlipArea) { for (int i = cnk.i0; i < cnk.JE; i++) { switch (this.dntParams.GNBC_SlipLength) { case NavierSlip_SlipLength.hmin_DG: { int degU = ColMapping.BasisS.ToArray()[0].Degree; SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1); break; } case NavierSlip_SlipLength.hmin_Grid: { SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i]; break; } case NavierSlip_SlipLength.Prescribed_SlipLength: { SlipLengths[i] = this.physParams.sliplength; break; } case NavierSlip_SlipLength.Prescribed_Beta: { SlipLengths[i] = -1.0; break; } } } } } // parameter assembly // ================== // normals: SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions. if (this.NormalsRequired) { if (LevelSetGradient == null) { LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory); LevelSetGradient.Gradient(1.0, Phi); } Normals = LevelSetGradient.ToArray(); } else { Normals = new SinglePhaseField[D]; } // curvature: SinglePhaseField Curvature; if (this.CurvatureRequired) { Curvature = ExternalyProvidedCurvature; } else { Curvature = null; } // linearization velocity: DGField[] U0_U0mean; if (this.U0meanrequired) { XDGBasis U0meanBasis = new XDGBasis(Tracker, 0); VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory); U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean); } else { U0_U0mean = new DGField[2 * D]; } // Temperature gradient for evaporation VectorField <DGField> GradTemp = new VectorField <DGField>(D, new XDGBasis(LsTrk, 0), XDGField.Factory); if (CoupledCurrentState != null) { DGField Temp = CoupledCurrentState.ToArray()[0]; GradTemp = new VectorField <DGField>(D, Temp.Basis, "GradTemp", XDGField.Factory); XNSEUtils.ComputeGradientForParam(Temp, GradTemp, this.LsTrk); } // concatenate everything var Params = ArrayTools.Cat <DGField>( U0_U0mean, Curvature, ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]), Normals, ((evaporation) ? GradTemp.ToArray() : new SinglePhaseField[D]), ((evaporation) ? CoupledCurrentState.ToArray <DGField>() : new SinglePhaseField[1]), ((evaporation) ? CoupledParams.ToArray <DGField>() : new SinglePhaseField[1])); //((evaporation) ? GradTemp.ToArray() : new SinglePhaseField[D])); // linearization velocity: if (this.U0meanrequired) { VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray()); U0mean.Clear(); if (this.physParams.IncludeConvection) { ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper); } } // assemble the matrix & affine vector // =================================== // compute matrix if (OpMatrix != null) { //Op.ComputeMatrixEx(Tracker, // ColMapping, Params, RowMapping, // OpMatrix, OpAffine, false, time, true, // AgglomeratedCellLengthScales, // InterfaceLengths, SlipLengths, // SpcToCompute); 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 (evaporation) { BitArray EvapMicroRegion = new BitArray(this.LsTrk.GridDat.Cells.Count);; // this.LsTrk.GridDat.GetBoundaryCells().GetBitMask(); mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion); } } 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); #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 } 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 (evaporation) { BitArray EvapMicroRegion = new BitArray(this.LsTrk.GridDat.Cells.Count); eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion); } } 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); } // 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."); * } */ }
private void DrawGraph () { bool isMini = IsMini; //background float gridColor = !StylesCache.isPro ? 0.45f : 0.12f; float gridBackgroundColor = !StylesCache.isPro ? 0.5f : 0.15f; #if MM_DEBUG if (!graph.debugGraphBackground) { gridColor = graph.debugGraphBackColor; gridBackgroundColor = graph.debugGraphBackColor; } #endif Draw.StaticGrid( displayRect: new Rect(0, 0, Screen.width, Screen.height-toolbarSize), cellSize:32, color:new Color(gridColor,gridColor,gridColor), background:new Color(gridBackgroundColor,gridBackgroundColor,gridBackgroundColor), fadeWithZoom:true); #if MM_DEBUG if (graph.drawInSceneView) { using (Cell.Full) DrawSceneView(); } #endif //drawing groups foreach (Group group in graph.groups) using (Cell.Custom(group.guiPos.x, group.guiPos.y, group.guiSize.x, group.guiSize.y)) { GroupDraw.DragGroup(group, graph.generators); GroupDraw.DrawGroup(group, isMini:isMini); } //dragging nodes foreach (Generator gen in graph.generators) GeneratorDraw.DragGenerator(gen, selected); //drawing links //using (Timer.Start("Links")) if (!UI.current.layout) { List<(IInlet<object> inlet, IOutlet<object> outlet)> linksToRemove = null; foreach (var kvp in graph.links) { IInlet<object> inlet = kvp.Key; IOutlet<object> outlet = kvp.Value; Cell outletCell = UI.current.cellObjs.GetCell(outlet, "Outlet"); Cell inletCell = UI.current.cellObjs.GetCell(inlet, "Inlet"); if (outletCell == null || inletCell == null) { Debug.LogError("Could not find a cell for inlet/outlet. Removing link"); if (linksToRemove == null) linksToRemove = new List<(IInlet<object> inlet, IOutlet<object> outlet)>(); linksToRemove.Add((inlet,outlet)); continue; } GeneratorDraw.DrawLink( GeneratorDraw.StartCellLinkpos(outletCell), GeneratorDraw.EndCellLinkpos(inletCell), GeneratorDraw.GetLinkColor(inlet), width:!isMini ? 4f : 6f ); } if (linksToRemove != null) foreach ((IInlet<object> inlet, IOutlet<object> outlet) in linksToRemove) { graph.UnlinkInlet(inlet); graph.UnlinkOutlet(outlet); } } //removing null generators (for test purpose) for (int n=graph.generators.Length-1; n>=0; n--) { if (graph.generators[n] == null) ArrayTools.RemoveAt(ref graph.generators, n); } //drawing generators //using (Timer.Start("Generators")) float nodeWidth = !isMini ? GeneratorDraw.nodeWidth : GeneratorDraw.miniWidth; foreach (Generator gen in graph.generators) using (Cell.Custom(gen.guiPosition.x, gen.guiPosition.y, nodeWidth, 0)) GeneratorDraw.DrawGeneratorOrPortal(gen, graph, isMini:isMini, selected.Contains(gen)); //de-selecting nodes (after dragging and drawing since using drag obj) if (!UI.current.layout) { GeneratorDraw.SelectGenerators(selected, shiftForSingleSelect:!isMini); GeneratorDraw.DeselectGenerators(selected); //and deselected always without shift } //add/remove button //using (Timer.Start("AddRemove")) using (Cell.Full) DragDrawAddRemove(); //right click menu (should have access to cellObjs) if (!UI.current.layout && Event.current.type == EventType.MouseDown && Event.current.button == 1) RightClick.DrawRightClickItems(graphUI, graphUI.mousePos, graph); //create menu on space if (!UI.current.layout && Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Space && !Event.current.shift) CreateRightClick.DrawCreateItems(graphUI.mousePos, graph); //delete selected generators if (selected!=null && selected.Count!=0 && Event.current.type==EventType.KeyDown && Event.current.keyCode==KeyCode.Delete) GraphEditorActions.RemoveGenerators(graph, selected); }
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> /// computes the injector for multigrid level 1 /// </summary> /// <seealso cref="BuildInjector_Lv2andup"/> private static MultidimensionalArray[] BuildInjector_Lv1( Basis maxDgBasis, int Np, MultidimensionalArray InjectorsBase, bool[] InjectorsBaseReady, int Jagg, int[][] Ag2Pt, int[][] C2F) { using (new FuncTrace()) { MultidimensionalArray ortho = MultidimensionalArray.Create(Np, Np); MultidimensionalArray[] Injectors_iLevel = new MultidimensionalArray[Jagg]; #if DEBUG { int Jbase = InjectorsBase.GetLength(0); if (InjectorsBase.GetLength(1) != InjectorsBase.GetLength(2)) { throw new ArgumentException(); } int N = InjectorsBase.GetLength(1); var check = MultidimensionalArray.Create(N, N); for (int j = 0; j < Jbase; j++) { check.Clear(); check.AccEye(1.0); check.Acc(-1.0, InjectorsBase.ExtractSubArrayShallow(j, -1, -1)); if (check.InfNorm() != 0.0) { throw new ArgumentException(); } } } #endif var iLPar = maxDgBasis.GridDat.iLogicalCells; // cells of *parent* grid for (int j = 0; j < Jagg; j++) // loop over aggregate cells { Debug.Assert(ArrayTools.ListEquals(Ag2Pt[j], C2F[j])); int[] compCell = Ag2Pt[j]; int I = compCell.Length; int iRoot = -1; double maxSize = -1.0; for (int i = 0; i < I; i++) { double sz = iLPar.GetCellVolume(compCell[i]); if (sz <= 0.0) { throw new ArithmeticException("found cell with non-positive volume."); } if (sz > maxSize) { iRoot = i; maxSize = sz; } } //var gdat = ((maxDgBasis.GridDat) as Classic.GridData); //double[] Sizes = compCell.Select(jPart => gdat.iLogicalCells.GetCellVolume(jPart)).ToArray(); Injectors_iLevel[j] = MultidimensionalArray.Create(I, Np, Np); if (I > 1) { // compute extrapolation int[,] CellPairs = new int[I - 1, 2]; int cnt = 0; for (int i = 0; i < I; i++) { if (i != iRoot) { CellPairs[cnt, 0] = compCell[iRoot]; CellPairs[cnt, 1] = compCell[i]; Debug.Assert(CellPairs[cnt, 0] != CellPairs[cnt, 1]); cnt++; } } //cnt = 0; //for (int i = 0; i < I - 1; i++) { // CellPairs[cnt, 0] = compCell[0]; // CellPairs[cnt, 1] = compCell[i + 1]; // cnt++; //} var ExpolMtx = MultidimensionalArray.Create(I, Np, Np); maxDgBasis.GetExtrapolationMatrices(CellPairs, ExpolMtx.ExtractSubArrayShallow(new int[] { 1, 0, 0 }, new int[] { I - 1, Np - 1, Np - 1 })); for (int i = 0; i < iRoot; i++) { var M2 = ExpolMtx.ExtractSubArrayShallow(i, -1, -1); var M1 = ExpolMtx.ExtractSubArrayShallow(i + 1, -1, -1); M2.Set(M1); } for (int n = 0; n < Np; n++) { for (int m = 0; m < Np; m++) { ExpolMtx[iRoot, n, m] = n == m ? 1.0 : 0.0; } } // Compute intermediate mass matrix var MMtemp = MultidimensionalArray.Create(Np, Np); MMtemp.Multiply(1.0, ExpolMtx, ExpolMtx, 0.0, "nm", "iln", "ilm"); // orthonormalize //try { MMtemp.SymmetricLDLInversion(ortho, null); // ortho is output, will be overwritten //} catch (ArithmeticException ae) { // PlotScheisse(gdat.Grid, compCell); //} Injectors_iLevel[j].Multiply(1.0, ExpolMtx, ortho, 0.0, "inm", "ink", "km"); } else { Injectors_iLevel[j].ExtractSubArrayShallow(0, -1, -1).AccEye(1.0); } // base level injector var injBase = InjectorsBase.ExtractSubArrayShallow(compCell[0], -1, -1); injBase.Set(Injectors_iLevel[j].ExtractSubArrayShallow(0, -1, -1)); Debug.Assert(InjectorsBaseReady[compCell[0]]); for (int i = 1; i < I; i++) { InjectorsBaseReady[compCell[i]] = false; } } return(Injectors_iLevel); } }
public void Init(int ReqDegree) { if (ReqDegree < 0) { throw new ArgumentOutOfRangeException(); } if (ReqDegree <= MaxSupportedDegree) { return; } var aGdat = m_owner.AncestorGrid; Basis maxDGbasis = new Basis(aGdat, ReqDegree); int Np = maxDGbasis.Length; int Jbase = aGdat.Cells.NoOfLocalUpdatedCells; int Jagg = m_owner.iLogicalCells.NoOfLocalUpdatedCells; int[][] Ag2Pt = m_owner.iLogicalCells.AggregateCellToParts; int[][] C2F = m_owner.jCellCoarse2jCellFine; if (m_owner.ParentGrid is AggregationGridData) { var agParrent = m_owner.ParentGrid as AggregationGridData; int[][] Ag2Pt_Fine = agParrent.iLogicalCells.AggregateCellToParts; agParrent.m_ChefBasis.Init(MaxSupportedDegree); if (ReqDegree == agParrent.m_ChefBasis.MaxSupportedDegree) { this.InjectorsBase = agParrent.m_ChefBasis.InjectorsBase.CloneAs(); } else { this.InjectorsBase = agParrent.m_ChefBasis.InjectorsBase.ExtractSubArrayShallow(new int[] { 0, 0, 0 }, new int[] { Jbase - 1, Np - 1, Np - 1 }).CloneAs(); } this.InjectorsBaseReady = agParrent.m_ChefBasis.InjectorsBaseReady.CloneAs(); this.Injectors = BuildInjector_Lv2andup(maxDGbasis, Np, this.InjectorsBase, this.InjectorsBaseReady, Jagg, Ag2Pt_Fine, C2F); } else if (m_owner.ParentGrid is Classic.GridData) { // this is level 0 var agParrent = m_owner.ParentGrid as Classic.GridData; this.InjectorsBase = MultidimensionalArray.Create(Jbase, Np, Np); this.InjectorsBaseReady = new bool[Jbase]; ArrayTools.SetAll(this.InjectorsBaseReady, true); for (int j = 0; j < Jbase; j++) { this.InjectorsBase.ExtractSubArrayShallow(j, -1, -1).AccEye(1.0); } if (IsCloneOfAncestor()) { //this.Injectors = BuildInjector_Lv1(maxDGbasis, Np, this.InjectorsBase, this.InjectorsBaseReady, Jagg, Ag2Pt, C2F); // nop } else { this.Injectors = BuildInjector_Lv1(maxDGbasis, Np, this.InjectorsBase, this.InjectorsBaseReady, Jagg, Ag2Pt, C2F); //this.Injectors = BuildInjector_Lv2andup(maxDGbasis, Np, this.InjectorsBase, this.InjectorsBaseReady, Jagg, Ag2Pt_Fine, C2F); } } else { throw new NotSupportedException("dont know what to do"); } MaxSupportedDegree = ReqDegree; }
public void GetOutDegree_LongLine_IsCorrect() { var g = new DependencyGraph <int>(i => i == 5 ? new[] { 12, 4 } : i <= 0 ? ArrayTools.Empty <int>() : new[] { i - 1 }); Assert.That(g.GetOutDegree(5), Is.EqualTo(2)); }
/// <summary> /// Updates all columns related to convergence plots /// </summary> public void Update() { // Get all sessions which are successfully terminated // ================================================== var SuccSessions = owner.Sessions.Where(sess => sess.SuccessfulTermination == true).ToArray(); // Group the sessions according to polynomial degree // ================================================= System.Func <int[], int[], bool> eqFunc = (A, B) => ArrayTools.AreEqual(A, B); var comp = eqFunc.ToEqualityComparer(); var SessionGroups = SuccSessions.GroupBy(GetDGDegreeKey, comp).ToArray(); // Spatial convergence for each session group // ========================================== // intermediate result storage // 1st key: Field name // 2nd key: session name // value: error norm var Errors = new Dictionary <string, Dictionary <Guid, double> >(); foreach (IEnumerable <ISessionInfo> spatialSeries in SessionGroups) { if (spatialSeries.Count() <= 1) { continue; } ITimestepInfo[] tsiS = spatialSeries.Select(sess => sess.Timesteps.Last()).ToArray(); // find DG field identifications which are present in _all_ timesteps var commonFieldIds = new HashSet <string>(); foreach (var fi in tsiS[0].FieldInitializers) { string id = fi.Identification; bool containedInOthers = true; foreach (var tsi in tsiS.Skip(1)) { if (tsi.FieldInitializers.Where(fii => fii.Identification == id).Count() <= 0) { containedInOthers = false; } } if (containedInOthers) { commonFieldIds.Add(id); } } string[] fieldIds = commonFieldIds.ToArray(); // compute L2-errors DGFieldComparison.ComputeErrors(fieldIds, tsiS, out double[] hS, out var DOFs, out var ERRs, out var tsiIdS); // record errors foreach (var id in fieldIds) { Dictionary <Guid, double> err_id; if (!Errors.TryGetValue(id, out err_id)) { err_id = new Dictionary <Guid, double>(); Errors.Add(id, err_id); } for (int iGrd = 0; iGrd < hS.Length; iGrd++) { ITimestepInfo tsi = tsiS.Single(t => t.ID == tsiIdS[iGrd]); ISessionInfo sess = tsi.Session; err_id.Add(sess.ID, ERRs[id][iGrd]); } } } // Set L2 error columns in session table // ===================================== foreach (string fieldName in Errors.Keys) { string colName = "L2Error_" + fieldName; if (owner.AdditionalSessionTableColums.ContainsKey(colName)) { owner.AdditionalSessionTableColums.Remove(colName); } var ErrorsCol = Errors[fieldName]; owner.AdditionalSessionTableColums.Add(colName, delegate(ISessionInfo s) { object ret = 0.0; if (ErrorsCol.ContainsKey(s.ID)) { ret = ErrorsCol[s.ID]; } return(ret); }); } }
public OperatorFactory( OperatorConfiguration config, LevelSetTracker _LsTrk, int _HMFdegree, int degU, IncompressibleMultiphaseBoundaryCondMap BcMap, bool _movingmesh, bool _evaporation, bool _staticInt) { // variable names // ============== D = _LsTrk.GridDat.SpatialDimension; this.LsTrk = _LsTrk; //this.momentFittingVariant = momentFittingVariant; this.HMFDegree = _HMFdegree; this.dntParams = config.dntParams.CloneAs(); this.physParams = config.physParams.CloneAs(); this.UseExtendedVelocity = config.UseXDG4Velocity; this.movingmesh = _movingmesh; this.evaporation = _evaporation; // test input // ========== { if (config.DomBlocks.GetLength(0) != 2 || config.CodBlocks.GetLength(0) != 2) { throw new ArgumentException(); } if (config.physParams.mu_A == 0.0 && config.physParams.mu_B == 0.0) { muIs0 = true; } else { if (config.physParams.mu_A <= 0) { throw new ArgumentException(); } if (config.physParams.mu_B <= 0) { throw new ArgumentException(); } } if (config.physParams.rho_A <= 0) { throw new ArgumentException(); } if (config.physParams.rho_B <= 0) { throw new ArgumentException(); } if (_LsTrk.SpeciesNames.Count != 2) { throw new ArgumentException(); } if (!(_LsTrk.SpeciesNames.Contains("A") && _LsTrk.SpeciesNames.Contains("B"))) { throw new ArgumentException(); } } // full operator: CodName = ((new string[] { "momX", "momY", "momZ" }).GetSubVector(0, D)).Cat("div"); Params = ArrayTools.Cat( VariableNames.Velocity0Vector(D), VariableNames.Velocity0MeanVector(D), "Curvature", (new string[] { "surfForceX", "surfForceY", "surfForceZ" }).GetSubVector(0, D), (new string[] { "NX", "NY", "NZ" }).GetSubVector(0, D), (new string[] { "GradTempX", "GradTempY", "GradTempZ" }.GetSubVector(0, D)), VariableNames.Temperature, "DisjoiningPressure"); DomName = ArrayTools.Cat(VariableNames.VelocityVector(D), VariableNames.Pressure); // selected part: if (config.CodBlocks[0]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, D)); } if (config.CodBlocks[1]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D, 1)); } if (config.DomBlocks[0]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, D)); } if (config.DomBlocks[1]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D, 1)); } muA = config.physParams.mu_A; muB = config.physParams.mu_B; rhoA = config.physParams.rho_A; rhoB = config.physParams.rho_B; sigma = config.physParams.Sigma; MatInt = !evaporation; double kA = 0.0; double kB = 0.0; double hVapA = 0.0; double hVapB = 0.0; double Tsat = 0.0; double R_int = 0.0; double p_c = 0.0; if (evaporation) { kA = config.thermParams.k_A; kB = config.thermParams.k_B; hVapA = config.thermParams.hVap_A; hVapB = config.thermParams.hVap_B; Tsat = config.thermParams.T_sat; p_c = config.thermParams.pc; //double T_intMin = 0.0; double f = config.thermParams.fc; double R = config.thermParams.Rc; //double pc = config.thermParams.pc; if (config.thermParams.hVap_A > 0 && config.thermParams.hVap_B < 0) { R_int = ((2.0 - f) / (2 * f)) * Tsat * Math.Sqrt(2 * Math.PI * R * Tsat) / (rhoB * hVapA.Pow2()); //T_intMin = Tsat * (1 + (pc / (rhoA * hVapA.Pow2()))); } else if (config.thermParams.hVap_A < 0 && config.thermParams.hVap_B > 0) { R_int = ((2.0 - f) / (2 * f)) * Tsat * Math.Sqrt(2 * Math.PI * R * Tsat) / (rhoA * hVapB.Pow2()); //T_intMin = Tsat * (1 + (pc / (rhoB * hVapB.Pow2()))); } this.CurvatureRequired = true; } //if (!MatInt) // throw new NotSupportedException("Non-Material interface is NOT tested!"); // create Operator // =============== m_OP = new XSpatialOperator(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree); // build the operator // ================== { // Momentum equation // ================= if (config.physParams.IncludeConvection && config.Transport) { for (int d = 0; d < D; d++) { var comps = m_OP.EquationComponents[CodName[d]]; // convective part: // variante 1: double LFFA = config.dntParams.LFFA; double LFFB = config.dntParams.LFFB; var conv = new Operator.Convection.ConvectionInBulk_LLF(D, BcMap, d, rhoA, rhoB, LFFA, LFFB, LsTrk); comps.Add(conv); // Bulk component comps.Add(new Operator.Convection.ConvectionAtLevelSet_LLF(d, D, LsTrk, rhoA, rhoB, LFFA, LFFB, config.physParams.Material, BcMap, movingmesh)); // LevelSet component //comps.Add(new Operator.Convection.ConvectionAtLevelSet_weightedLLF(d, D, LsTrk, rhoA, rhoB, LFFA, LFFB, BcMap, movingmesh)); // LevelSet component if (evaporation) { //comps.Add(new Operator.Convection.ConvectionAtLevelSet_Divergence(d, D, LsTrk, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti, kA, kB, hVapA, R_int, Tsat, sigma, p_c)); //comps.Add(new Operator.Convection.ConvectionAtLevelSet_nonMaterialLLF(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c)); //comps.Add(new Operator.Convection.ConvectionAtLevelSet_nonMaterial(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c)); } // variante 3: //var convA = new LocalConvection(D, d, rhoA, rhoB, this.config.varMode, LsTrk); //XOP.OnIntegratingBulk += convA.SetParameter; //comps.Add(convA); //////var convB = new LocalConvection2(D, d, rhoA, rhoB, varMode, LsTrk); // macht Bum-Bum! ////XOP.OnIntegratingBulk += convB.SetParameter; ////comps.Add(convB); } this.U0meanrequired = true; } // pressure gradient // ================= if (config.PressureGradient) { for (int d = 0; d < D; d++) { var comps = m_OP.EquationComponents[CodName[d]]; var pres = new Operator.Pressure.PressureInBulk(d, BcMap); comps.Add(pres); //if (!MatInt) // throw new NotSupportedException("New Style pressure coupling does not support non-material interface."); var presLs = new Operator.Pressure.PressureFormAtLevelSet(d, D, LsTrk); //, dntParams.UseWeightedAverages, muA, muB); comps.Add(presLs); //if (evaporation) { // var presLSGen = new Operator.Pressure.GeneralizedPressureFormAtLevelSet(d, D, LsTrk, config.thermParams.p_sat, hVapA); // comps.Add(presLSGen); //} } } // viscous operator // ================ if (config.Viscous && !muIs0) { for (int d = 0; d < D; d++) { var comps = m_OP.EquationComponents[CodName[d]]; // viscous part: //double _D = D; //double penalty_mul = dntParams.PenaltySafety; //double _p = degU; //double penalty_base = (_p + 1) * (_p + _D) / _D; //double penalty = penalty_base * penalty_mul; double penalty = dntParams.PenaltySafety; switch (dntParams.ViscosityMode) { case ViscosityMode.Standard: { // Bulk operator: var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB); // , _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B); comps.Add(Visc); if (dntParams.UseGhostPenalties) { var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB); m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty); } // Level-Set operator: comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, true)); break; } case ViscosityMode.TransposeTermMissing: { // Bulk operator: var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB); comps.Add(Visc); if (dntParams.UseGhostPenalties) { var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB); m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty); } // Level-Set operator: comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, false)); break; } case ViscosityMode.ExplicitTransformation: { // Bulk operator var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB); comps.Add(Visc); if (dntParams.UseGhostPenalties) { var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB); m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty); } //Level-Set operator: //comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Explicit(d, D, LsTrk, penalty, muA, muB)); throw new NotSupportedException("Beim refact rausgeflogen, braucht eh kein Mensch. fk, 08jan16."); //break; } case ViscosityMode.FullySymmetric: { // Bulk operator var Visc1 = new Operator.Viscosity.ViscosityInBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB, _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B); var Visc2 = new Operator.Viscosity.ViscosityInBulk_GradUtranspTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB, _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B); //var Visc3 = new Operator.Viscosity.ViscosityInBulk_divTerm(dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB); comps.Add(Visc1); comps.Add(Visc2); //comps.Add(Visc3); if (dntParams.UseGhostPenalties) { var Visc1Penalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm( penalty, 0.0, BcMap, d, D, muA, muB); var Visc2Penalty = new Operator.Viscosity.ViscosityInBulk_GradUtranspTerm( penalty, 0.0, BcMap, d, D, muA, muB); //var Visc3Penalty = new Operator.Viscosity.ViscosityInBulk_divTerm( // penalty, 0.0, // BcMap, d, D, muA, muB); //m_OP.OnIntegratingBulk += Visc3Penalty.SetParameter; m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(Visc1Penalty); m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(Visc2Penalty); //m_OP.AndresHint.EquationComponents[CodName[d]].Add(Visc3Penalty); } // Level-Set operator comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_FullySymmetric(LsTrk, muA, muB, penalty, d, _staticInt, dntParams.UseWeightedAverages)); if (this.evaporation) { comps.Add(new Operator.Viscosity.GeneralizedViscosityAtLevelSet_FullySymmetric(LsTrk, muA, muB, penalty, d, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c)); } break; } default: throw new NotImplementedException(); } } } // Continuum equation // ================== if (config.continuity) { for (int d = 0; d < D; d++) { var src = new Operator.Continuity.DivergenceInBulk_Volume(d, D, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti); var flx = new Operator.Continuity.DivergenceInBulk_Edge(d, BcMap, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti); m_OP.EquationComponents["div"].Add(flx); m_OP.EquationComponents["div"].Add(src); } var divPen = new Operator.Continuity.DivergenceAtLevelSet(D, LsTrk, rhoA, rhoB, MatInt, config.dntParams.ContiSign, config.dntParams.RescaleConti, _staticInt); //, dntParams.UseWeightedAverages, muA, muB); m_OP.EquationComponents["div"].Add(divPen); if (evaporation) { var divPenGen = new Operator.Continuity.GeneralizedDivergenceAtLevelSet(D, LsTrk, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti, kA, kB, hVapA, R_int, Tsat, sigma, p_c); m_OP.EquationComponents["div"].Add(divPenGen); } //// pressure stabilization //if (this.config.PressureStab) { // Console.WriteLine("Pressure Stabilization active."); //var pStabi = new PressureStabilization(0.0001, 0.0001); // m_OP.OnIntegratingBulk += pStabi.SetParameter; // m_OP.EquationComponents["div"].Add(pStabi); ////var pStabiLS = new PressureStabilizationAtLevelSet(D, LsTrk, rhoA, muA, rhoB, muB, sigma, this.config.varMode, MatInt); // //XOP.EquationComponents["div"].Add(pStabiLS); //} else { // Console.WriteLine("Pressure Stabilization INACTIVE."); //} } // surface tension // =============== if (config.PressureGradient && config.physParams.Sigma != 0.0) { // isotropic part of the surface stress tensor if (config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Local || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine) { for (int d = 0; d < D; d++) { if (config.dntParams.SST_isotropicMode != SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine) { IEquationComponent G = new SurfaceTension_LaplaceBeltrami_Surface(d, config.physParams.Sigma * 0.5); IEquationComponent H = new SurfaceTension_LaplaceBeltrami_BndLine(d, config.physParams.Sigma * 0.5, config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(G); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(H); } else { //G = new SurfaceTension_LaplaceBeltrami2_Surface(d, config.physParams.Sigma * 0.5); //H = new SurfaceTension_LaplaceBeltrami2_BndLine(d, config.physParams.Sigma * 0.5, config.physParams.Theta_e, config.physParams.betaL); IEquationComponent isoSurfT = new IsotropicSurfaceTension_LaplaceBeltrami(d, D, config.physParams.Sigma * 0.5, BcMap.EdgeTag2Type, BcMap, config.physParams.theta_e, config.physParams.betaL, _staticInt); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(isoSurfT); } } this.NormalsRequired = true; } else if (config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Projected || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_ClosestPoint || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_LaplaceBeltramiMean || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Fourier) { for (int d = 0; d < D; d++) { m_OP.EquationComponents[CodName[d]].Add(new CurvatureBasedSurfaceTension(d, D, LsTrk, config.physParams.Sigma)); } this.CurvatureRequired = true; /* * Console.WriteLine("REM: hack in Operator factory"); * for(int d = 0; d < D; d++) { * //var G = new SurfaceTension_LaplaceBeltrami_Surface(d, config.physParams.Sigma * 0.5); * var H = new SurfaceTension_LaplaceBeltrami_BndLine(d, config.physParams.Sigma * 0.5, config.dntParams.surfTensionMode == SurfaceTensionMode.LaplaceBeltrami_Flux); * * //m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(G); * m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(H); * } * * this.NormalsRequired = true; */ } else { throw new NotImplementedException("Not implemented."); } // dynamic part if (config.dntParams.SurfStressTensor != SurfaceSressTensor.Isotropic) { double muI = config.physParams.mu_I; double lamI = config.physParams.lambda_I; double penalty_base = (degU + 1) * (degU + D) / D; double penalty = penalty_base * dntParams.PenaltySafety; // surface shear viscosity if (config.dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceRateOfDeformation || config.dntParams.SurfStressTensor == SurfaceSressTensor.SemiImplicit || config.dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven) { for (int d = 0; d < D; d++) { var surfDeformRate = new BoussinesqScriven_SurfaceDeformationRate_GradU(d, muI * 0.5, penalty); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfDeformRate); //m_OP.OnIntegratingSurfaceElement += surfDeformRate.SetParameter; if (config.dntParams.SurfStressTensor != SurfaceSressTensor.SemiImplicit) { var surfDeformRateT = new BoussinesqScriven_SurfaceDeformationRate_GradUTranspose(d, muI * 0.5, penalty); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfDeformRateT); //m_OP.OnIntegratingSurfaceElement += surfDeformRateT.SetParameter; } } } // surface dilatational viscosity if (config.dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceVelocityDivergence || config.dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven) { for (int d = 0; d < D; d++) { var surfVelocDiv = new BoussinesqScriven_SurfaceVelocityDivergence(d, muI * 0.5, lamI * 0.5, penalty, BcMap.EdgeTag2Type); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfVelocDiv); //m_OP.OnIntegratingSurfaceElement += surfVelocDiv.SetParameter; } } } // stabilization if (config.dntParams.UseLevelSetStabilization) { for (int d = 0; d < D; d++) { m_OP.EquationComponents[CodName[d]].Add(new LevelSetStabilization(d, D, LsTrk)); } } } // surface force term // ================== if (config.PressureGradient && config.physParams.useArtificialSurfaceForce) { for (int d = 0; d < D; d++) { m_OP.EquationComponents[CodName[d]].Add(new SurfaceTension_ArfForceSrc(d, D, LsTrk)); } } // evaporation (mass flux) // ======================= if (evaporation) { for (int d = 0; d < D; d++) { m_OP.EquationComponents[CodName[d]].Add(new Operator.DynamicInterfaceConditions.MassFluxAtInterface(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c)); } } } // Finalize // ======== m_OP.Commit(); }
public static IBM_Control[] IBMCylinderFlow(string _DbPath = null, int k = 2, bool xPeriodic = false, double VelXBase = 0.0) { List <IBM_Control> R = new List <IBM_Control>(); foreach (int i in new int[] { 3 }) { IBM_Control C = new IBM_Control(); C.Paramstudy_CaseIdentification = new Tuple <string, object>[] { new Tuple <string, object>("k", i), }; k = i; const double BaseSize = 1.0; // basic database options // ====================== C.DbPath = @"\\fdyprime\userspace\krause\BoSSS_DBs\Paper_CellAgglo01_Penalty4"; C.savetodb = false; C.ProjectName = "FixedCylinderRe100_k" + i + "_CellAgglo02_penalty4_newMesh2"; switch (i) { case 1: C.MeshFactor = 1.33; // was 1.33 break; case 2: C.MeshFactor = 0.92; break; case 3: C.MeshFactor = 0.7; // was 07 break; default: throw new ApplicationException(); } C.ProjectDescription = "Cylinder"; C.Tags.Add("with immersed boundary method"); // DG degrees // ========== C.FieldOptions.Add("VelocityX", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("VelocityY", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); //Console.WriteLine("Achtung: equal order!!!!"); C.FieldOptions.Add("Pressure", new FieldOpts() { Degree = k - 1, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("PhiDG", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Phi", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); //grid and boundary conditions // ============================ C.GridFunc = delegate { var _xNodes1 = Grid1D.TanhSpacing(-2, -1, Convert.ToInt32(10 * C.MeshFactor), 0.5, false); //10 _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1)); var _xNodes2 = GenericBlas.Linspace(-1, 2, Convert.ToInt32(35 * C.MeshFactor)); //35 _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1)); var _xNodes3 = Grid1D.TanhSpacing(2, 20, Convert.ToInt32(60 * C.MeshFactor), 1.5, true); //60 var xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3); var _yNodes1 = Grid1D.TanhSpacing(-2, -1, Convert.ToInt32(7 * C.MeshFactor), 0.9, false); //7 _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1)); var _yNodes2 = GenericBlas.Linspace(-1, 1, Convert.ToInt32(25 * C.MeshFactor)); //25 _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1)); var _yNodes3 = Grid1D.TanhSpacing(1, 2.1, Convert.ToInt32(7 * C.MeshFactor), 1.1, true); //7 var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3); //double[] xNodes = GenericBlas.Linspace(0 * BaseSize, 22 * BaseSize, 25); //double[] yNodes = GenericBlas.Linspace(0 * BaseSize, 4.1 * BaseSize, 25); var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: xPeriodic); grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper"); grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower"); if (!xPeriodic) { grd.EdgeTagNames.Add(3, "Velocity_Inlet_left"); grd.EdgeTagNames.Add(4, "Pressure_Outlet_right"); } grd.DefineEdgeTags(delegate(double[] X) { byte et = 0; if (Math.Abs(X[1] - (-2 * BaseSize)) <= 1.0e-8) { et = 1; } if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8) { et = 2; } if (!xPeriodic && Math.Abs(X[0] - (-2 * BaseSize)) <= 1.0e-8) { et = 3; } if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8) { et = 4; } Debug.Assert(et != 0); return(et); }); Console.WriteLine("Cells: {0}", grd.NumberOfCells); return(grd); }; //C.GridFunc = delegate { // // Box1 // var box1_p1 = new double[2] { -2, -2 }; // var box1_p2 = new double[2] { 20, 2.1 }; // var box1 = new GridBox(box1_p1, box1_p2, 46, 20); //k1: 70,25 ; k2: 46,20 ; k3: 35,15 // // Box2 // var box2_p1 = new double[2] { -2, -2 }; // var box2_p2 = new double[2] { 3, 2.1 }; // var box2 = new GridBox(box2_p1, box2_p2, 26, 40); //k1: 40,50 ; k2: 26,40; k3: 20, 30 // // Box3 // var box3_p1 = new double[2] { -2, -1 }; // var box3_p2 = new double[2] { 1, 1 }; // var box3 = new GridBox(box3_p1, box3_p2, 32, 38); //k1: 48,58 ; k2: 32,38; k3: 24, 30 // // Box4 // var box4_p1 = new double[2] { -0.7, -0.72 }; // var box4_p2 = new double[2] { 0.7, 0.7 }; // var box4 = new GridBox(box4_p1, box4_p2, 30, 56); //k1: 44,84 ; k2: 30,56; k3: 22, 42 // var grd = Grid2D.HangingNodes2D(box1, box2, box3,box4); // grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper"); // grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower"); // if (!xPeriodic) { // grd.EdgeTagNames.Add(3, "Velocity_Inlet_left"); // grd.EdgeTagNames.Add(4, "Pressure_Outlet_right"); // } // grd.DefineEdgeTags(delegate (double[] X) { // byte et = 0; // if (Math.Abs(X[1] - (-2 * BaseSize)) <= 1.0e-8) // et = 1; // if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8) // et = 2; // if (!xPeriodic && Math.Abs(X[0] - (-2 * BaseSize)) <= 1.0e-8) // et = 3; // if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8) // et = 4; // Debug.Assert(et != 0); // return et; // }); // Console.WriteLine("Cells: {0}", grd.NumberOfCells); // return grd; //}; C.AddBoundaryCondition("Velocity_Inlet_upper", "VelocityX", X => 0); C.AddBoundaryCondition("Velocity_Inlet_lower", "VelocityX", X => 0); //-(4 * 1.5 * X[1] * (4.1 - X[1]) / (4.1 * 4.1)) if (!xPeriodic) { C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX", X => (4 * 1.5 * (X[1] + 2) * (4.1 - (X[1] + 2)) / (4.1 * 4.1))); //C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX#A", X => 1); } C.AddBoundaryCondition("Pressure_Outlet_right"); // Initial Values // ============== double radius = 0.5; C.PhysicalParameters.rho_A = 1; C.PhysicalParameters.mu_A = 1.0 / 20; //C.InitialValues.Add("Phi", X => phi(X, 0)); //C.InitialValues.Add("Phi", X => ((X[0] / (radius * BaseSize)) - mPx) * (X[0] / (radius * BaseSize)) - mPx) + ((X[1]) / (radius * BaseSize)) - 2.)Pow2() - radius.Pow2())); // quadratic form // ); C.InitialValues_Evaluators.Add("Phi", X => - (X[0]).Pow2() + -(X[1]).Pow2() + radius.Pow2()); //C.InitialValues.Add("Phi", X => -1); C.InitialValues_Evaluators.Add("VelocityX", X => 4 * 1.5 * (X[1] + 2) * (4.1 - (X[1] + 2)) / (4.1 * 4.1)); //C.InitialValues.Add("VelocityX", delegate (double[] X) //{ // double x = X[0]; // double y = X[1]; // double R = Math.Sqrt((x + 1).Pow2() + y.Pow2()); // double xVel = 0; // if (R < 0.75) // { // xVel = 1; // } // return xVel; //}); //C.InitialValues.Add("VelocityY", delegate (double[] X) { // double x = X[0]; // double y = X[1]; // double R = Math.Sqrt((x + 1).Pow2() + (y).Pow2()); // double yVel = 0; // if (R < 0.75) { // yVel = 1; // } // return yVel; //}); // For restart //C.RestartInfo = new Tuple<Guid, TimestepNumber>(new Guid("8f5cfed9-31c7-4be8-aa56-e92e5348e08b"), 95); //C.GridGuid = new Guid("71ffc0c4-66aa-4762-b07e-45385f34b03f"); // Physical Parameters // =================== C.PhysicalParameters.IncludeConvection = true; // misc. solver options // ==================== C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2; C.LevelSetSmoothing = false; //C.option_solver = "direct"; C.MaxKrylovDim = 20; C.MaxSolverIterations = 50; C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite; C.NoOfMultigridLevels = 0; // Timestepping // ============ C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.ImplicitEuler; double dt = 0.05; C.dtMax = dt; C.dtMin = dt; C.Endtime = 70; C.NoOfTimesteps = 1000000; // haben fertig... // =============== R.Add(C); } return(R.ToArray()); }
/// <summary> /// ctor. /// </summary> public NECQuadratureVolume(IGridData context, SpatialOperator DiffOp, IList <DGField> _DomainFields, IList <DGField> _ParameterFields, UnsetteledCoordinateMapping CodomainMapping, ICompositeQuadRule <QuadRule> domNrule) : base(context, DiffOp, _DomainFields, _ParameterFields, CodomainMapping) { // ----------------- // quadrature object // ----------------- m_Quad = CellQuadrature.GetQuadrature2(new int[] { CodomainMapping.NoOfCoordinatesPerCell }, context, domNrule, this.EvaluateEx, this.SaveIntegrationResults, this.AllocateBuffers); int Gamma = _DomainFields.Count; // ------------------------ // sort equation components // ------------------------ m_NonlinSources = EquationComponentArgMapping <INonlinearSource> .GetArgMapping(DiffOp, true); m_NonlinFormV = EquationComponentArgMapping <INonlinVolumeForm_V> .GetArgMapping(DiffOp, true, eq => ((eq.VolTerms & (TermActivationFlags.V | TermActivationFlags.UxV | TermActivationFlags.GradUxV)) != 0), eq => (eq is IVolumeForm ? new NonlinVolumeFormVectorizer((IVolumeForm)eq) : null)); m_NonlinFormGradV = EquationComponentArgMapping <INonlinVolumeForm_GradV> .GetArgMapping(DiffOp, true, eq => ((eq.VolTerms & (TermActivationFlags.UxGradV | TermActivationFlags.GradV | TermActivationFlags.GradUxGradV)) != 0), eq => (eq is IVolumeForm ? new NonlinVolumeFormVectorizer((IVolumeForm)eq) : null)); Debug.Assert(base.m_DomainFields.Length >= Gamma); m_ValueRequired = new bool[base.m_DomainFields.Length]; m_GradientRequired = new bool[Gamma]; // base.m_DomainFields may also contain parameter fields: for (int i = Gamma; i < base.m_DomainFields.Length; i++) { m_ValueRequired[i] = true; } this.m_NonlinFormV.DetermineReqFields(m_GradientRequired, comp => ((comp.VolTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0)); this.m_NonlinFormGradV.DetermineReqFields(m_GradientRequired, comp => ((comp.VolTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0)); this.m_NonlinFormV.DetermineReqFields(m_ValueRequired, comp => ((comp.VolTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0)); this.m_NonlinFormGradV.DetermineReqFields(m_ValueRequired, comp => ((comp.VolTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0)); this.m_NonlinSources.DetermineReqFields(m_ValueRequired, comp => true); base.m_NonlinFluxes.DetermineReqFields(m_ValueRequired, comp => true); base.m_NonlinFluxesEx.DetermineReqFields(m_ValueRequired, comp => true); // --------- // profiling // --------- var _CustomTimers = new Stopwatch[] { new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch() }; var _CustomTimers_Names = new string[] { "Flux-Eval", "Basis-Eval", "Field-Eval", "Loops", "ParametersAndNormals", "Flux-Trafo" }; Flux_Eval = _CustomTimers[0]; Flux_Trafo = _CustomTimers[5]; Field_Eval = _CustomTimers[2]; Basis_Eval = _CustomTimers[1]; Loops = _CustomTimers[3]; ParametersAndNormals = _CustomTimers[4]; m_Quad.CustomTimers = m_Quad.CustomTimers.Cat(_CustomTimers); m_Quad.CustomTimers_Names = m_Quad.CustomTimers_Names.Cat(_CustomTimers_Names); m_Quad.CustomTimers_RootPointer = new int[_CustomTimers_Names.Length]; ArrayTools.SetAll(m_Quad.CustomTimers_RootPointer, -1); this.m_NonlinSources_watch = this.m_NonlinSources.InitStopWatches(0, m_Quad); this.m_NonlinFormV_watch = this.m_NonlinFormV.InitStopWatches(0, m_Quad); this.m_NonlinFormGradV_watch = this.m_NonlinFormGradV.InitStopWatches(0, m_Quad); base.m_NonlinFluxesWatches = base.m_NonlinFluxes.InitStopWatches(0, m_Quad); base.m_NonlinFluxesExWatches = base.m_NonlinFluxesEx.InitStopWatches(0, m_Quad); // --------------------- // alloc multidim arrays // --------------------- m_FluxValues = new MultidimensionalArray[m_CodomainBasisS.Length]; m_FluxValuesTrf = new MultidimensionalArray[m_CodomainBasisS.Length]; for (int i = 0; i < m_FluxValues.Length; i++) { if (m_NonlinFluxes[i].m_AllComponentsOfMyType.Length > 0 || m_NonlinFluxesEx[i].m_AllComponentsOfMyType.Length > 0 || m_NonlinFormGradV[i].m_AllComponentsOfMyType.Length > 0) { m_FluxValues[i] = new MultidimensionalArray(3); m_FluxValuesTrf[i] = new MultidimensionalArray(3); Basis GradBasis = base.m_CodomainBasisS[i]; if (m_MaxCodBasis_Gradient == null || m_MaxCodBasis_Gradient.Degree < GradBasis.Degree) { m_MaxCodBasis_Gradient = GradBasis; } } } m_SourceValues = new MultidimensionalArray[m_CodomainBasisS.Length]; for (int i = 0; i < m_SourceValues.Length; i++) { if (m_NonlinSources[i].m_AllComponentsOfMyType.Length > 0 || m_NonlinFormV[i].m_AllComponentsOfMyType.Length > 0) { m_SourceValues[i] = new MultidimensionalArray(2); Basis ValBasis = base.m_CodomainBasisS[i]; if (m_MaxCodBasis == null || m_MaxCodBasis.Degree < ValBasis.Degree) { m_MaxCodBasis = ValBasis; } } } m_FieldValues = new MultidimensionalArray[m_DomainFields.Length]; m_FieldGradients = new MultidimensionalArray[Gamma]; for (int i = 0; i < m_DomainFields.Length; i++) { if (m_ValueRequired[i]) { m_FieldValues[i] = new MultidimensionalArray(2); } if (i < Gamma && m_GradientRequired[i]) { m_FieldGradients[i] = new MultidimensionalArray(3); } } m_TestFuncWeighted = new MultidimensionalArray(2); m_TestFuncGradWeighted = new MultidimensionalArray(3); }
static void InfoRecursive(object obj, int RecursionDepth, int MaxRecursionDepth) { if (obj == null) { Console.WriteLine("Null"); return; } if (RecursionDepth > MaxRecursionDepth) { Console.WriteLine(" ... no further recursion - max recursion depth reached."); return; } Type objT = obj.GetType(); if ((objT.IsPrimitive || objT.IsEnum || objT == typeof(string))) { Console.WriteLine(obj.ToString() + " (" + objT.Name + ")"); return; } if (objT.IsSubclassOf(typeof(System.Delegate))) { // unable to log delegates Console.WriteLine("Delegate"); return; } void WriteSpaces() { //Console.WriteLine(); for (int i = 0; i < RecursionDepth; i++) { Console.Write(" "); } } if (obj is System.Collections.IEnumerable) { System.Collections.IEnumerable objEnu = (System.Collections.IEnumerable)obj; int cnt = 0; foreach (var objE in objEnu) { WriteSpaces(); Console.Write("[{0}]: ", cnt); cnt++; InfoRecursive(objE, RecursionDepth + 1, MaxRecursionDepth); } return; } BindingFlags biFlags = BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty; MemberInfo[] PIs = objT.GetProperties(biFlags); MemberInfo[] FIs = objT.GetFields(biFlags); foreach (MemberInfo mi in ArrayTools.Cat(PIs, FIs)) { WriteSpaces(); Console.Write(mi.Name + ": "); object Val; if (mi is PropertyInfo) { PropertyInfo pi = ((PropertyInfo)mi); if (!pi.CanRead) { Console.WriteLine("cannot read."); continue; } if (pi.GetIndexParameters() != null && pi.GetIndexParameters().Length > 0) { // no support for indexed properties. Console.WriteLine("indexed property - not supported."); continue; } //pi.GetIndexParameters try { Val = pi.GetValue(obj, biFlags, null, null, null); } catch (TargetInvocationException tie) { Console.WriteLine(tie.GetType().Name + ": " + tie.Message); continue; } } else if (mi is FieldInfo) { Val = ((FieldInfo)mi).GetValue(obj); } else { Console.WriteLine("unsupported member type: " + mi.GetType().FullName + "."); continue; } InfoRecursive(Val, RecursionDepth + 1, MaxRecursionDepth); } }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="OpMatrix"></param> /// <param name="OpAffine"></param> /// <param name="RowMapping"></param> /// <param name="ColMapping"></param> /// <param name="CurrentState"></param> /// <param name="AgglomeratedCellLengthScales"></param> /// <param name="time"></param> /// <param name="CutCellQuadOrder"></param> /// <param name="SurfaceForce"></param> /// <param name="LevelSetGradient"></param> /// <param name="ExternalyProvidedCurvature"></param> public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine, UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping, IEnumerable <T> CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time, int CutCellQuadOrder, VectorField <SinglePhaseField> SurfaceForce, VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature) where T : DGField { // checks: if (ColMapping.BasisS.Count != this.m_XOp.DomainVar.Count) { throw new ArgumentException(); } if (RowMapping.BasisS.Count != this.m_XOp.CodomainVar.Count) { throw new ArgumentException(); } int D = this.LsTrk.GridDat.SpatialDimension; if (CurrentState != null && CurrentState.Count() != (D + 1)) { throw new ArgumentException(); } if (OpMatrix == null && CurrentState == null) { throw new ArgumentException(); } DGField[] U0; if (CurrentState != null) { U0 = CurrentState.Take(D).ToArray(); } else { U0 = null; } // advanced settings for the navier slip boundary condition // ======================================================== CellMask SlipArea; switch (this.dntParams.GNBC_Localization) { case NavierSlip_Localization.Bulk: { SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask; break; } case NavierSlip_Localization.ContactLine: { SlipArea = null; break; } case NavierSlip_Localization.Nearband: { SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth)); break; } case NavierSlip_Localization.Prescribed: { throw new NotImplementedException(); } default: throw new ArgumentException(); } MultidimensionalArray SlipLengths; SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs(); SlipLengths.Clear(); //SlipLengths.AccConstant(-1.0); if (SlipArea != null) { foreach (Chunk cnk in SlipArea) { for (int i = cnk.i0; i < cnk.JE; i++) { switch (this.dntParams.GNBC_SlipLength) { case NavierSlip_SlipLength.hmin_DG: { int degU = ColMapping.BasisS.ToArray()[0].Degree; SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1); break; } case NavierSlip_SlipLength.hmin_Grid: { SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i]; break; } case NavierSlip_SlipLength.Prescribed_SlipLength: { SlipLengths[i] = this.physParams.sliplength; break; } case NavierSlip_SlipLength.Prescribed_Beta: { SlipLengths[i] = -1.0; break; } } } } } // parameter assembly // ================== LevelSet Phi = (LevelSet)(this.LsTrk.LevelSets[0]); SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray(); // normals: SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions. if (this.NormalsRequired) { if (LevelSetGradient == null) { LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory); LevelSetGradient.Gradient(1.0, Phi); } Normals = LevelSetGradient.ToArray(); } else { Normals = new SinglePhaseField[D]; } // curvature: SinglePhaseField Curvature; if (this.CurvatureRequired) { Curvature = ExternalyProvidedCurvature; } else { Curvature = null; } // linearization velocity: DGField[] U0_U0mean; if (this.U0meanrequired) { XDGBasis U0meanBasis = new XDGBasis(this.LsTrk, 0); VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory); U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean); } else { U0_U0mean = new DGField[2 * D]; } // Temperature gradient for evaporation //VectorField<DGField> GradTemp = new VectorField<DGField>(D, new XDGBasis(LsTrk, 0), XDGField.Factory); //if (CoupledCurrentState != null) { // DGField Temp = CoupledCurrentState.ToArray()[0]; // GradTemp = new VectorField<DGField>(D, Temp.Basis, "GradTemp", XDGField.Factory); // XNSEUtils.ComputeGradientForParam(Temp, GradTemp, this.LsTrk); //} // concatenate everything var Params = ArrayTools.Cat <DGField>( U0_U0mean, Normals, Curvature, ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D])); // linearization velocity: if (this.U0meanrequired) { VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray()); U0mean.Clear(); if (this.physParams.IncludeConvection) { ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper); } } // assemble the matrix & affine vector // =================================== IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea; // compute matrix if (OpMatrix != null) { XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = this.m_XOp.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping, SpcToCompute); foreach (var kv in AgglomeratedCellLengthScales) { mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value; mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths); } if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0) { foreach (var kv in InterfaceLengths) { mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value); } } mtxBuilder.time = time; mtxBuilder.ComputeMatrix(OpMatrix, OpAffine); } else { XSpatialOperatorMk2.XEvaluatorNonlin eval = this.m_XOp.GetEvaluatorEx(this.LsTrk, CurrentState.ToArray(), Params, RowMapping, SpcToCompute); foreach (var kv in AgglomeratedCellLengthScales) { eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value; eval.SpeciesOperatorCoefficients[kv.Key].EdgeLengthScales = kv.Value; eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths); } if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0) { foreach (var kv in InterfaceLengths) { eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value); } } eval.time = time; eval.Evaluate(1.0, 1.0, OpAffine); } }
private void BuildNeighborship(int[][] AggregationCells) { IGridData pGrid = ParentGrid; int j0Coarse = CellPartitioning.i0; int JlocCoarse = CellPartitioning.LocalLength; int JElocFine = pGrid.iLogicalCells.Count; int JlocFine = pGrid.iLogicalCells.NoOfLocalUpdatedCells; // compute fine-to-coarse mapping // ============================== int[] Fine2CoarseGlobal = new int[JElocFine]; // index: local cell index on fine grid; maps to _global_ cell index on coarse grid. { ArrayTools.SetAll(Fine2CoarseGlobal, -111); for (int jCellCoarse = 0; jCellCoarse < JlocCoarse; jCellCoarse++) { foreach (int jCellFine in AggregationCells[jCellCoarse]) { if (jCellFine < 0 || jCellFine >= JlocFine) { throw new ArgumentOutOfRangeException(); } Fine2CoarseGlobal[jCellFine] = jCellCoarse + j0Coarse; } } Fine2CoarseGlobal.MPIExchange <int[], int>(pGrid); } // define external coarse cells // ============================ int JElocCoarse; { HashSet <long> tmpCoarseExternal = new HashSet <long>(); for (int jF = JlocFine; jF < JElocFine; jF++) { tmpCoarseExternal.Add(Fine2CoarseGlobal[jF]); } long[] ExtGlbIdx = tmpCoarseExternal.ToArray(); Array.Sort(ExtGlbIdx); // since the send lists are ascending, the external cells also should be ascending; // since the MPI rank only increases with the global cell index, this sort-operation also guarantees // that the external cells are sorted according to MPI rank. m_Parallel.GlobalIndicesExternalCells = ExtGlbIdx; JElocCoarse = JlocCoarse + ExtGlbIdx.Length; // global-to-local index mapping: Dictionary <long, int> GlobalIdx2Local = new Dictionary <long, int>(); for (int jC = JlocCoarse; jC < JElocCoarse; jC++) { GlobalIdx2Local.Add(ExtGlbIdx[jC - JlocCoarse], jC); } m_Parallel.Global2LocalIdx = GlobalIdx2Local; } // fine-to-coarse, coarse-to-fine mapping in local indices // ======================================================== { // fine-to-coarse this.jCellFine2jCellCoarse = new int[JElocFine]; var F2C = jCellFine2jCellCoarse; for (int jF = 0; jF < JElocFine; jF++) // loop over fine cells... { int jCoarse; if (jF < JlocFine) { jCoarse = Fine2CoarseGlobal[jF] - j0Coarse; Debug.Assert(jCoarse >= 0); Debug.Assert(jCoarse < JlocCoarse); } else { jCoarse = m_Parallel.Global2LocalIdx[Fine2CoarseGlobal[jF]]; Debug.Assert(jCoarse >= JlocCoarse); Debug.Assert(jCoarse < JElocCoarse); } F2C[jF] = jCoarse; } // coarse-to-fine mapping this.jCellCoarse2jCellFine = new int[JElocCoarse][]; var C2F = jCellCoarse2jCellFine; var tmpC2F = new List <int> [JElocCoarse]; for (int jC = 0; jC < JElocCoarse; jC++) { tmpC2F[jC] = new List <int>(); } for (int jFine = 0; jFine < JElocFine; jFine++) { int jCoarse = F2C[jFine]; Debug.Assert(!tmpC2F[jCoarse].Contains(jFine)); tmpC2F[jCoarse].Add(jFine); } for (int jC = 0; jC < JElocCoarse; jC++) { C2F[jC] = tmpC2F[jC].ToArray(); } } // define neighborship // =================== { int[][] FineClNeigh = pGrid.iLogicalCells.CellNeighbours; HashSet <int>[] tmpClNeig = new HashSet <int> [JlocCoarse]; Dictionary <long, int> ExtCells_GlobalIdx2Local = m_Parallel.Global2LocalIdx; for (int jCellCoarse = 0; jCellCoarse < JlocCoarse; jCellCoarse++) // loop over all coarse grid cells... { foreach (int jCellFine in AggregationCells[jCellCoarse]) { int[] FineNeighs = FineClNeigh[jCellFine]; foreach (int jCellFineNeigh in FineNeighs) // loop over all neighbor cells in the fine grid... { int jCellCoarseNeighGlob = Fine2CoarseGlobal[jCellFineNeigh]; // map index of fine grid neighbor to coarse cell index // convert global cell index to local int jCellCoarseNeighLoc; if (jCellCoarseNeighGlob >= j0Coarse && jCellCoarseNeighGlob <= (j0Coarse + JlocCoarse)) { // Neighbor is a locally updated cell jCellCoarseNeighLoc = jCellCoarseNeighGlob - j0Coarse; } else { // Neighbor is an external cell jCellCoarseNeighLoc = ExtCells_GlobalIdx2Local[jCellCoarseNeighGlob]; } // add neighbor cell if (jCellCoarse != jCellCoarseNeighLoc) { if (tmpClNeig[jCellCoarse] == null) { tmpClNeig[jCellCoarse] = new HashSet <int>(); } tmpClNeig[jCellCoarse].Add(jCellCoarseNeighLoc); } } } } m_LogicalCellData.CellNeighbours = new int[JlocCoarse][]; var CN = m_LogicalCellData.CellNeighbours; for (int jCellCoarse = 0; jCellCoarse < JlocCoarse; jCellCoarse++) { var hs = tmpClNeig[jCellCoarse]; Debug.Assert(hs == null || hs.Contains(jCellCoarse) == false); if (hs != null) { int[] xx = new int[hs.Count]; CN[jCellCoarse] = xx; int i = 0; foreach (int x in hs) { xx[i] = x; i++; } } else { CN[jCellCoarse] = new int[0]; } Debug.Assert(CN[jCellCoarse].Contains(jCellCoarse) == false); } } // MPI send lists // ============== int mpiSize = CellPartitioning.MpiSize; { m_Parallel.ProcessesToSendTo = ParentGrid.iParallel.ProcessesToSendTo.CloneAs(); m_Parallel.ProcessesToReceiveFrom = ParentGrid.iParallel.ProcessesToReceiveFrom.CloneAs(); int[] F2C = this.jCellFine2jCellCoarse; m_Parallel.SendCommLists = new int[mpiSize][]; var tmpSendList = new HashSet <int>(); for (int rnk = 0; rnk < mpiSize; rnk++) { int[] ParrentSendList = ParentGrid.iParallel.SendCommLists[rnk]; if (ParrentSendList != null && ParrentSendList.Length > 0) { tmpSendList.Clear(); foreach (int jFine in ParrentSendList) { Debug.Assert(jFine >= 0); Debug.Assert(jFine < ParentGrid.iLogicalCells.NoOfLocalUpdatedCells); int jCoarse = F2C[jFine]; Debug.Assert(jCoarse >= 0); Debug.Assert(jCoarse < this.iLogicalCells.NoOfLocalUpdatedCells); tmpSendList.Add(jCoarse); } m_Parallel.SendCommLists[rnk] = tmpSendList.ToArray(); Array.Sort(m_Parallel.SendCommLists[rnk]); } } } // MPI receive lists // ================= { //ParentGrid.iParallel.ProcessesToReceiveFrom var GlobalIdx = this.m_Parallel.GlobalIndicesExternalCells; this.m_Parallel.RcvCommListsNoOfItems = new int[mpiSize]; this.m_Parallel.RcvCommListsInsertIndex = new int[mpiSize]; int[] NoOfItems = this.m_Parallel.RcvCommListsNoOfItems; int[] InsertIdx = this.m_Parallel.RcvCommListsInsertIndex; ArrayTools.SetAll(InsertIdx, -1); #if DEBUG HashSet <int> ProcCheck = new HashSet <int>(); #endif for (int jC = JlocCoarse; jC < JElocCoarse; jC++) { int jGlob = (int)GlobalIdx[jC - JlocCoarse]; int iProc = this.CellPartitioning.FindProcess(jGlob); #if DEBUG ProcCheck.Add(iProc); #endif if (InsertIdx[iProc] < 0) { InsertIdx[iProc] = jC; } else { Debug.Assert(jC > InsertIdx[iProc]); } NoOfItems[iProc]++; } #if DEBUG Debug.Assert(this.iParallel.ProcessesToReceiveFrom.SetEquals(ProcCheck)); #endif } // MPI check // ========= #if DEBUG { int[] TestData = new int[JElocCoarse]; for (int jC = 0; jC < JlocCoarse; jC++) { int GlobalIdx; GlobalIdx = jC + j0Coarse; TestData[jC] = GlobalIdx; } TestData.MPIExchange <int[], int>(this); for (int jC = 0; jC < JElocCoarse; jC++) { int GlobalIdx; if (jC < JlocCoarse) { GlobalIdx = jC + j0Coarse; } else { GlobalIdx = (int)(m_Parallel.GlobalIndicesExternalCells[jC - JlocCoarse]); } Debug.Assert(TestData[jC] == GlobalIdx); } } #endif }
/// <summary> /// ctor for the operator factory, where the equation compnents are set /// </summary> /// <param name="config"></param> /// <param name="_LsTrk"></param> /// <param name="_HMFdegree"></param> /// <param name="BcMap"></param> /// <param name="degU"></param> public XNSE_OperatorFactory(IXNSE_Configuration config, LevelSetTracker _LsTrk, int _HMFdegree, IncompressibleMultiphaseBoundaryCondMap BcMap, int degU) { this.LsTrk = _LsTrk; this.D = _LsTrk.GridDat.SpatialDimension; this.HMFDegree = _HMFdegree; this.physParams = config.getPhysParams; this.dntParams = config.getDntParams; // test input // ========== { if (config.getDomBlocks.GetLength(0) != 2 || config.getCodBlocks.GetLength(0) != 2) { throw new ArgumentException(); } if ((config.getPhysParams.mu_A <= 0) && (config.getPhysParams.mu_B <= 0)) { config.isViscous = false; } else { if ((config.getPhysParams.mu_A <= 0) || (config.getPhysParams.mu_B <= 0)) { throw new ArgumentException(); } } if ((config.getPhysParams.rho_A <= 0) || (config.getPhysParams.rho_B <= 0)) { throw new ArgumentException(); } if (_LsTrk.SpeciesNames.Count != 2) { throw new ArgumentException(); } if (!(_LsTrk.SpeciesNames.Contains("A") && _LsTrk.SpeciesNames.Contains("B"))) { throw new ArgumentException(); } } // full operator: // ============== CodName = ArrayTools.Cat(EquationNames.MomentumEquations(D), EquationNames.ContinuityEquation); Params = ArrayTools.Cat( VariableNames.Velocity0Vector(D), VariableNames.Velocity0MeanVector(D), VariableNames.NormalVector(D), VariableNames.Curvature, VariableNames.SurfaceForceVector(D) ); DomName = ArrayTools.Cat(VariableNames.VelocityVector(D), VariableNames.Pressure); // selected part: if (config.getCodBlocks[0]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, D)); } if (config.getCodBlocks[1]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D, 1)); } if (config.getDomBlocks[0]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, D)); } if (config.getDomBlocks[1]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D, 1)); } // create Operator // =============== m_XOp = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesIdS.ToArray()); // add components // ============== // species bulk components for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { // Navier Stokes equations XOperatorComponentsFactory.AddSpeciesNSE(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired); // continuity equation if (config.isContinuity) { XOperatorComponentsFactory.AddSpeciesContinuityEq(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap); } } // interface components XOperatorComponentsFactory.AddInterfaceNSE(m_XOp, config, D, BcMap, LsTrk); // surface stress tensor XOperatorComponentsFactory.AddSurfaceTensionForce(m_XOp, config, D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); // surface tension force if (config.isContinuity) { XOperatorComponentsFactory.AddInterfaceContinuityEq(m_XOp, config, D, LsTrk); // continuity equation } m_XOp.Commit(); }
/// <summary> /// /// </summary> /// <param name="TargetMappingIndex"></param> /// <param name="outputPartitioning"> /// Partitioning of the new grid, resp the return array. /// </param> /// <returns> /// - 1st index: cell index in new grid, correlates with <paramref name="outputPartitioning"/>. /// - 2nd index: enumeration over cells (in the old grid) which are combined in the new grid. /// For cells with refinement, always one entry, for cells which are coarsened a greater number of entries. /// If null, the cell is not changed. /// - content: Subdivision leaf index, correlates with 2nd index of <see cref="KrefS_SubdivLeaves"/>, can be used as an input to <see cref="GetSubdivBasisTransform(int, int, int)"/>. /// </returns> public int[][] GetTargetMappingIndex(IPartitioning outputPartitioning) { using (new FuncTrace()) { Debug.Assert(DestGlobalId.Length == MappingIndex.Length); Debug.Assert(OldGlobalId.Length == MappingIndex.Length); int oldJ = DestGlobalId.Length; // Caching // ======= if (m_TargetMappingIndex != null) { // caching if (m_TargetMappingIndex.Length != outputPartitioning.LocalLength) { throw new ArgumentException("Length mismatch of output list and output partition."); } return(m_TargetMappingIndex); } // local evaluation, prepare communication // ======================================= m_TargetMappingIndex = new int[outputPartitioning.LocalLength][]; int j0Dest = outputPartitioning.i0; // keys: processors which should receive data from this processor Dictionary <int, GetTargetMapping_Helper> AllSendData = new Dictionary <int, GetTargetMapping_Helper>(); for (int j = 0; j < oldJ; j++) { int[] MappingIndex_j = MappingIndex[j]; if (MappingIndex_j != null) { Debug.Assert(TargetIdx[j].Length == MappingIndex_j.Length); int L = MappingIndex_j.Length; for (int l = 0; l < L; l++) { int jDest = TargetIdx[j][l]; int MapIdx = MappingIndex_j[l]; if (outputPartitioning.IsInLocalRange(jDest)) { int[] destCollection = m_TargetMappingIndex[jDest - j0Dest]; ArrayTools.AddToArray(MapIdx, ref destCollection); m_TargetMappingIndex[jDest - j0Dest] = destCollection; } else { int targProc = outputPartitioning.FindProcess(jDest); GetTargetMapping_Helper dataTargPrc; if (!AllSendData.TryGetValue(targProc, out dataTargPrc)) { dataTargPrc = new GetTargetMapping_Helper(); AllSendData.Add(targProc, dataTargPrc); } dataTargPrc.TargetIndices.Add(jDest); dataTargPrc.Items.Add(MapIdx); } } } else { Debug.Assert(TargetIdx[j].Length == 1); } } // communication // ============= var AllRcvData = SerialisationMessenger.ExchangeData(AllSendData, outputPartitioning.MPI_Comm); foreach (var kv in AllRcvData) { int rcvProc = kv.Key; j0Dest = outputPartitioning.GetI0Offest(rcvProc); var TIdxs = kv.Value.TargetIndices; var TVals = kv.Value.Items; Debug.Assert(TIdxs.Count == TVals.Count); int L = TIdxs.Count; for (int l = 0; l < L; l++) { int idx = TIdxs[l] - j0Dest; Debug.Assert(outputPartitioning.IsInLocalRange(idx)); int[] destCollection = m_TargetMappingIndex[idx]; ArrayTools.AddToArray(TVals[idx], ref destCollection); m_TargetMappingIndex[idx] = destCollection; } } // return // ====== return(m_TargetMappingIndex); } }
/// <summary> /// Computes a mapping from the new, cell local DG coordinate index to the previous/old DG coordinate index, or vice-versa. /// </summary> /// <param name="jCell"> /// Local cell index. /// </param> /// <param name="New2Old"> /// If true, a mapping from new species index to previous/old species index is returned, /// if false the other way around. /// </param> /// <param name="LsTrk"> /// </param> /// <param name="Map"> /// DG coordinate mapping. /// </param> /// <returns> /// Null, if there is no change in species ordering in cell <paramref name="jCell"/> /// from the previous level-set tracker state to the actual. /// /// Otherwise, if <paramref name="New2Old"/> is true, an array of the same length /// as the number of degrees-of-freedom currently in cell <paramref name="jCell"/>. /// - index: current DOF index in cell <paramref name="jCell"/>. /// - content: index of this DOF with respect to the previous level-set-tracker state. /// If <paramref name="New2Old"/> false, the other way around. /// </returns> public static int[] MappingUpdate(LevelSetTracker LsTrk, int jCell, UnsetteledCoordinateMapping Map, bool New2Old) { int[] SpeciesMap = SpeciesUpdate(LsTrk, jCell, New2Old); if (SpeciesMap == null) { return(null); } int NoVar = Map.NoOfVariables; XDGBasis[] XBasiseS = new XDGBasis[NoVar]; Basis[] BasiseS = new Basis[NoVar]; int[] Ns = new int[NoVar]; for (int iVar = 0; iVar < NoVar; iVar++) { Basis b = Map.BasisS[iVar]; XBasiseS[iVar] = b as XDGBasis; if (XBasiseS[iVar] != null) { BasiseS[iVar] = XBasiseS[iVar].NonX_Basis; } else { BasiseS[iVar] = b; } Ns[iVar] = BasiseS[iVar].Length; } //List<int> oldIdx = new List<int>(); //List<int> newIdx = new List<int>(); int[] IdxMap = new int[Map.MaxTotalNoOfCoordinatesPerCell]; ArrayTools.SetAll(IdxMap, int.MinValue); bool AnyRelocation = false; int i0 = Map.LocalUniqueCoordinateIndex(0, jCell, 0); for (int iVar = 0; iVar < NoVar; iVar++) { int i0Var = Map.LocalUniqueCoordinateIndex(iVar, jCell, 0); int N = Ns[iVar]; int offset = i0Var - i0; if (XBasiseS[iVar] != null) { // XDG-field for (int i = 0; i < SpeciesMap.Length; i++) { int ii = SpeciesMap[i]; for (int n = 0; n < N; n++) { int idxS = offset + n + i * N; int idxT = ii >= 0 ? offset + n + ii * N : int.MinValue; Debug.Assert(IdxMap[idxS] < 0); IdxMap[idxS] = idxT; AnyRelocation |= (idxS != idxT); } } } else { // single-phase-field for (int n = 0; n < N; n++) { int idx = offset + n; //oldIdx.Add(idx); //newIdx.Add(idx); Debug.Assert(IdxMap[idx] < 0); IdxMap[idx] = idx; } } } return(IdxMap); //if (AnyRelocation) // return IdxMap; //else // return null; }
/// <summary> /// Usual plotting /// </summary> protected override void PlotCurrentState(double physTime, TimestepNumber timestepNo, int superSampling = 0) { Tecplot.PlotFields( ArrayTools.Cat <DGField>(f1Gradient_Analytical, f1Gradient_Numerical, f1, GridData.BoundaryMark(), Laplace_f1_Numerical, Laplace_f2_Numerical), "derivatives", 0.0, superSampling); }
/// <summary> /// One Iteration of the ReInitialization /// Operators must be built first /// </summary> /// <param name="ChangeRate"> /// L2-Norm of the Change-Rate in the level set in this reinit step /// </param> /// <param name="Restriction"> /// The subgrid, on which the ReInit is performed /// </param> /// <param name="IncludingInterface"> /// !! Not yet functional !! /// True, if the subgrid contains the interface, this causes all external edges of the subgrid to be treated as boundaries /// False, for the rest of the domain, thus the flux to the adjacent cells wil be evaluated /// </param> /// <returns></returns> public void ReInitSingleStep(out double ChangeRate, SubGrid Restriction = null, bool IncludingInterface = true) { if (!IncludingInterface) { throw new NotImplementedException("Untested, not yet functional!"); } using (new FuncTrace()) { /// Init Residuals Residual.Clear(); Residual.Acc(1.0, Phi); OldPhi.Clear(); OldPhi.Acc(1.0, Phi); NewPhi.Clear(); NewPhi.Acc(1.0, Phi); CellMask RestrictionMask = Restriction == null ? null : Restriction.VolumeMask; //if (Control.Upwinding && UpdateDirection && IterationCounter % 10 == 0) { if (false && Control.Upwinding && UpdateDirection) { //if (Control.Upwinding && UpdateDirection) { UpdateBulkMatrix(Restriction); } UpdateDirection = false; // RHS part RHSField.CoordinateVector.Clear(); //Operator_RHS.Evaluate(NewPhi.Mapping, RHSField.Mapping); Operator_RHS.Evaluate(double.NaN, IncludingInterface ? Restriction : null, IncludingInterface ? SubGridBoundaryModes.BoundaryEdge : SubGridBoundaryModes.InnerEdge, ArrayTools.Cat(new DGField[] { Phi }, parameterFields, new DGField[] { RHSField })); #if DEBUG RHSField.CheckForNanOrInf(); #endif // solve // ===== double[] RHS = OpAffine.CloneAs(); RHS.ScaleV(-1.0); RHS.AccV(1.0, RHSField.CoordinateVector); SolverResult Result; if (Restriction != null) { SubRHS.Clear(); SubSolution.Clear(); SubRHS.AccV(1.0, RHS, default(int[]), SubVecIdx); SubSolution.AccV(1.0, NewPhi.CoordinateVector, default(int[]), SubVecIdx); Result = slv.Solve(SubSolution, SubRHS); NewPhi.Clear(RestrictionMask); NewPhi.CoordinateVector.AccV(1.0, SubSolution, SubVecIdx, default(int[])); } else { Result = slv.Solve(NewPhi.CoordinateVector, RHS); } #if Debug OpMatrix.SpMV(-1.0, NewPhi.CoordinateVector, 1.0, RHS); Console.WriteLine("LinearSolver: {0} Iterations, Converged={1}, Residual = {2} ", Result.NoOfIterations, Result.Converged, RHS.L2Norm()); #endif // Apply underrelaxation Phi.Clear(RestrictionMask); Phi.Acc(1 - underrelaxation, OldPhi, RestrictionMask); Phi.Acc(underrelaxation, NewPhi, RestrictionMask); Residual.Acc(-1.0, Phi, RestrictionMask); ChangeRate = Residual.L2Norm(RestrictionMask); //Calculate LevelSetGradient.Clear(); LevelSetGradient.Gradient(1.0, Phi, RestrictionMask); //LevelSetGradient.GradientByFlux(1.0, Phi); MeanLevelSetGradient.Clear(); MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient, RestrictionMask); if (Control.Upwinding) { //RestrictionMask.GetBitMask(); for (int i = 0; i < MeanLevelSetGradient.CoordinateVector.Length; i++) { NewDirection[i] = Math.Sign(MeanLevelSetGradient.CoordinateVector[i]); //NewDirection[i] = MeanLevelSetGradient.CoordinateVector[i]; OldDirection[i] -= NewDirection[i]; } double MaxDiff = OldDirection.L2Norm(); //if (MaxDiff > 1E-20 && IterationCounter % 10 == 0 ) { //if (MaxDiff > 1E-20) { // Console.WriteLine("Direction Values differ by {0}", MaxDiff); if (MaxDiff > 0.2) { //UpdateDirection = true; //Console.WriteLine("Direction Values differ by {0} => Updating ReInit-Matrix", MaxDiff); } ; //} //Console.WriteLine("HACK!!! Updating Upwind Matrix everytime!"); //UpdateDirection = true; // Reset Value OldDirection.Clear(); OldDirection.AccV(1.0, NewDirection); } } }
public static IBM_Control IBMCylinderFlow(string _DbPath = null, int k = 2, bool xPeriodic = false, double VelXBase = 0.0) { IBM_Control C = new IBM_Control(); const double BaseSize = 1.0; // basic database options // ==================== C.savetodb = false; C.ProjectDescription = "Cylinder"; C.Tags.Add("with immersed boundary method"); // DG degrees // ========== C.FieldOptions.Add("VelocityX", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("VelocityY", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Pressure", new FieldOpts() { Degree = k - 1, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("PhiDG", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Phi", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); // grid and boundary conditions // ============================ C.GridFunc = delegate { var _xNodes1 = Grid1D.TanhSpacing(0, 1, 5, 1, false); _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1)); var _xNodes2 = GenericBlas.Linspace(1, 5.5, 35); _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1)); var _xNodes3 = Grid1D.TanhSpacing(5.5, 22, 20, 1.3, true); var xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3); var _yNodes1 = Grid1D.TanhSpacing(0, 1, 5, 1.2, false); _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1)); var _yNodes2 = GenericBlas.Linspace(1, 3, 20); _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1)); var _yNodes3 = Grid1D.TanhSpacing(3, 4.1, 5, 1.2, true); var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3); var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: xPeriodic); grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper"); grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower"); if (!xPeriodic) { grd.EdgeTagNames.Add(3, "Velocity_Inlet_left"); grd.EdgeTagNames.Add(4, "Pressure_Outlet_right"); } grd.DefineEdgeTags(delegate(double[] X) { byte et = 0; if (Math.Abs(X[1] - (0 * BaseSize)) <= 1.0e-8) { et = 1; } if (Math.Abs(X[1] + (-4.1 * BaseSize)) <= 1.0e-8) { et = 2; } if (!xPeriodic && Math.Abs(X[0] - (0 * BaseSize)) <= 1.0e-8) { et = 3; } if (!xPeriodic && Math.Abs(X[0] + (-22 * BaseSize)) <= 1.0e-8) { et = 4; } Debug.Assert(et != 0); return(et); }); return(grd); }; C.AddBoundaryCondition("Velocity_Inlet_upper", "VelocityX", X => 0); C.AddBoundaryCondition("Velocity_Inlet_lower", "VelocityX", X => 0); if (!xPeriodic) { C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX", X => (4 * 1.5 * X[1] * (4.1 - X[1]) / (4.1 * 4.1))); } C.AddBoundaryCondition("Pressure_Outlet_right"); // Initial Values // ============== C.particleRadius = 0.5; C.InitialValues_Evaluators.Add("Phi", X => - (X[0] - 2).Pow2() + -(X[1] - 2).Pow2() + C.particleRadius.Pow2()); C.InitialValues_Evaluators.Add("VelocityX", X => 0); // Physical Parameters // =================== C.PhysicalParameters.mu_A = 0.05; C.PhysicalParameters.rho_A = 1; C.PhysicalParameters.IncludeConvection = true; C.PhysicalParameters.Material = true; // misc. solver options // ==================== C.AdvancedDiscretizationOptions.PenaltySafety = 1; C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.1; C.LevelSetSmoothing = false; C.MaxKrylovDim = 20; C.MaxSolverIterations = 100; C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite; C.NoOfMultigridLevels = 1; // Timestepping // ============ C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.BDF2; double dt = 1E20; C.dtFixed = dt; C.dtMax = dt; C.dtMin = dt; C.Endtime = 200; C.NoOfTimesteps = 1; // haben fertig... // =============== return(C); }
/// <summary> /// Based on the Ideas by /// C. Basting and D. Kuzmin, /// “A minimization-based finite element formulation for interface-preserving level set reinitialization”, /// Computing, vol. 95, no. 1, pp. 13–25, Dec. 2012. /// Create Spatial Operators and build the corresponding Matrices /// For the Left-Hand Side of the ReInitProblem /// RHS is computed on the fly in <see cref="ReInitSingleStep"/> /// The Bulk component is constant unless the grid changes, thus it is computed in <see cref="BuildOperators(CellQuadratureScheme)"/>. /// The Interface component changes with its motion. /// This component is calculated in <see cref="UpdateOperators(CellQuadratureScheme)"/>. /// </summary> /// <param name="LSTrck"></param> /// <param name="Control">various parameters <paramref name="EllipticReinitControl"/></param> /// <param name="HMFOrder">order of tghe interface quadrature</param> public EllipticReInit(LevelSetTracker LSTrck, EllipticReInitAlgoControl Control, SinglePhaseField LevelSetForReInit = null) { this.Control = Control; this.LevelSetTracker = LSTrck; if (LevelSetForReInit == null) { Phi = LevelSetTracker.LevelSets[0] as SinglePhaseField; } else { Phi = LevelSetForReInit; } this.underrelaxation = Control.underrelaxation; Residual = new SinglePhaseField(Phi.Basis); OldPhi = new SinglePhaseField(Phi.Basis); NewPhi = new SinglePhaseField(Phi.Basis); foreach (SinglePhaseField f in new List <SinglePhaseField> { Residual, OldPhi, NewPhi }) { f.Clear(); f.Acc(1.0, Phi); } this.D = LevelSetTracker.GridDat.SpatialDimension; this.ConvergenceCriterion = Control.ConvergenceCriterion; this.MaxIteration = Control.MaxIt; double PenaltyBase = ((double)((Phi.Basis.Degree + 1) * (Phi.Basis.Degree + D))) / ((double)D); // Choose Forms according to Upwinding or Central Fluxes string[] paramNames; int noOfParamFields; IEquationComponent BulkForm; RHSForm myRHSForm; LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, "LevelSetGradient", SinglePhaseField.Factory); MeanLevelSetGradient = new VectorField <SinglePhaseField>(D, new Basis(Phi.GridDat, 0), "MeanLevelSetGradient", SinglePhaseField.Factory); if (Control.Upwinding) { paramNames = new string[] { "OldLevelSet", "MeanLevelSetGradient[0]", "MeanLevelSetGradient[1]" }; noOfParamFields = D; LevelSetGradient.Clear(); LevelSetGradient.Gradient(1.0, Phi); //LevelSetGradient.GradientByFlux(1.0, Phi); MeanLevelSetGradient.Clear(); MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient); parameterFields = ArrayTools.Cat(new SinglePhaseField[] { OldPhi }, MeanLevelSetGradient.ToArray()); //throw new NotImplementedException("ToDO"); BulkForm = new EllipticReInitUpwindForm_Laplace(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck); myRHSForm = new EllipticReInitUpwindForm_RHS(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck); OldDirection = new double[MeanLevelSetGradient.CoordinateVector.ToArray().Length]; for (int i = 0; i < MeanLevelSetGradient.CoordinateVector.Length; i++) { OldDirection[i] = Math.Sign(MeanLevelSetGradient.CoordinateVector[i]); } NewDirection = OldDirection.CloneAs(); } else { paramNames = new string[] { }; noOfParamFields = 0; parameterFields = new SinglePhaseField[] { }; BulkForm = new CentralDifferencesLHSForm(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck.GridDat.Cells.cj); myRHSForm = new CentralDifferencesRHSForm(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck); } // SIP for the bulk Phase //this.Operator_bulk = new SpatialOperator(1, noOfParamFields, 1, QuadOrderFunc.SumOfMaxDegrees(1, RoundUp: false), variableNames); this.Operator_bulk = BulkForm.Operator(); // Zero at the Interface // Calculate Quadrature Order Func <int[], int[], int[], int> InterfaceQuadOrder; InterfaceQuadOrder = QuadOrderFunc.FixedOrder(Phi.Basis.Degree * 2 + 2); // Generate Interface Operator this.Operator_interface = (new EllipticReInitInterfaceForm(Control.PenaltyMultiplierInterface * PenaltyBase, LSTrck)).XOperator(new[] { "A" }, InterfaceQuadOrder); // Nonlinear Part on the RHS // switch for the potential functions switch (Control.Potential) { case ReInitPotential.BastingDoubleWell: { myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.DoubleWell(d, b)); break; }; case ReInitPotential.BastingSingleWell: { myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWell(d, b)); break; }; case ReInitPotential.SingleWellNear: { myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWellNear(d, b)); break; }; case ReInitPotential.P4DoubleWell: { Console.WriteLine("Warning - This Option for Elliptic ReInit does not work well"); myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.DoubleWellAlternative(d, b)); break; }; case ReInitPotential.SingleWellOnCutDoubleWellElse: { myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWellOnCutDoubleWellElse(d, b)); break; } } Operator_RHS = myRHSForm.Operator(QuadOrderFunc.SumOfMaxDegrees(2, RoundUp: true)); // The result of the nonlinear part on the rhs is projected on a single-phase field RHSField = new SinglePhaseField(Phi.Basis, "RHS"); OpMatrix = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping); OpAffine = new double[OpMatrix.RowPartitioning.LocalLength]; // Matrix and RHS for the Bulk component OpMatrix_bulk = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping); OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength]; // Matrix and RHS for the Interface Penalty OpMatrix_interface = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping); OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength]; // Init Parameter Fields OldPhi.Clear(); OldPhi.Acc(1.0, Phi); // Compute Matrices UpdateBulkMatrix(); }
void psiCalcDisplay() { float[][] psi_set; float[] charges, charges_x, charges_y; object[] solution; // vertical_steps=100; //number of eigen energies xmin = -3.78f; xmax = 4.1f; xss = numeric.linspace(-1.0f, 1.0f, num_points); charges = new float[2] { 10, -15 }; charges_x = new float[2] { -0.5f, 0.5f }; charges_y = new float[2] { 0.1f, 0.1f }; dx = (xmax - xmin) / (num_points); solution = (object[])Wavefunction(xmin, xmax, num_points, num_elevel, pe_profile); energy_set = (float[])solution[0]; ArrayTools.Update(energy_set, x => x + yOffset2); psi_set = (float[][])solution[1]; psi_valuesInit = psi_set[E]; lineRenderer.SetVertexCount(psi_valuesInit.Length); // Debug.Log(psi_valuesInit.Length); float a = (E + 1.0f) / num_elevel; // Debug.Log(a); vertical_steps = Mathf.FloorToInt(50.0f / a); psiAnim = psiMotionArray(psi_valuesInit, vertical_steps); probM = prob(psi_valuesInit); cumprob = new float[probM.Length]; cumprob[0] = probM[0]; float sumprob = 0; for (int i = 0; i < probM.Length; i++) { sumprob = sumprob + probM[i]; } for (int i = 1; i < probM.Length; i++) { cumprob[i] = cumprob[i - 1] + probM[i]; } for (int i = 0; i < cumprob.Length; i++) { cumprob[i] = cumprob[i] / sumprob; } EnergyLevels.ePlotsignal = true; this.i = 0; GameObject.Find("Wire").GetComponent <WireColor>().probSignal = true; // Debug.Log(psiAnim.Length); }
public Expression ToExpression(Func <object, Expression> fallbackConverter) { return(New(GetType().GetConstructors()[0], ArrayTools.Empty <Expression>())); }