void GridPatchCartesianGLL::EvaluateTopography( const TestCase & test ) { const PhysicalConstants & phys = m_grid.GetModel().GetPhysicalConstants(); // Compute values of topography for (int i = 0; i < m_box.GetATotalWidth(); i++) { for (int j = 0; j < m_box.GetBTotalWidth(); j++) { double dX = m_box.GetANode(i); double dY = m_box.GetBNode(j); m_dataTopography[i][j] = test.EvaluateTopography(phys, dX, dY); if (m_dataTopography[i][j] >= m_grid.GetZtop()) { _EXCEPTIONT("TestCase topography exceeds model top."); } } } // Get derivatves from basis GridCartesianGLL & gridCartesianGLL = dynamic_cast<GridCartesianGLL &>(m_grid); const DataMatrix<double> & dDxBasis1D = gridCartesianGLL.GetDxBasis1D(); // Compute derivatives of topography for (int a = 0; a < GetElementCountA(); a++) { for (int b = 0; b < GetElementCountB(); b++) { for (int i = 0; i < m_nHorizontalOrder; i++) { for (int j = 0; j < m_nHorizontalOrder; j++) { // Nodal points int iElementA = m_box.GetAInteriorBegin() + a * m_nHorizontalOrder; int iElementB = m_box.GetBInteriorBegin() + b * m_nHorizontalOrder; int iA = iElementA + i; int iB = iElementB + j; // Topography height and its derivatives double dZs = m_dataTopography[iA][iB]; double dDaZs = 0.0; double dDbZs = 0.0; for (int s = 0; s < m_nHorizontalOrder; s++) { dDaZs += dDxBasis1D[s][i] * m_dataTopography[iElementA+s][iB]; dDbZs += dDxBasis1D[s][j] * m_dataTopography[iA][iElementB+s]; } dDaZs /= GetElementDeltaA(); dDbZs /= GetElementDeltaB(); m_dataTopographyDeriv[0][iA][iB] = dDaZs; m_dataTopographyDeriv[1][iA][iB] = dDbZs; } } } } }
void GridPatchCartesianGLL::EvaluateTestCase( const TestCase & test, const Time & time, int iDataIndex ) { // Initialize the data at each node if (m_datavecStateNode.size() == 0) { _EXCEPTIONT("InitializeData must be called before InitialConditions"); } if (iDataIndex >= m_datavecStateNode.size()) { _EXCEPTIONT("Invalid iDataIndex (out of range)"); } // Check dimensionality if ((m_grid.GetModel().GetEquationSet().GetDimensionality() == 2) && (m_nVerticalOrder != 1) ) { _EXCEPTIONT("VerticalOrder / Dimensionality mismatch:\n" "For 2D problems vertical order must be 1."); } // Evaluate topography EvaluateTopography(test); // Physical constants const PhysicalConstants & phys = m_grid.GetModel().GetPhysicalConstants(); // Initialize the topography at each node for (int i = 0; i < m_box.GetATotalWidth(); i++) { for (int j = 0; j < m_box.GetBTotalWidth(); j++) { m_dataTopography[i][j] = test.EvaluateTopography( phys, m_dataLon[i][j], m_dataLat[i][j]); if (m_dataTopography[i][j] >= m_grid.GetZtop()) { _EXCEPTIONT("TestCase topography exceeds model top."); } // Gal-Chen and Sommerville vertical coordinate for (int k = 0; k < m_grid.GetRElements(); k++) { m_dataZLevels[k][i][j] = m_dataTopography[i][j] + m_grid.GetREtaLevel(k) * (m_grid.GetZtop() - m_dataTopography[i][j]); } for (int k = 0; k <= m_grid.GetRElements(); k++) { m_dataZInterfaces[k][i][j] = m_dataTopography[i][j] + m_grid.GetREtaInterface(k) * (m_grid.GetZtop() - m_dataTopography[i][j]); } /* // Schar Exponential Decay vertical coordinate for (int k = 0; k < m_grid.GetRElements(); k++) { m_dataZLevels[k][i][j] = m_grid.GetZtop() * m_grid.GetREtaLevel(k) + m_dataTopography[i][j] * sinh(m_grid.GetZtop() * (1.0 - m_grid.GetREtaLevel(k)) / m_dSL) / sinh(m_grid.GetZtop() / m_dSL); } for (int k = 0; k <= m_grid.GetRElements(); k++) { m_dataZInterfaces[k][i][j] = m_grid.GetZtop() * m_grid.GetREtaInterface(k) + m_dataTopography[i][j] * sinh(m_grid.GetZtop() * (1.0 - m_grid.GetREtaInterface(k)) / m_dSL) / sinh(m_grid.GetZtop() / m_dSL); } */ } } // Initialize the Rayleigh friction strength at each node if (test.HasRayleighFriction()) { for (int i = 0; i < m_box.GetATotalWidth(); i++) { for (int j = 0; j < m_box.GetBTotalWidth(); j++) { for (int k = 0; k < m_grid.GetRElements(); k++) { m_dataRayleighStrengthNode[k][i][j] = test.EvaluateRayleighStrength( m_dataZLevels[k][i][j], m_dataLon[i][j], m_dataLat[i][j]); } for (int k = 0; k < m_grid.GetRElements(); k++) { m_dataRayleighStrengthREdge[k][i][j] = test.EvaluateRayleighStrength( m_dataZInterfaces[k][i][j], m_dataLon[i][j], m_dataLat[i][j]); } } } } // Buffer vector for storing pointwise states const EquationSet & eqns = m_grid.GetModel().GetEquationSet(); int nComponents = eqns.GetComponents(); int nTracers = eqns.GetTracers(); DataVector<double> dPointwiseState; dPointwiseState.Initialize(nComponents); DataVector<double> dPointwiseRefState; dPointwiseRefState.Initialize(nComponents); DataVector<double> dPointwiseTracers; if (m_datavecTracers.size() > 0) { dPointwiseTracers.Initialize(nTracers); } // Evaluate the state on model levels for (int k = 0; k < m_grid.GetRElements(); k++) { for (int i = 0; i < m_box.GetATotalWidth(); i++) { for (int j = 0; j < m_box.GetBTotalWidth(); j++) { // Evaluate pointwise state test.EvaluatePointwiseState( m_grid.GetModel().GetPhysicalConstants(), time, m_dataZLevels[k][i][j], m_dataLon[i][j], m_dataLat[i][j], dPointwiseState, dPointwiseTracers); eqns.ConvertComponents(phys, dPointwiseState); for (int c = 0; c < dPointwiseState.GetRows(); c++) { m_datavecStateNode[iDataIndex][c][k][i][j] = dPointwiseState[c]; } // Evaluate reference state if (m_grid.HasReferenceState()) { test.EvaluateReferenceState( m_grid.GetModel().GetPhysicalConstants(), m_dataZLevels[k][i][j], m_dataLon[i][j], m_dataLat[i][j], dPointwiseRefState); eqns.ConvertComponents(phys, dPointwiseRefState); for (int c = 0; c < dPointwiseState.GetRows(); c++) { m_dataRefStateNode[c][k][i][j] = dPointwiseRefState[c]; } } // Evaluate tracers for (int c = 0; c < dPointwiseTracers.GetRows(); c++) { m_datavecTracers[iDataIndex][c][k][i][j] = dPointwiseTracers[c]; } } } } // Evaluate the state on model interfaces for (int k = 0; k <= m_grid.GetRElements(); k++) { for (int i = 0; i < m_box.GetATotalWidth(); i++) { for (int j = 0; j < m_box.GetBTotalWidth(); j++) { // Evaluate pointwise state test.EvaluatePointwiseState( phys, time, m_dataZInterfaces[k][i][j], m_dataLon[i][j], m_dataLat[i][j], dPointwiseState, dPointwiseTracers); eqns.ConvertComponents(phys, dPointwiseState); for (int c = 0; c < dPointwiseState.GetRows(); c++) { m_datavecStateREdge[iDataIndex][c][k][i][j] = dPointwiseState[c]; } if (m_grid.HasReferenceState()) { test.EvaluateReferenceState( phys, m_dataZInterfaces[k][i][j], m_dataLon[i][j], m_dataLat[i][j], dPointwiseRefState); eqns.ConvertComponents(phys, dPointwiseRefState); for (int c = 0; c < dPointwiseState.GetRows(); c++) { m_dataRefStateREdge[c][k][i][j] = dPointwiseRefState[c]; } } } } } }
void GridPatchCSGLL::EvaluateTopography( const TestCase & test ) { const PhysicalConstants & phys = m_grid.GetModel().GetPhysicalConstants(); // Compute values of topography for (int i = 0; i < m_box.GetATotalWidth(); i++) { for (int j = 0; j < m_box.GetBTotalWidth(); j++) { double dLon; double dLat; CubedSphereTrans::RLLFromABP( m_dANode[i], m_dBNode[j], m_box.GetPanel(), dLon, dLat); m_dataTopography[i][j] = test.EvaluateTopography(phys, dLon, dLat); } } // Get derivatves from basis GridCSGLL & gridCSGLL = dynamic_cast<GridCSGLL &>(m_grid); const DataArray2D<double> & dDxBasis1D = gridCSGLL.GetDxBasis1D(); // Compute derivatives of topography for (int a = 0; a < GetElementCountA(); a++) { for (int b = 0; b < GetElementCountB(); b++) { for (int i = 0; i < m_nHorizontalOrder; i++) { for (int j = 0; j < m_nHorizontalOrder; j++) { // Nodal points int iElementA = m_box.GetAInteriorBegin() + a * m_nHorizontalOrder; int iElementB = m_box.GetBInteriorBegin() + b * m_nHorizontalOrder; int iA = iElementA + i; int iB = iElementB + j; // Topography height and its derivatives double dZs = m_dataTopography[iA][iB]; double dDaZs = 0.0; double dDbZs = 0.0; for (int s = 0; s < m_nHorizontalOrder; s++) { dDaZs += dDxBasis1D[s][i] * m_dataTopography[iElementA+s][iB]; dDbZs += dDxBasis1D[s][j] * m_dataTopography[iA][iElementB+s]; } dDaZs /= GetElementDeltaA(); dDbZs /= GetElementDeltaB(); m_dataTopographyDeriv[0][iA][iB] = dDaZs; m_dataTopographyDeriv[1][iA][iB] = dDbZs; } } } } }