void Grid::InitializeConnectivity( bool fAllocate ) { // Clear all existing neighbors fro all active patches for (int n = 0; n < m_vecActiveGridPatches.size(); n++) { m_vecActiveGridPatches[n]->m_connect.ClearNeighbors(); } // Loop through all exchange buffers const ExchangeBufferRegistry::ExchangeBufferInfoVector & vecRegistry = m_aExchangeBufferRegistry.GetRegistry(); for (int m = 0; m < vecRegistry.size(); m++) { const ExchangeBufferInfo & info = vecRegistry[m]; // If the GridPatch associated with this exchange buffer is active, // add neighbors GridPatch * pPatch = NULL; for (int n = 0; n < m_vecActiveGridPatches.size(); n++) { if (m_vecActiveGridPatchIndices[n] == info.ixSourcePatch) { pPatch = m_vecActiveGridPatches[n]; break; } } if (pPatch != NULL) { const PatchBox & boxSource = GetPatchBox(info.ixSourcePatch); const PatchBox & boxTarget = GetPatchBox(info.ixTargetPatch); // Build the new ExteriorNeighbor ExteriorNeighbor * pNeighbor = new ExteriorNeighbor(info); if (fAllocate) { m_aExchangeBufferRegistry.Allocate(m); } pNeighbor->AttachBuffers( m_aExchangeBufferRegistry.GetRecvBufferPtr(m), m_aExchangeBufferRegistry.GetSendBufferPtr(m)); pPatch->m_connect.AddExteriorNeighbor(pNeighbor); } } }
int Grid::GetTotalNodeCount( DataLocation loc ) const { // Total number of nodes over all patches of grid int nTotalNodes = 0; // Loop over all patches and obtain total node count for (int n = 0; n < m_aPatchBoxes.GetRows(); n++) { const PatchBox & box = GetPatchBox(n); int nPatchNodes; if (loc == DataLocation_Node) { nPatchNodes = box.GetTotalNodes() * GetRElements(); } else if (loc == DataLocation_REdge) { nPatchNodes = box.GetTotalNodes() * (GetRElements() + 1); } else { _EXCEPTIONT("Invalid location"); } nTotalNodes += nPatchNodes; } return nTotalNodes; }
void Grid::RegisterExchangeBuffer( int ixSourcePatch, int ixTargetPatch, Direction dir ) { const PatchBox & box = GetPatchBox(ixSourcePatch); // First patch coordinate index int ixFirst; int ixSecond; if ((dir == Direction_Right) || (dir == Direction_Left) ) { ixFirst = box.GetBInteriorBegin(); ixSecond = box.GetBInteriorEnd(); } else if ( (dir == Direction_Top) || (dir == Direction_Bottom) ) { ixFirst = box.GetAInteriorBegin(); ixSecond = box.GetAInteriorEnd(); } else if (dir == Direction_TopRight) { ixFirst = box.GetAInteriorEnd()-1; ixSecond = box.GetBInteriorEnd()-1; } else if (dir == Direction_TopLeft) { ixFirst = box.GetAInteriorBegin(); ixSecond = box.GetBInteriorEnd()-1; } else if (dir == Direction_BottomLeft) { ixFirst = box.GetAInteriorBegin(); ixSecond = box.GetBInteriorBegin(); } else if (dir == Direction_BottomRight) { ixFirst = box.GetAInteriorEnd()-1; ixSecond = box.GetBInteriorBegin(); } else { _EXCEPTIONT("Invalid direction"); } // Exterior connect RegisterExchangeBuffer( ixSourcePatch, ixTargetPatch, dir, ixFirst, ixSecond); }
GridPatch * GridCartesianGLL::NewPatch( int ixPatch ) { const PatchBox & box = GetPatchBox(ixPatch); return ( new GridPatchCartesianGLL( (*this), ixPatch, box, m_nHorizontalOrder, m_nVerticalOrder)); }
void Grid::InitializeExchangeBuffersFromPatch( int ixSourcePatch ) { const PatchBox & box = GetPatchBox(ixSourcePatch); // Vector of nodal points around element int nPerimeter = box.GetInteriorPerimeter() + 4; DataArray1D<int> vecIxA(nPerimeter); DataArray1D<int> vecIxB(nPerimeter); DataArray1D<int> vecPanel(nPerimeter); DataArray1D<int> vecPatch(nPerimeter); // Perimeter node index int ix = 0; // Bottom-left corner vecIxA[ix] = box.GetAGlobalInteriorBegin()-1; vecIxB[ix] = box.GetBGlobalInteriorBegin()-1; vecPanel[ix] = box.GetPanel(); ix++; // Bottom edge for (int i = box.GetAGlobalInteriorBegin(); i < box.GetAGlobalInteriorEnd(); i++ ) { vecIxA[ix] = i; vecIxB[ix] = box.GetBGlobalInteriorBegin()-1; vecPanel[ix] = box.GetPanel(); ix++; } // Bottom-right corner vecIxA[ix] = box.GetAGlobalInteriorEnd(); vecIxB[ix] = box.GetBGlobalInteriorBegin()-1; vecPanel[ix] = box.GetPanel(); ix++; // Right edge for (int j = box.GetBGlobalInteriorBegin(); j < box.GetBGlobalInteriorEnd(); j++ ) { vecIxA[ix] = box.GetAGlobalInteriorEnd(); vecIxB[ix] = j; vecPanel[ix] = box.GetPanel(); ix++; } // Top-right corner vecIxA[ix] = box.GetAGlobalInteriorEnd(); vecIxB[ix] = box.GetBGlobalInteriorEnd(); vecPanel[ix] = box.GetPanel(); ix++; // Top edge for (int i = box.GetAGlobalInteriorEnd()-1; i >= box.GetAGlobalInteriorBegin(); i-- ) { vecIxA[ix] = i; vecIxB[ix] = box.GetBGlobalInteriorEnd(); vecPanel[ix] = box.GetPanel(); ix++; } // Top-left corner vecIxA[ix] = box.GetAGlobalInteriorBegin()-1; vecIxB[ix] = box.GetBGlobalInteriorEnd(); vecPanel[ix] = box.GetPanel(); ix++; // Left edge for (int j = box.GetBGlobalInteriorEnd()-1; j >= box.GetBGlobalInteriorBegin(); j-- ) { vecIxA[ix] = box.GetAGlobalInteriorBegin()-1; vecIxB[ix] = j; vecPanel[ix] = box.GetPanel(); ix++; } // Get neighboring patches at each halo node GetPatchFromCoordinateIndex( box.GetRefinementLevel(), vecIxA, vecIxB, vecPanel, vecPatch, ix); // Verify index length if (ix != box.GetInteriorPerimeter() + 4) { _EXCEPTIONT("Index mismatch"); } // Reset index ix = 0; // Add connectivity to bottom-left corner if (vecPatch[ix] != GridPatch::InvalidIndex) { RegisterExchangeBuffer( ixSourcePatch, vecPatch[ix], Direction_BottomLeft); } ix++; // Add connectivity to bottom edge: Look for segments along each // edge that connect to distinct patches and construct corresponding // ExteriorNeighbors. { int ixFirstBegin = box.GetAInteriorBegin(); int iCurrentPatch = vecPatch[ix]; for (int i = ixFirstBegin; i <= box.GetAInteriorEnd(); i++) { if ((i == box.GetAInteriorEnd()) || (vecPatch[ix] != iCurrentPatch) ) { RegisterExchangeBuffer( ixSourcePatch, iCurrentPatch, Direction_Bottom, ixFirstBegin, i); if (i != box.GetAInteriorEnd()) { RegisterExchangeBuffer( ixSourcePatch, iCurrentPatch, Direction_BottomLeft, i, box.GetBInteriorBegin()); ixFirstBegin = i; iCurrentPatch = vecPatch[ix]; RegisterExchangeBuffer( ixSourcePatch, iCurrentPatch, Direction_BottomRight, i - 1, box.GetBInteriorBegin()); } } if (i != box.GetAInteriorEnd()) { ix++; } } } // Add connectivity to bottom-right corner if (vecPatch[ix] != GridPatch::InvalidIndex) { RegisterExchangeBuffer( ixSourcePatch, vecPatch[ix], Direction_BottomRight); } ix++; // Add connectivity to right edge { int ixFirstBegin = box.GetBInteriorBegin(); int iCurrentPatch = vecPatch[ix]; for (int j = ixFirstBegin; j <= box.GetBInteriorEnd(); j++) { if ((j == box.GetBInteriorEnd()) || (vecPatch[ix] != iCurrentPatch) ) { RegisterExchangeBuffer( ixSourcePatch, iCurrentPatch, Direction_Right, ixFirstBegin, j); if (j != box.GetBInteriorEnd()) { RegisterExchangeBuffer( ixSourcePatch, iCurrentPatch, Direction_BottomRight, box.GetAInteriorEnd()-1, j); ixFirstBegin = j; iCurrentPatch = vecPatch[ix]; RegisterExchangeBuffer( ixSourcePatch, iCurrentPatch, Direction_TopRight, box.GetAInteriorEnd()-1, j - 1); } } if (j != box.GetBInteriorEnd()) { ix++; } } } // Add connectivity to top-right corner if (vecPatch[ix] != GridPatch::InvalidIndex) { RegisterExchangeBuffer( ixSourcePatch, vecPatch[ix], Direction_TopRight); } ix++; // Add connectivity to top edge { int ixFirstEnd = box.GetAInteriorEnd(); int iCurrentPatch = vecPatch[ix]; for (int i = ixFirstEnd-1; i >= box.GetAInteriorBegin()-1; i--) { if ((i == box.GetAInteriorBegin()-1) || (vecPatch[ix] != iCurrentPatch) ) { RegisterExchangeBuffer( ixSourcePatch, iCurrentPatch, Direction_Top, i + 1, ixFirstEnd); if (i != box.GetAInteriorBegin()-1) { RegisterExchangeBuffer( ixSourcePatch, iCurrentPatch, Direction_TopRight, i, box.GetBInteriorEnd()-1); ixFirstEnd = i + 1; iCurrentPatch = vecPatch[ix]; RegisterExchangeBuffer( ixSourcePatch, iCurrentPatch, Direction_TopLeft, i + 1, box.GetBInteriorEnd()-1); } } if (i != box.GetAInteriorBegin()-1) { ix++; } } } // Add connectivity to top-left corner if (vecPatch[ix] != GridPatch::InvalidIndex) { RegisterExchangeBuffer( ixSourcePatch, vecPatch[ix], Direction_TopLeft); } ix++; // Add connectivity to top edge { int ixFirstEnd = box.GetBInteriorEnd(); int iCurrentPatch = vecPatch[ix]; for (int j = ixFirstEnd-1; j >= box.GetBInteriorBegin()-1; j--) { if ((j == box.GetBInteriorBegin()-1) || (vecPatch[ix] != iCurrentPatch) ) { RegisterExchangeBuffer( ixSourcePatch, iCurrentPatch, Direction_Left, j + 1, ixFirstEnd); if (j != box.GetBInteriorBegin()-1) { RegisterExchangeBuffer( ixSourcePatch, iCurrentPatch, Direction_TopLeft, box.GetAInteriorBegin(), j); ixFirstEnd = j + 1; iCurrentPatch = vecPatch[ix]; RegisterExchangeBuffer( ixSourcePatch, iCurrentPatch, Direction_BottomLeft, box.GetAInteriorBegin(), j + 1); } } if (j != box.GetBInteriorBegin()-1) { ix++; } } } // Verify index length if (ix != box.GetInteriorPerimeter() + 4) { _EXCEPTIONT("Index mismatch"); } }
void Grid::RegisterExchangeBuffer( int ixSourcePatch, int ixTargetPatch, Direction dir, int ixFirst, int ixSecond ) { if (ixSourcePatch == GridPatch::InvalidIndex) { _EXCEPTIONT("Invalid ixSourcePatch"); } // Check for NULL patches (do nothing) if (ixTargetPatch == GridPatch::InvalidIndex) { return; } // Get the GridPatch's PatchBox const PatchBox & boxSource = GetPatchBox(ixSourcePatch); const PatchBox & boxTarget = GetPatchBox(ixTargetPatch); // Build key ExchangeBufferInfo info; info.ixSourcePatch = ixSourcePatch; info.ixTargetPatch = ixTargetPatch; info.dir = dir; // Build exhange buffer metadata info.ixFirst = ixFirst; info.ixSecond = ixSecond; // Get number of components const Model & model = GetModel(); const EquationSet & eqn = model.GetEquationSet(); size_t sStateTracerMaxVariables; if (eqn.GetComponents() > eqn.GetTracers()) { sStateTracerMaxVariables = eqn.GetComponents(); } else { sStateTracerMaxVariables = eqn.GetTracers(); } info.sHaloElements = model.GetHaloElements(); info.sComponents = sStateTracerMaxVariables; info.sMaxRElements = GetRElements() + 1; // Get the opposing direction GetOpposingDirection( boxSource.GetPanel(), boxTarget.GetPanel(), dir, info.dirOpposing, info.fReverseDirection, info.fFlippedCoordinate); // Determine the size of the boundary (number of elements along exterior // edge). Used in computing the size of the send/recv buffers. if ((dir == Direction_Right) || (dir == Direction_Top) || (dir == Direction_Left) || (dir == Direction_Bottom) ) { info.sBoundarySize = ixSecond - ixFirst; } else { info.sBoundarySize = info.sHaloElements; } info.CalculateByteSize(); if ((dir == Direction_TopRight) && ( (ixFirst < boxSource.GetAInteriorBegin() + info.sBoundarySize - 1) || (ixSecond < boxSource.GetBInteriorBegin() + info.sBoundarySize - 1) )) { _EXCEPTIONT("Insufficient interior elements to build " "diagonal connection."); } if ((dir == Direction_TopLeft) && ( (ixFirst > boxSource.GetAInteriorEnd() - info.sBoundarySize) || (ixSecond < boxSource.GetBInteriorBegin() + info.sBoundarySize - 1) )) { _EXCEPTIONT("Insufficient interior elements to build " "diagonal connection."); } if ((dir == Direction_BottomLeft) && ( (ixFirst > boxSource.GetAInteriorEnd() - info.sBoundarySize) || (ixSecond > boxSource.GetBInteriorEnd() - info.sBoundarySize) )) { _EXCEPTIONT("Insufficient interior elements to build " "diagonal connection."); } if ((dir == Direction_BottomRight) && ( (ixFirst < boxSource.GetAInteriorBegin() + info.sBoundarySize - 1) || (ixSecond > boxSource.GetBInteriorEnd() - info.sBoundarySize) )) { _EXCEPTIONT("Insufficient interior elements to build " "diagonal connection."); } // Add the exchange buffer information to the registry m_aExchangeBufferRegistry.Register(info); }
void GridPatchCSGLL::InterpolateData( DataType eDataType, const DataArray1D<double> & dREta, const DataArray1D<double> & dAlpha, const DataArray1D<double> & dBeta, const DataArray1D<int> & iPatch, DataArray3D<double> & dInterpData, DataLocation eOnlyVariablesAt, bool fIncludeReferenceState, bool fConvertToPrimitive ) { if ((dAlpha.GetRows() != dBeta.GetRows()) || (dAlpha.GetRows() != iPatch.GetRows()) ) { _EXCEPTIONT("Point vectors must have equivalent length."); } // Vector for storage interpolated points DataArray1D<double> dAInterpCoeffs(m_nHorizontalOrder); DataArray1D<double> dBInterpCoeffs(m_nHorizontalOrder); DataArray1D<double> dADiffCoeffs(m_nHorizontalOrder); DataArray1D<double> dBDiffCoeffs(m_nHorizontalOrder); DataArray1D<double> dAInterpPt(m_nHorizontalOrder); // Physical constants const PhysicalConstants & phys = m_grid.GetModel().GetPhysicalConstants(); // Perform interpolation on all variables int nComponents = 0; int nRElements = m_grid.GetRElements(); // Discretization type Grid::VerticalDiscretization eVerticalDiscType = m_grid.GetVerticalDiscretization(); // State Data: Perform interpolation on all variables if (eDataType == DataType_State) { nComponents = m_datavecStateNode[0].GetSize(0); nRElements = m_grid.GetRElements() + 1; // Tracer Data: Perform interpolation on all variables } else if (eDataType == DataType_Tracers) { nComponents = m_datavecTracers[0].GetSize(0); // Topography Data } else if (eDataType == DataType_Topography) { nComponents = 1; nRElements = 1; // Vorticity Data } else if (eDataType == DataType_Vorticity) { nComponents = 1; // Divergence Data } else if (eDataType == DataType_Divergence) { nComponents = 1; // Temperature Data } else if (eDataType == DataType_Temperature) { nComponents = 1; // Surface Pressure Data } else if (eDataType == DataType_SurfacePressure) { nComponents = 1; nRElements = 1; // 2D User Data } else if (eDataType == DataType_Auxiliary2D) { nComponents = m_dataUserData2D.GetSize(0); nRElements = 1; } else { _EXCEPTIONT("Invalid DataType"); } // Buffer storage in column DataArray1D<double> dColumnDataOut(dREta.GetRows()); // Loop through all components for (int c = 0; c < nComponents; c++) { DataLocation eDataLocation = DataLocation_Node; if (eDataType == DataType_State) { eDataLocation = m_grid.GetVarLocation(c); // Exclude variables not at the specified DataLocation if ((eOnlyVariablesAt != DataLocation_None) && (eOnlyVariablesAt != eDataLocation) ) { continue; } // Adjust RElements depending on state data location if (eDataLocation == DataLocation_Node) { nRElements = m_grid.GetRElements(); } else if (eDataLocation == DataLocation_REdge) { nRElements = m_grid.GetRElements() + 1; } else { _EXCEPTIONT("Invalid DataLocation"); } } // Vertical interpolation operator LinearColumnInterpFEM opInterp; if (nRElements != 1) { // Finite element interpolation if (eVerticalDiscType == Grid::VerticalDiscretization_FiniteElement ) { if (eDataLocation == DataLocation_Node) { opInterp.Initialize( LinearColumnInterpFEM::InterpSource_Levels, m_nVerticalOrder, m_grid.GetREtaLevels(), m_grid.GetREtaInterfaces(), dREta); } else if (eDataLocation == DataLocation_REdge) { opInterp.Initialize( LinearColumnInterpFEM::InterpSource_Interfaces, m_nVerticalOrder, m_grid.GetREtaLevels(), m_grid.GetREtaInterfaces(), dREta); } else { _EXCEPTIONT("Invalid DataLocation"); } // Finite volume interpolation } else if ( eVerticalDiscType == Grid::VerticalDiscretization_FiniteVolume ) { if (eDataLocation == DataLocation_Node) { opInterp.Initialize( LinearColumnInterpFEM::InterpSource_Levels, 1, m_grid.GetREtaLevels(), m_grid.GetREtaInterfaces(), dREta); } else if (eDataLocation == DataLocation_REdge) { opInterp.Initialize( LinearColumnInterpFEM::InterpSource_Interfaces, 1, m_grid.GetREtaLevels(), m_grid.GetREtaInterfaces(), dREta); } else { _EXCEPTIONT("Invalid DataLocation"); } // Invalid vertical discretization type } else { _EXCEPTIONT("Invalid VerticalDiscretization"); } } else { opInterp.InitializeIdentity(1); } // Buffer storage in column DataArray1D<double> dColumnData(nRElements); // Get a pointer to the 3D data structure DataArray3D<double> pData; DataArray3D<double> pDataRef; pData.SetSize( nRElements, m_box.GetATotalWidth(), m_box.GetBTotalWidth()); pDataRef.SetSize( nRElements, m_box.GetATotalWidth(), m_box.GetBTotalWidth()); if (eDataType == DataType_State) { if (eDataLocation == DataLocation_Node) { pData.AttachToData(&(m_datavecStateNode[0][c][0][0][0])); pDataRef.AttachToData(&(m_dataRefStateNode[c][0][0][0])); } else if (eDataLocation == DataLocation_REdge) { pData.AttachToData(&(m_datavecStateREdge[0][c][0][0][0])); pDataRef.AttachToData(&(m_dataRefStateREdge[c][0][0][0])); } else { _EXCEPTIONT("Invalid DataLocation"); } } else if (eDataType == DataType_Tracers) { pData.AttachToData(&(m_datavecTracers[0][c][0][0][0])); } else if (eDataType == DataType_Topography) { pData.AttachToData(&(m_dataTopography[0][0])); } else if (eDataType == DataType_Vorticity) { pData.AttachToData(&(m_dataVorticity[0][0][0])); } else if (eDataType == DataType_Divergence) { pData.AttachToData(&(m_dataDivergence[0][0][0])); } else if (eDataType == DataType_Temperature) { pData.AttachToData(&(m_dataTemperature[0][0][0])); } else if (eDataType == DataType_SurfacePressure) { pData.AttachToData(&(m_dataSurfacePressure[0][0])); } else if (eDataType == DataType_Auxiliary2D) { pData.AttachToData(&(m_dataUserData2D[c][0][0])); } // Loop throught all points for (int i = 0; i < dAlpha.GetRows(); i++) { // Element index if (iPatch[i] != GetPatchIndex()) { continue; } // Verify point lies within domain of patch const double Eps = 1.0e-10; if ((dAlpha[i] < m_dAEdge[m_box.GetAInteriorBegin()] - Eps) || (dAlpha[i] > m_dAEdge[m_box.GetAInteriorEnd()] + Eps) || (dBeta[i] < m_dBEdge[m_box.GetBInteriorBegin()] - Eps) || (dBeta[i] > m_dBEdge[m_box.GetBInteriorEnd()] + Eps) ) { _EXCEPTIONT("Point out of range"); } // Determine finite element index int iA = (dAlpha[i] - m_dAEdge[m_box.GetAInteriorBegin()]) / GetElementDeltaA(); int iB = (dBeta[i] - m_dBEdge[m_box.GetBInteriorBegin()]) / GetElementDeltaB(); // Bound the index within the element if (iA < 0) { iA = 0; } if (iA >= (m_box.GetAInteriorWidth() / m_nHorizontalOrder)) { iA = m_box.GetAInteriorWidth() / m_nHorizontalOrder - 1; } if (iB < 0) { iB = 0; } if (iB >= (m_box.GetBInteriorWidth() / m_nHorizontalOrder)) { iB = m_box.GetBInteriorWidth() / m_nHorizontalOrder - 1; } iA = m_box.GetHaloElements() + iA * m_nHorizontalOrder; iB = m_box.GetHaloElements() + iB * m_nHorizontalOrder; // Compute interpolation coefficients PolynomialInterp::LagrangianPolynomialCoeffs( m_nHorizontalOrder, &(m_dAEdge[iA]), dAInterpCoeffs, dAlpha[i]); PolynomialInterp::LagrangianPolynomialCoeffs( m_nHorizontalOrder, &(m_dBEdge[iB]), dBInterpCoeffs, dBeta[i]); // Perform interpolation on all levels for (int k = 0; k < nRElements; k++) { dColumnData[k] = 0.0; // Rescale vertical velocity const int WIx = 3; if ((c == WIx) && (fConvertToPrimitive)) { if (m_grid.GetVarLocation(WIx) == DataLocation_REdge) { for (int m = 0; m < m_nHorizontalOrder; m++) { for (int n = 0; n < m_nHorizontalOrder; n++) { dColumnData[k] += dAInterpCoeffs[m] * dBInterpCoeffs[n] * pData[k][iA+m][iB+n] / m_dataDerivRREdge[k][iA][iB][2]; } } } else { for (int m = 0; m < m_nHorizontalOrder; m++) { for (int n = 0; n < m_nHorizontalOrder; n++) { dColumnData[k] += dAInterpCoeffs[m] * dBInterpCoeffs[n] * pData[k][iA+m][iB+n] / m_dataDerivRNode[k][iA][iB][2]; } } } } else { for (int m = 0; m < m_nHorizontalOrder; m++) { for (int n = 0; n < m_nHorizontalOrder; n++) { dColumnData[k] += dAInterpCoeffs[m] * dBInterpCoeffs[n] * pData[k][iA+m][iB+n]; } } } // Do not include the reference state if ((eDataType == DataType_State) && (!fIncludeReferenceState) ) { for (int m = 0; m < m_nHorizontalOrder; m++) { for (int n = 0; n < m_nHorizontalOrder; n++) { dColumnData[k] -= dAInterpCoeffs[m] * dBInterpCoeffs[n] * pDataRef[k][iA+m][iB+n]; } } } } // Interpolate vertically opInterp.Apply( &(dColumnData[0]), &(dColumnDataOut[0])); // Store data for (int k = 0; k < dREta.GetRows(); k++) { dInterpData[c][k][i] = dColumnDataOut[k]; } } } // Convert to primitive variables if ((eDataType == DataType_State) && (fConvertToPrimitive)) { for (int i = 0; i < dAlpha.GetRows(); i++) { if (iPatch[i] != GetPatchIndex()) { continue; } for (int k = 0; k < dREta.GetRows(); k++) { double dUalpha = dInterpData[0][k][i] / phys.GetEarthRadius(); double dUbeta = dInterpData[1][k][i] / phys.GetEarthRadius(); CubedSphereTrans::CoVecTransRLLFromABP( tan(dAlpha[i]), tan(dBeta[i]), GetPatchBox().GetPanel(), dUalpha, dUbeta, dInterpData[0][k][i], dInterpData[1][k][i]); } } } }