void GridCartesianGLL::ApplyDefaultPatchLayout( int nPatchCount ) { // Verify patch count is positive if (nPatchCount < 1) { _EXCEPTIONT("nPatchCount must be a positive integer"); } // Verify no Patches have been previously added if (m_nInitializedPatchBoxes != 0) { _EXCEPTIONT("ApplyDefaultPatchLayout() must be called on an empty Grid"); } // Determine number of usable processors int nProcsPerDirection = nPatchCount; int nDistributedPatches = nProcsPerDirection; // Determine arrangement of elements on processors if (GetABaseResolution() % nProcsPerDirection != 0) { _EXCEPTIONT("\n(UNIMPLEMENTED) Currently elements must be " "equally divided among processors."); } int nElementsPerDirection = GetABaseResolution() / nProcsPerDirection; DataArray1D<int> iBoxBegin(nProcsPerDirection + 1); iBoxBegin[0] = 0; for (int n = 1; n < nProcsPerDirection; n++) { iBoxBegin[n] = n * nElementsPerDirection; } iBoxBegin[nProcsPerDirection] = GetABaseResolution(); // Single panel 0 implementation (Cartesian Grid) // Rectangular alpha-wise patches that span all of the beta direction // (as many as there are processors available) for (int i = 0; i < nProcsPerDirection; i++) { // Patch strips that span beta m_aPatchBoxes[i] = PatchBox( 0, 0, m_model.GetHaloElements(), m_nHorizontalOrder * iBoxBegin[i], m_nHorizontalOrder * iBoxBegin[i+1], 0, m_nHorizontalOrder * GetBBaseResolution()); } m_nInitializedPatchBoxes = nProcsPerDirection; }
void GridCartesianGLL::GetPatchFromCoordinateIndex( int iRefinementLevel, const DataArray1D<int> & vecIxA, const DataArray1D<int> & vecIxB, const DataArray1D<int> & vecPanel, DataArray1D<int> & vecPatchIndex, int nVectorLength ) { // Set vector length if (nVectorLength == (-1)) { nVectorLength = vecIxA.GetRows(); } //std::cout << GetPatchCount() << '\n'; // Check arguments if ((vecIxA.GetRows() < nVectorLength) || (vecIxB.GetRows() < nVectorLength) || (vecPanel.GetRows() < nVectorLength) ) { _EXCEPTIONT("Argument vector length mismatch"); } if (iRefinementLevel < 0) { _EXCEPTIONT("Refinement level must be positive"); } // Calculate local resolution int nLocalResolutionA = m_nHorizontalOrder * GetABaseResolution(iRefinementLevel); int nLocalResolutionB = m_nHorizontalOrder * GetBBaseResolution(iRefinementLevel); // Loop through all entries int iLastPatch = GridPatch::InvalidIndex; for (int i = 0; i < nVectorLength; i++) { int iA = vecIxA[i]; int iB = vecIxB[i]; int iP = 0; // Wrap global indices if (iA < 0) { BoundaryCondition eLeftBoundary = m_eBoundaryCondition[Direction_Left]; if (eLeftBoundary == BoundaryCondition_Periodic) { iA += nLocalResolutionA; } else { vecPatchIndex[i] = GridPatch::InvalidIndex; continue; } } if (iA >= nLocalResolutionA) { BoundaryCondition eRightBoundary = m_eBoundaryCondition[Direction_Right]; if (eRightBoundary == BoundaryCondition_Periodic) { iA -= nLocalResolutionA; } else { vecPatchIndex[i] = GridPatch::InvalidIndex; continue; } } if (iB < 0) { BoundaryCondition eBottomBoundary = m_eBoundaryCondition[Direction_Bottom]; if (eBottomBoundary == BoundaryCondition_Periodic) { iB += nLocalResolutionB; } else { vecPatchIndex[i] = GridPatch::InvalidIndex; continue; } } if (iB >= nLocalResolutionB) { BoundaryCondition eTopBoundary = m_eBoundaryCondition[Direction_Top]; if (eTopBoundary == BoundaryCondition_Periodic) { iB -= nLocalResolutionB; } else { vecPatchIndex[i] = GridPatch::InvalidIndex; continue; } } // Check the last patch searched if (iLastPatch != GridPatch::InvalidIndex) { const PatchBox & box = m_aPatchBoxes[iLastPatch]; if (box.ContainsGlobalPoint(iP, iA, iB)) { vecPatchIndex[i] = iLastPatch; continue; } } // Check all other patches int n; for (n = 0; n < GetPatchCount(); n++) { const PatchBox & box = m_aPatchBoxes[n]; if (box.ContainsGlobalPoint(iP, iA, iB)) { vecPatchIndex[i] = n; iLastPatch = n; break; } } if (n == GetPatchCount()) { vecPatchIndex[i] = GridPatch::InvalidIndex; _EXCEPTIONT("(LOGIC ERROR) Invalid global coordinate"); } } }
void GridCartesianGLL::ConvertReferenceToPatchCoord( const DataArray1D<double> & dXReference, const DataArray1D<double> & dYReference, DataArray1D<double> & dAlpha, DataArray1D<double> & dBeta, DataArray1D<int> & iPatch ) const { // No conversion needed for cartesian grid but left the dimension check if ((dXReference.GetRows() != dYReference.GetRows()) || (dXReference.GetRows() != dAlpha.GetRows()) || (dXReference.GetRows() != dBeta.GetRows()) || (dXReference.GetRows() != iPatch.GetRows()) ) { _EXCEPTIONT("Dimension mismatch: All arrays must have same length"); } // Loop over all coordinates for (int i = 0; i < dXReference.GetRows(); i++) { // Reference and computational coordinates are the same dAlpha[i] = dXReference[i]; dBeta[i] = dYReference[i]; // Loop over all patches int n = 0; for (; n < GetPatchCount(); n++) { const PatchBox & box = m_aPatchBoxes[n]; double dElementDeltaA = (m_dGDim[1] - m_dGDim[0]) / static_cast<double>(GetABaseResolution()); double dElementDeltaB = (m_dGDim[3] - m_dGDim[2]) / static_cast<double>(GetBBaseResolution()); int iAElementInteriorBegin = box.GetAGlobalInteriorBegin() / m_nHorizontalOrder; int iAElementInteriorEnd = box.GetAGlobalInteriorEnd() / m_nHorizontalOrder; int iBElementInteriorBegin = box.GetBGlobalInteriorBegin() / m_nHorizontalOrder; int iBElementInteriorEnd = box.GetBGlobalInteriorEnd() / m_nHorizontalOrder; if ((box.GetAGlobalInteriorBegin() % m_nHorizontalOrder != 0) || (box.GetAGlobalInteriorEnd() % m_nHorizontalOrder != 0) || (box.GetBGlobalInteriorBegin() % m_nHorizontalOrder != 0) || (box.GetBGlobalInteriorEnd() % m_nHorizontalOrder != 0) ) { _EXCEPTIONT("Elements must be aligned with HorizontalOrder"); } double dAInteriorBegin = m_dGDim[0] + iAElementInteriorBegin * dElementDeltaA; double dAInteriorEnd = m_dGDim[0] + iAElementInteriorEnd * dElementDeltaA; double dBInteriorBegin = m_dGDim[2] + iBElementInteriorBegin * dElementDeltaB; double dBInteriorEnd = m_dGDim[2] + iBElementInteriorEnd * dElementDeltaB; if ((dAlpha[i] >= dAInteriorBegin) && (dAlpha[i] <= dAInteriorEnd) && (dBeta[i] >= dBInteriorBegin) && (dBeta[i] <= dBInteriorEnd) ) { iPatch[i] = n; break; } } if (n == GetPatchCount()) { _EXCEPTION4("Unable to find associated patch for node:\n" "(%1.5e, %1.5e) : (%1.5e, %1.5e)", dXReference[i], dYReference[i], dAlpha[i], dBeta[i]); } } }
void GridCartesianGLL::ApplyDefaultPatchLayout( int nPatchCount ) { // Verify patch count is positive if (nPatchCount < 1) { _EXCEPTIONT("nPatchCount must be a positive integer"); } // Verify no Patches have been previously added if (m_nInitializedPatchBoxes != 0) { _EXCEPTIONT("ApplyDefaultPatchLayout() must be called on an empty Grid"); } // Determine number of usable processors int nProcsPerDirection = nPatchCount; int nDistributedPatches = nProcsPerDirection; // Determine arrangement of elements on processors // SINGLE RECTANGULAR PATCH if (GetABaseResolution() * GetBBaseResolution() % nProcsPerDirection != 0) { _EXCEPTIONT("\n(UNIMPLEMENTED) Currently Alpha-Beta elements must be " "equally divided among processors."); } bool fCartXZ = GetIsCartesianXZ(); int nProcsADirection = 0; int nProcsBDirection = 0; // Handle special case of 2 or 3 processors (laptop testing) if (fCartXZ || (nDistributedPatches < 4)) { nProcsADirection = nProcsPerDirection; nProcsBDirection = 1; } /* // Allow 3D cases to split the Beta elements once (EVEN NUMBER OF PROCESSORS) else if (!fCartXZ && (nProcsPerDirection % 2 == 0)) { # pragma message "3D Cartesian processor layout..." nProcsADirection = (int) (nProcsPerDirection / 2); nProcsBDirection = 2; } else if (!fCartXZ && (nProcsADirection * nProcsBDirection != nDistributedPatches)) { _EXCEPTIONT("Even number of processors required" "for 3D Cartesian cases."); } */ // Default to alpha wise strips else { nProcsADirection = nProcsPerDirection; nProcsBDirection = 1; } //nProcsADirection = nProcsPerDirection; //nProcsBDirection = 1; int nElementsPerDirectionA = GetABaseResolution() / nProcsADirection; DataArray1D<int> iBoxBeginA(nProcsADirection + 1); int nElementsPerDirectionB = GetBBaseResolution() / nProcsBDirection; DataArray1D<int> iBoxBeginB(nProcsBDirection + 1); // Set the patch array for Alpha iBoxBeginA[0] = 0; for (int n = 1; n < nProcsADirection; n++) { iBoxBeginA[n] = n * nElementsPerDirectionA; } iBoxBeginA[nProcsADirection] = GetABaseResolution(); // Set the patch array for Beta iBoxBeginB[0] = 0; for (int n = 1; n < nProcsBDirection; n++) { iBoxBeginB[n] = n * nElementsPerDirectionB; } iBoxBeginB[nProcsBDirection] = GetBBaseResolution(); /* // Single panel 0 implementation (Cartesian Grid) // Rectangular alpha-wise patches that span all of the beta direction // (as many as there are processors available) for (int i = 0; i < nProcsPerDirection; i++) { // Patch strips that span beta m_aPatchBoxes[i] = PatchBox( 0, 0, m_model.GetHaloElements(), m_nHorizontalOrder * iBoxBegin[i], m_nHorizontalOrder * iBoxBegin[i+1], 0, m_nHorizontalOrder * GetBBaseResolution()); } */ // Create master patch for each panel int ixPatch = 0; for (int i = 0; i < nProcsADirection; i++) { for (int j = 0; j < nProcsBDirection; j++) { m_aPatchBoxes[ixPatch] = PatchBox( 0, 0, m_model.GetHaloElements(), m_nHorizontalOrder * iBoxBeginA[i], m_nHorizontalOrder * iBoxBeginA[i+1], m_nHorizontalOrder * iBoxBeginB[j], m_nHorizontalOrder * iBoxBeginB[j+1]); ixPatch++; } } m_nInitializedPatchBoxes = ixPatch; }