int TimestepSchemeStrang::SubStep( bool fFirstStep, bool fLastStep, const Time & time, double dDeltaT, int iSubStep ) { Grid * pGrid = m_model.GetGrid(); HorizontalDynamics * pHorizontalDynamics = m_model.GetHorizontalDynamics(); VerticalDynamics * pVerticalDynamics = m_model.GetVerticalDynamics(); if (pGrid == NULL) { _EXCEPTIONT("Model Grid has not been initialized"); } if (pHorizontalDynamics == NULL) { _EXCEPTIONT("Model HorizontalDynamics has not been initialized"); } if (pVerticalDynamics == NULL) { _EXCEPTIONT("Model VerticalDynamics has not been initialized"); } // Half a time step double dHalfDeltaT = 0.5 * dDeltaT; // Number of HorizontalDynamics substeps int nHorizontalDynamicsSubSteps = pHorizontalDynamics->GetSubStepAfterSubCycleCount(); // Vertical timestep if (iSubStep == 0) { // Vertical timestep if (fFirstStep) { pVerticalDynamics->StepImplicit(0, 0, time, dHalfDeltaT); } else { pGrid->LinearCombineData(m_dCarryoverCombination, 0, DataType_State); pGrid->LinearCombineData(m_dCarryoverCombination, 0, DataType_Tracers); pVerticalDynamics->FilterNegativeTracers(0); } } // Forward Euler if (m_eExplicitDiscretization == ForwardEuler) { if (iSubStep == 0) { pGrid->CopyData(0, 4, DataType_State); pGrid->CopyData(0, 4, DataType_Tracers); pHorizontalDynamics->StepExplicit(0, 4, time, dDeltaT); pVerticalDynamics->StepExplicit(0, 4, time, dDeltaT); return 4; } // Explicit fourth-order Runge-Kutta } else if (m_eExplicitDiscretization == RungeKutta4) { if (iSubStep == 0) { pGrid->CopyData(0, 1, DataType_State); pGrid->CopyData(0, 1, DataType_Tracers); pHorizontalDynamics->StepExplicit(0, 1, time, dHalfDeltaT); pVerticalDynamics->StepExplicit(0, 1, time, dHalfDeltaT); return 1; } else if (iSubStep == 1) { pGrid->CopyData(0, 2, DataType_State); pGrid->CopyData(0, 2, DataType_Tracers); pHorizontalDynamics->StepExplicit(1, 2, time, dHalfDeltaT); pVerticalDynamics->StepExplicit(1, 2, time, dHalfDeltaT); return 2; } else if (iSubStep == 2) { pGrid->CopyData(0, 3, DataType_State); pGrid->CopyData(0, 3, DataType_Tracers); pHorizontalDynamics->StepExplicit(2, 3, time, dDeltaT); pVerticalDynamics->StepExplicit(2, 3, time, dDeltaT); return 3; } else if (iSubStep == 3) { pGrid->LinearCombineData(m_dRK4Combination, 4, DataType_State); pGrid->LinearCombineData(m_dRK4Combination, 4, DataType_Tracers); pHorizontalDynamics->StepExplicit(3, 4, time, dDeltaT / 6.0); pVerticalDynamics->StepExplicit(3, 4, time, dDeltaT / 6.0); return 4; } // Explicit strong stability preserving third-order Runge-Kutta } else if (m_eExplicitDiscretization == RungeKuttaSSP3) { if (iSubStep == 0) { pGrid->CopyData(0, 1, DataType_State); pGrid->CopyData(0, 1, DataType_Tracers); pHorizontalDynamics->StepExplicit(0, 1, time, dDeltaT); pVerticalDynamics->StepExplicit(0, 1, time, dDeltaT); return 1; } else if (iSubStep == 1) { pGrid->LinearCombineData(m_dSSPRK3CombinationA, 2, DataType_State); pGrid->LinearCombineData(m_dSSPRK3CombinationA, 2, DataType_Tracers); pHorizontalDynamics->StepExplicit(1, 2, time, 0.25 * dDeltaT); pVerticalDynamics->StepExplicit(1, 2, time, 0.25 * dDeltaT); return 2; } else if (iSubStep == 2) { pGrid->LinearCombineData(m_dSSPRK3CombinationB, 4, DataType_State); pGrid->LinearCombineData(m_dSSPRK3CombinationB, 4, DataType_Tracers); pHorizontalDynamics->StepExplicit(2, 4, time, (2.0/3.0) * dDeltaT); pVerticalDynamics->StepExplicit(2, 4, time, (2.0/3.0) * dDeltaT); return 4; } // Explicit Kinnmark, Gray and Ullrich third-order five-stage Runge-Kutta } else if (m_eExplicitDiscretization == KinnmarkGrayUllrich35) { if (iSubStep == 0) { pGrid->CopyData(0, 1, DataType_State); pGrid->CopyData(0, 1, DataType_Tracers); pHorizontalDynamics->StepExplicit(0, 1, time, dDeltaT / 5.0); pVerticalDynamics->StepExplicit(0, 1, time, dDeltaT / 5.0); return 1; } else if (iSubStep == 1) { pGrid->CopyData(0, 2, DataType_State); pGrid->CopyData(0, 2, DataType_Tracers); pHorizontalDynamics->StepExplicit(1, 2, time, dDeltaT / 5.0); pVerticalDynamics->StepExplicit(1, 2, time, dDeltaT / 5.0); return 2; } else if (iSubStep == 2) { pGrid->CopyData(0, 3, DataType_State); pGrid->CopyData(0, 3, DataType_Tracers); pHorizontalDynamics->StepExplicit(2, 3, time, dDeltaT / 3.0); pVerticalDynamics->StepExplicit(2, 3, time, dDeltaT / 3.0); return 3; } else if (iSubStep == 3) { pGrid->CopyData(0, 2, DataType_State); pGrid->CopyData(0, 2, DataType_Tracers); pHorizontalDynamics->StepExplicit(3, 2, time, 2.0 * dDeltaT / 3.0); pVerticalDynamics->StepExplicit(3, 2, time, 2.0 * dDeltaT / 3.0); return 2; } else if (iSubStep == 4) { pGrid->LinearCombineData( m_dKinnmarkGrayUllrichCombination, 4, DataType_State); pGrid->LinearCombineData( m_dKinnmarkGrayUllrichCombination, 4, DataType_Tracers); pHorizontalDynamics->StepExplicit(2, 4, time, 3.0 * dDeltaT / 4.0); pVerticalDynamics->StepExplicit(2, 4, time, 3.0 * dDeltaT / 4.0); return 4; } // Explicit strong stability preserving five-stage third-order Runge-Kutta } else if (m_eExplicitDiscretization == RungeKuttaSSPRK53) { if (iSubStep == 0) { const double dStepOne = 0.377268915331368; pGrid->CopyData(0, 1, DataType_State); pGrid->CopyData(0, 1, DataType_Tracers); pHorizontalDynamics->StepExplicit(0, 1, time, dStepOne * dDeltaT); pVerticalDynamics->StepExplicit(0, 1, time, dStepOne * dDeltaT); return 1; } else if (iSubStep == 1) { const double dStepOne = 0.377268915331368; pGrid->CopyData(1, 2, DataType_State); pGrid->CopyData(1, 2, DataType_Tracers); pHorizontalDynamics->StepExplicit(1, 2, time, dStepOne * dDeltaT); pVerticalDynamics->StepExplicit(1, 2, time, dStepOne * dDeltaT); return 2; } else if (iSubStep == 2) { const double dStepThree = 0.242995220537396; pGrid->LinearCombineData(m_dSSPRK53CombinationA, 3, DataType_State); pGrid->LinearCombineData(m_dSSPRK53CombinationA, 3, DataType_Tracers); pHorizontalDynamics->StepExplicit(2, 3, time, dStepThree * dDeltaT); pVerticalDynamics->StepExplicit(2, 3, time, dStepThree * dDeltaT); return 3; } else if (iSubStep == 3) { const double dStepFour = 0.238458932846290; pGrid->LinearCombineData(m_dSSPRK53CombinationB, 0, DataType_State); pGrid->LinearCombineData(m_dSSPRK53CombinationB, 0, DataType_Tracers); pHorizontalDynamics->StepExplicit(3, 0, time, dStepFour * dDeltaT); pVerticalDynamics->StepExplicit(3, 0, time, dStepFour * dDeltaT); return 0; } else if (iSubStep == 4) { const double dStepFive = 0.287632146308408; pGrid->LinearCombineData(m_dSSPRK53CombinationC, 4, DataType_State); pGrid->LinearCombineData(m_dSSPRK53CombinationC, 4, DataType_Tracers); pHorizontalDynamics->StepExplicit(0, 4, time, dStepFive * dDeltaT); pVerticalDynamics->StepExplicit(0, 4, time, dStepFive * dDeltaT); return 4; } // Fixers, filters and diffusion } else if ( (iSubStep >= m_nExplicitSubSteps) && (iSubStep < m_nExplicitSubSteps + nHorizontalDynamicsSubSteps) ) { return pHorizontalDynamics->SubStepAfterSubCycle( 4, 1, 2, time, dDeltaT, iSubStep - m_nExplicitSubSteps); // Vertical timestep } else if ( iSubStep == m_nExplicitSubSteps + nHorizontalDynamicsSubSteps ) { pGrid->CopyData(1, 0, DataType_State); pGrid->CopyData(1, 0, DataType_Tracers); pVerticalDynamics->StepImplicit(0, 0, time, 0.5 * dDeltaT); if (!fLastStep) { pGrid->LinearCombineData(m_dCarryoverFinal, 1, DataType_State); pGrid->LinearCombineData(m_dCarryoverFinal, 1, DataType_Tracers); } #pragma message "Merge this vertical timestep in above" return (-1); } // Invalid substep _EXCEPTIONT("Invalid iSubStep"); }
void TimestepSchemeStrang::Step( bool fFirstStep, bool fLastStep, const Time & time, double dDeltaT ) { // Get a copy of the grid Grid * pGrid = m_model.GetGrid(); // Get a copy of the HorizontalDynamics HorizontalDynamics * pHorizontalDynamics = m_model.GetHorizontalDynamics(); // Get a copy of the VerticalDynamics VerticalDynamics * pVerticalDynamics = m_model.GetVerticalDynamics(); // Half a time step double dHalfDeltaT = 0.5 * dDeltaT; // Vertical timestep if (fFirstStep) { pVerticalDynamics->StepImplicit(0, 0, time, dHalfDeltaT); } else { pGrid->LinearCombineData(m_dCarryoverCombination, 0, DataType_State); } // Forward Euler if (m_eExplicitDiscretization == ForwardEuler) { pGrid->CopyData(0, 4, DataType_State); pHorizontalDynamics->StepExplicit(0, 4, time, dDeltaT); pVerticalDynamics->StepExplicit(0, 4, time, dDeltaT); pGrid->PostProcessSubstage(4, DataType_State); pGrid->PostProcessSubstage(4, DataType_Tracers); // Explicit fourth-order Runge-Kutta } else if (m_eExplicitDiscretization == RungeKutta4) { pGrid->CopyData(0, 1, DataType_State); pHorizontalDynamics->StepExplicit(0, 1, time, dHalfDeltaT); pVerticalDynamics->StepExplicit(0, 1, time, dHalfDeltaT); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); pGrid->CopyData(0, 2, DataType_State); pHorizontalDynamics->StepExplicit(1, 2, time, dHalfDeltaT); pVerticalDynamics->StepExplicit(1, 2, time, dHalfDeltaT); pGrid->PostProcessSubstage(2, DataType_State); pGrid->PostProcessSubstage(2, DataType_Tracers); pGrid->CopyData(0, 3, DataType_State); pHorizontalDynamics->StepExplicit(2, 3, time, dDeltaT); pVerticalDynamics->StepExplicit(2, 3, time, dDeltaT); pGrid->PostProcessSubstage(3, DataType_State); pGrid->PostProcessSubstage(3, DataType_Tracers); pGrid->LinearCombineData(m_dRK4Combination, 4, DataType_State); pHorizontalDynamics->StepExplicit(3, 4, time, dDeltaT / 6.0); pVerticalDynamics->StepExplicit(3, 4, time, dDeltaT / 6.0); pGrid->PostProcessSubstage(4, DataType_State); pGrid->PostProcessSubstage(4, DataType_Tracers); // Explicit strong stability preserving third-order Runge-Kutta } else if (m_eExplicitDiscretization == RungeKuttaSSP3) { pGrid->CopyData(0, 1, DataType_State); pHorizontalDynamics->StepExplicit(0, 1, time, dDeltaT); pVerticalDynamics->StepExplicit(0, 1, time, dDeltaT); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); pGrid->LinearCombineData(m_dSSPRK3CombinationA, 2, DataType_State); pHorizontalDynamics->StepExplicit(1, 2, time, 0.25 * dDeltaT); pVerticalDynamics->StepExplicit(1, 2, time, 0.25 * dDeltaT); pGrid->PostProcessSubstage(2, DataType_State); pGrid->PostProcessSubstage(2, DataType_Tracers); pGrid->LinearCombineData(m_dSSPRK3CombinationB, 4, DataType_State); pHorizontalDynamics->StepExplicit(2, 4, time, (2.0/3.0) * dDeltaT); pVerticalDynamics->StepExplicit(2, 4, time, (2.0/3.0) * dDeltaT); pGrid->PostProcessSubstage(4, DataType_State); pGrid->PostProcessSubstage(4, DataType_Tracers); // Explicit Kinnmark, Gray and Ullrich third-order five-stage Runge-Kutta } else if (m_eExplicitDiscretization == KinnmarkGrayUllrich35) { pGrid->CopyData(0, 1, DataType_State); pHorizontalDynamics->StepExplicit(0, 1, time, dDeltaT / 5.0); pVerticalDynamics->StepExplicit(0, 1, time, dDeltaT / 5.0); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); pGrid->CopyData(0, 2, DataType_State); pHorizontalDynamics->StepExplicit(1, 2, time, dDeltaT / 5.0); pVerticalDynamics->StepExplicit(1, 2, time, dDeltaT / 5.0); pGrid->PostProcessSubstage(2, DataType_State); pGrid->PostProcessSubstage(2, DataType_Tracers); pGrid->CopyData(0, 3, DataType_State); pHorizontalDynamics->StepExplicit(2, 3, time, dDeltaT / 3.0); pVerticalDynamics->StepExplicit(2, 3, time, dDeltaT / 3.0); pGrid->PostProcessSubstage(3, DataType_State); pGrid->PostProcessSubstage(3, DataType_Tracers); pGrid->CopyData(0, 2, DataType_State); pHorizontalDynamics->StepExplicit(3, 2, time, 2.0 * dDeltaT / 3.0); pVerticalDynamics->StepExplicit(3, 2, time, 2.0 * dDeltaT / 3.0); pGrid->PostProcessSubstage(2, DataType_State); pGrid->PostProcessSubstage(2, DataType_Tracers); pGrid->LinearCombineData( m_dKinnmarkGrayUllrichCombination, 4, DataType_State); pHorizontalDynamics->StepExplicit(2, 4, time, 3.0 * dDeltaT / 4.0); pVerticalDynamics->StepExplicit(2, 4, time, 3.0 * dDeltaT / 4.0); pGrid->PostProcessSubstage(4, DataType_State); pGrid->PostProcessSubstage(4, DataType_Tracers); // Explicit strong stability preserving five-stage third-order Runge-Kutta } else if (m_eExplicitDiscretization == RungeKuttaSSPRK53) { const double dStepOne = 0.377268915331368; pGrid->CopyData(0, 1, DataType_State); pHorizontalDynamics->StepExplicit(0, 1, time, dStepOne * dDeltaT); pVerticalDynamics->StepExplicit(0, 1, time, dStepOne * dDeltaT); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); pGrid->CopyData(1, 2, DataType_State); pHorizontalDynamics->StepExplicit(1, 2, time, dStepOne * dDeltaT); pVerticalDynamics->StepExplicit(1, 2, time, dStepOne * dDeltaT); pGrid->PostProcessSubstage(2, DataType_State); pGrid->PostProcessSubstage(2, DataType_Tracers); const double dStepThree = 0.242995220537396; pGrid->LinearCombineData(m_dSSPRK53CombinationA, 3, DataType_State); pHorizontalDynamics->StepExplicit(2, 3, time, dStepThree * dDeltaT); pVerticalDynamics->StepExplicit(2, 3, time, dStepThree * dDeltaT); pGrid->PostProcessSubstage(3, DataType_State); pGrid->PostProcessSubstage(3, DataType_Tracers); const double dStepFour = 0.238458932846290; pGrid->LinearCombineData(m_dSSPRK53CombinationB, 0, DataType_State); pHorizontalDynamics->StepExplicit(3, 0, time, dStepFour * dDeltaT); pVerticalDynamics->StepExplicit(3, 0, time, dStepFour * dDeltaT); pGrid->PostProcessSubstage(0, DataType_State); pGrid->PostProcessSubstage(0, DataType_Tracers); const double dStepFive = 0.287632146308408; pGrid->LinearCombineData(m_dSSPRK53CombinationC, 4, DataType_State); pHorizontalDynamics->StepExplicit(0, 4, time, dStepFive * dDeltaT); pVerticalDynamics->StepExplicit(0, 4, time, dStepFive * dDeltaT); pGrid->PostProcessSubstage(4, DataType_State); pGrid->PostProcessSubstage(4, DataType_Tracers); // Invalid explicit discretization } else { _EXCEPTIONT("Invalid explicit discretization"); } // Apply hyperdiffusion pGrid->CopyData(4, 1, DataType_State); pHorizontalDynamics->StepAfterSubCycle(4, 1, 2, time, dDeltaT); // Vertical timestep double dOffCenterDeltaT = 0.5 * (1.0 + m_dOffCentering) * dDeltaT; pGrid->CopyData(1, 0, DataType_State); pVerticalDynamics->StepImplicit(0, 0, time, dOffCenterDeltaT); pGrid->LinearCombineData(m_dOffCenteringCombination, 0, DataType_State); if (!fLastStep) { pGrid->LinearCombineData(m_dCarryoverFinal, 1, DataType_State); } //pGrid->CopyData(0, 1, DataType_State); //pVerticalDynamics->StepExplicit(0, 1, time, dDeltaT); //pVerticalDynamics->StepImplicit(0, 0, time, dDeltaT); /* if (0) { //if (fLastStep) { DataVector<double> dDifference; dDifference.Initialize(2); dDifference[0] = -1.0; dDifference[1] = 1.0; pGrid->LinearCombineData(dDifference, 0, DataType_State); } else { pGrid->CopyData(4, 0, DataType_State); } */ }
void TimestepSchemeARS443::Step( bool fFirstStep, bool fLastStep, const Time & time, double dDeltaT ) { // Get a copy of the grid Grid * pGrid = m_model.GetGrid(); // Get a copy of the HorizontalDynamics HorizontalDynamics * pHorizontalDynamics = m_model.GetHorizontalDynamics(); // Get a copy of the VerticalDynamics VerticalDynamics * pVerticalDynamics = m_model.GetVerticalDynamics(); // u2 explicit evaluation combination m_du2fCombo[0] = 1.0 - m_dExpCf[1][0] / m_dExpCf[0][0]; m_du2fCombo[1] = m_dExpCf[1][0] / m_dExpCf[0][0] - m_dImpCf[1][0] / m_dImpCf[0][0]; m_du2fCombo[2] = m_dImpCf[1][0] / m_dImpCf[0][0]; m_du2fCombo[3] = 0.0; m_du2fCombo[4] = 0.0; m_du2fCombo[5] = 0.0; m_du2fCombo[6] = 0.0; m_du2fCombo[7] = 0.0; // u3 explicit evaluation combination m_du3fCombo[0] = 1.0 - m_dExpCf[2][0] / m_dExpCf[0][0]; m_du3fCombo[1] = m_dExpCf[2][0] / m_dExpCf[0][0] - m_dImpCf[2][0] / m_dImpCf[0][0]; m_du3fCombo[2] = m_dImpCf[2][0] / m_dImpCf[0][0]; m_du3fCombo[3] = m_dExpCf[2][1] / m_dExpCf[1][1] - m_dImpCf[2][1] / m_dImpCf[1][1]; m_du3fCombo[4] = m_dImpCf[2][1] / m_dImpCf[1][1]; m_du3fCombo[5] = 0.0; m_du3fCombo[6] = 0.0; m_du3fCombo[7] = -m_dExpCf[2][1] / m_dExpCf[1][1]; m_du3fCombo[8] = 0.0; // u4 explicit evaluation combination m_du4fCombo[0] = 1.0 - m_dExpCf[3][0] / m_dExpCf[0][0]; m_du4fCombo[1] = m_dExpCf[3][0] / m_dExpCf[0][0] - m_dImpCf[3][0] / m_dImpCf[0][0]; m_du4fCombo[2] = m_dImpCf[3][0] / m_dImpCf[0][0]; m_du4fCombo[3] = m_dExpCf[3][1] / m_dExpCf[1][1] - m_dImpCf[3][1] / m_dImpCf[1][1]; m_du4fCombo[4] = m_dImpCf[3][1] / m_dImpCf[1][1]; m_du4fCombo[5] = m_dExpCf[3][2] / m_dExpCf[2][2] - m_dImpCf[3][2] / m_dImpCf[2][2]; m_du4fCombo[6] = m_dImpCf[3][2] / m_dImpCf[2][2]; m_du4fCombo[7] = -m_dExpCf[3][1] / m_dExpCf[1][1]; m_du4fCombo[8] = -m_dExpCf[3][2] / m_dExpCf[2][2]; m_du4fCombo[9] = 0.0; // STAGE 1 // Compute uf1 into index 1 pGrid->CopyData(0, 1, DataType_State); pGrid->CopyData(0, 1, DataType_Tracers); pHorizontalDynamics->StepExplicit( 0, 1, time, m_dExpCf[0][0] * dDeltaT); pVerticalDynamics->StepExplicit( 0, 1, time, m_dExpCf[0][0] * dDeltaT); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); // Compute u1 into index 2 pGrid->CopyData(1, 2, DataType_State); pGrid->CopyData(1, 2, DataType_State); pVerticalDynamics->StepImplicit( 2, 2, time, m_dImpCf[0][0] * dDeltaT); pGrid->PostProcessSubstage(2, DataType_State); pGrid->PostProcessSubstage(2, DataType_Tracers); // STAGE 2 // Compute uf2 from u1 (index 2) into index 7 pGrid->LinearCombineData(m_du2fCombo, 7, DataType_State); pGrid->LinearCombineData(m_du2fCombo, 7, DataType_Tracers); pGrid->CopyData(7, 3, DataType_State); pGrid->CopyData(7, 3, DataType_Tracers); pHorizontalDynamics->StepExplicit( 2, 3, time, m_dExpCf[1][1] * dDeltaT); pVerticalDynamics->StepExplicit( 2, 3, time, m_dExpCf[1][1] * dDeltaT); pGrid->PostProcessSubstage(3, DataType_State); pGrid->PostProcessSubstage(3, DataType_Tracers); // Compute u2 from uf2 (index 3) into index 4 pGrid->CopyData(3, 4, DataType_State); pGrid->CopyData(3, 4, DataType_State); pVerticalDynamics->StepImplicit( 4, 4, time, m_dImpCf[1][1] * dDeltaT); pGrid->PostProcessSubstage(4, DataType_State); pGrid->PostProcessSubstage(4, DataType_Tracers); // STAGE 3 // Compute uf3 from u2 (index 4) into index 8 pGrid->LinearCombineData(m_du3fCombo, 8, DataType_State); pGrid->LinearCombineData(m_du3fCombo, 8, DataType_Tracers); pGrid->CopyData(8, 5, DataType_State); pGrid->CopyData(8, 5, DataType_Tracers); pHorizontalDynamics->StepExplicit( 4, 5, time, m_dExpCf[2][2] * dDeltaT); pVerticalDynamics->StepExplicit( 4, 5, time, m_dExpCf[2][2] * dDeltaT); pGrid->PostProcessSubstage(5, DataType_State); pGrid->PostProcessSubstage(5, DataType_Tracers); // Compute u3 from uf3 (index 3) into index 6 pGrid->CopyData(5, 6, DataType_State); pGrid->CopyData(5, 6, DataType_State); pVerticalDynamics->StepImplicit( 6, 6, time, m_dImpCf[2][2] * dDeltaT); pGrid->PostProcessSubstage(6, DataType_State); pGrid->PostProcessSubstage(6, DataType_Tracers); // STAGE 4 // Compute uf4 from u3 (index 6) into index 9 pGrid->LinearCombineData(m_du4fCombo, 9, DataType_State); pGrid->LinearCombineData(m_du4fCombo, 9, DataType_Tracers); pHorizontalDynamics->StepExplicit( 6, 9, time, m_dExpCf[3][3] * dDeltaT); pVerticalDynamics->StepExplicit( 6, 9, time, m_dExpCf[3][3] * dDeltaT); pGrid->PostProcessSubstage(9, DataType_State); pGrid->PostProcessSubstage(9, DataType_Tracers); // Compute u2 from uf2 (index 7) into index 2 pVerticalDynamics->StepImplicit( 9, 9, time, m_dImpCf[3][3] * dDeltaT); pGrid->PostProcessSubstage(9, DataType_State); pGrid->PostProcessSubstage(9, DataType_Tracers); // Apply hyperdiffusion at the end of the explicit substep (ask Paul) pGrid->CopyData(9, 2, DataType_State); pGrid->CopyData(9, 2, DataType_Tracers); pHorizontalDynamics->StepAfterSubCycle(2, 1, 9, time, dDeltaT); pGrid->CopyData(1, 0, DataType_State); pGrid->CopyData(1, 0, DataType_Tracers); }