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;
}
Пример #2
0
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");
		}
	}
}
Пример #3
0
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]);
		}
	}
}
Пример #4
0
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;
}