void TimestepSchemeARS222::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; //std::cout << "Entering substages at the timestep... \n"; // 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 3 pGrid->LinearCombineData(m_du2fCombo, 3, DataType_State); pGrid->LinearCombineData(m_du2fCombo, 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 2 pVerticalDynamics->StepImplicit( 3, 3, time, m_dImpCf[1][1] * dDeltaT); pGrid->PostProcessSubstage(3, DataType_State); pGrid->PostProcessSubstage(3, DataType_Tracers); // Apply hyperdiffusion at the end of the explicit substep (ask Paul) pGrid->CopyData(3, 2, DataType_State); pGrid->CopyData(3, 2, DataType_Tracers); pHorizontalDynamics->StepAfterSubCycle(2, 1, 3, time, dDeltaT); pGrid->CopyData(1, 0, DataType_State); pGrid->CopyData(1, 0, DataType_Tracers); }
void TimestepSchemeSSP3332::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_dImpCf[1][0] / m_dImpCf[0][0]; m_du2fCombo[1] = 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_dImpCf[1][0] / m_dImpCf[0][0] * m_dExpCf[2][0] / m_dExpCf[1][0] - m_dExpCf[2][0] / m_dExpCf[1][0] - m_dImpCf[2][0] / m_dImpCf[0][0]; m_du3fCombo[1] = 0.0; m_du3fCombo[2] = m_dImpCf[2][0] / m_dImpCf[0][0] - m_dImpCf[1][0] / m_dImpCf[0][0] * m_dExpCf[2][0] / m_dExpCf[1][0]; m_du3fCombo[3] = m_dExpCf[2][0] / m_dExpCf[1][0]; m_du3fCombo[4] = 0.0; m_du3fCombo[5] = 0.0; m_du3fCombo[6] = 0.0; m_du3fCombo[7] = 0.0; m_du3fCombo[8] = 0.0; // u4 explicit evaluation combination m_du4fCombo[0] = 1.0 - m_dExpCf[3][0] / m_dImpCf[0][0]; m_du4fCombo[1] = 0.0; m_du4fCombo[2] = m_dImpCf[3][0] / m_dImpCf[0][0]; m_du4fCombo[3] = m_dExpCf[3][0] / m_dExpCf[1][0] - 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][1] / m_dExpCf[2][1] - 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][0] / m_dExpCf[1][0]; m_du4fCombo[8] = -m_dExpCf[3][1] / m_dExpCf[2][1]; // STAGE 1 // Compute u1 into index 2 pGrid->CopyData(0, 2, DataType_State); pGrid->CopyData(0, 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 uf1 from u0 (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][0] * dDeltaT); pVerticalDynamics->StepExplicit( 2, 3, time, m_dExpCf[1][0] * 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][1] * dDeltaT); pVerticalDynamics->StepExplicit( 4, 5, time, m_dExpCf[2][1] * 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, 1, DataType_State); pGrid->LinearCombineData(m_du4fCombo, 1, DataType_Tracers); pHorizontalDynamics->StepExplicit( 6, 1, time, m_dExpCf[3][2] * dDeltaT); pVerticalDynamics->StepExplicit( 6, 1, time, m_dExpCf[3][2] * dDeltaT); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); // NO IMPLICIT STEP ON THE LAST STAGE // Apply hyperdiffusion at the end of the explicit substep (ask Paul) pGrid->CopyData(1, 2, DataType_State); pGrid->CopyData(1, 2, DataType_Tracers); pHorizontalDynamics->StepAfterSubCycle(2, 1, 3, time, dDeltaT); pGrid->CopyData(1, 0, DataType_State); pGrid->CopyData(1, 0, DataType_Tracers); }
void TimestepSchemeARK4::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(); // K0 combination m_dK0Combo[0] = -1.0 / (dDeltaT * m_dImpCf[0][0]);; m_dK0Combo[1] = 1.0 / (dDeltaT * m_dImpCf[0][0]);; m_dK0Combo[2] = 0.0; m_dK0Combo[3] = 0.0; // u1 implicit evaluation combination m_du1fCombo[0] = 1.0; m_du1fCombo[1] = 0.0; m_du1fCombo[2] = 0.0; m_du1fCombo[3] = dDeltaT * m_dImpCf[1][0]; // Kh1 combination m_dKh1Combo[0] = -1.0 / (dDeltaT * m_dExpCf[1][0]); m_dKh1Combo[1] = 1.0 / (dDeltaT * m_dExpCf[1][0]); m_dKh1Combo[2] = 0.0; m_dKh1Combo[3] = -m_dImpCf[0][0] / m_dExpCf[1][0]; m_dKh1Combo[4] = 0.0; // K1 combination m_dK1Combo[0] = -1.0 / (dDeltaT * m_dImpCf[1][1]); m_dK1Combo[1] = 0.0; m_dK1Combo[2] = 1.0 / (dDeltaT * m_dImpCf[1][1]); m_dK1Combo[3] = -m_dImpCf[0][0] / m_dImpCf[1][1]; m_dK1Combo[4] = -m_dExpCf[1][0] / m_dImpCf[1][1]; m_dK1Combo[5] = 0.0; // u2 implicit evaluation combination m_du2fCombo[0] = 1.0; m_du2fCombo[1] = 0.0; m_du2fCombo[2] = 0.0; m_du2fCombo[3] = dDeltaT * m_dImpCf[2][0]; m_du2fCombo[4] = dDeltaT * m_dExpCf[2][0]; m_du2fCombo[5] = dDeltaT * m_dImpCf[2][1]; // K2 combination m_dK2Combo[0] = -1.0 / (dDeltaT * m_dImpCf[2][2]); m_dK2Combo[1] = 0.0; m_dK2Combo[2] = 1.0 / (dDeltaT * m_dImpCf[2][2]); m_dK2Combo[3] = -m_dImpCf[1][0] / m_dImpCf[2][2]; m_dK2Combo[4] = -m_dExpCf[2][0] / m_dImpCf[2][2]; m_dK2Combo[5] = -m_dImpCf[2][1] / m_dImpCf[2][2]; m_dK2Combo[6] = -m_dExpCf[2][1] / m_dImpCf[2][2]; m_dK2Combo[7] = 0.0; // Kh2 combination m_dKh2Combo[0] = -1.0 / (dDeltaT * m_dExpCf[2][1]); m_dKh2Combo[1] = 1.0 / (dDeltaT * m_dExpCf[2][1]); m_dKh2Combo[2] = 0.0; m_dKh2Combo[3] = -m_dImpCf[2][0] / m_dExpCf[2][1]; m_dKh2Combo[4] = -m_dExpCf[2][0] / m_dExpCf[2][1]; m_dKh2Combo[5] = -m_dImpCf[2][1] / m_dExpCf[2][1]; m_dKh2Combo[6] = 0.0; // u3 implicit evaluation combination m_du3fCombo[0] = 1.0; m_du3fCombo[1] = 0.0; m_du3fCombo[2] = 0.0; m_du3fCombo[3] = dDeltaT * m_dImpCf[3][0]; m_du3fCombo[4] = dDeltaT * m_dExpCf[3][0]; m_du3fCombo[5] = dDeltaT * m_dImpCf[3][1]; m_du3fCombo[6] = dDeltaT * m_dExpCf[3][1]; m_du3fCombo[7] = dDeltaT * m_dImpCf[3][2]; // K3 combination m_dK3Combo[0] = -1.0 / (dDeltaT * m_dImpCf[3][3]); m_dK3Combo[1] = 0.0; m_dK3Combo[2] = 1.0 / (dDeltaT * m_dImpCf[3][3]); m_dK3Combo[3] = -m_dImpCf[3][0] / m_dImpCf[3][3]; m_dK3Combo[4] = -m_dExpCf[3][0] / m_dImpCf[3][3]; m_dK3Combo[5] = -m_dImpCf[3][1] / m_dImpCf[3][3]; m_dK3Combo[6] = -m_dExpCf[3][1] / m_dImpCf[3][3]; m_dK3Combo[7] = -m_dImpCf[3][2] / m_dImpCf[3][3]; m_dK3Combo[8] = -m_dExpCf[3][2] / m_dImpCf[3][3]; m_dK3Combo[9] = 0.0; // Kh3 combination m_dKh3Combo[0] = -1.0 / (dDeltaT * m_dExpCf[3][2]); m_dKh3Combo[1] = 1.0 / (dDeltaT * m_dExpCf[3][2]); m_dKh3Combo[2] = 0.0; m_dKh3Combo[3] = -m_dImpCf[3][0] / m_dExpCf[3][2]; m_dKh3Combo[4] = -m_dExpCf[3][0] / m_dExpCf[3][2]; m_dKh3Combo[5] = -m_dImpCf[3][1] / m_dExpCf[3][2]; m_dKh3Combo[6] = -m_dExpCf[3][1] / m_dExpCf[3][2]; m_dKh3Combo[7] = -m_dImpCf[3][2] / m_dExpCf[3][2]; m_dKh3Combo[8] = 0.0; // uf4 explicit evaluation combination m_du4fCombo[0] = 1.0; m_du4fCombo[1] = 0.0; m_du4fCombo[2] = 0.0; m_du4fCombo[3] = dDeltaT * m_dImpCf[4][0]; m_du4fCombo[4] = dDeltaT * m_dExpCf[4][0]; m_du4fCombo[5] = dDeltaT * m_dImpCf[4][1]; m_du4fCombo[6] = dDeltaT * m_dExpCf[4][1]; m_du4fCombo[7] = dDeltaT * m_dImpCf[4][2]; m_du4fCombo[8] = dDeltaT * m_dExpCf[4][2]; m_du4fCombo[9] = dDeltaT * m_dImpCf[4][3]; // K4 combination m_dK4Combo[0] = -1.0 / (dDeltaT * m_dImpCf[4][4]); m_dK4Combo[1] = 0.0; m_dK4Combo[2] = 1.0 / (dDeltaT * m_dImpCf[4][4]); m_dK4Combo[3] = -m_dImpCf[4][0] / m_dImpCf[4][4]; m_dK4Combo[4] = -m_dExpCf[4][0] / m_dImpCf[4][4]; m_dK4Combo[5] = -m_dImpCf[4][1] / m_dImpCf[4][4]; m_dK4Combo[6] = -m_dExpCf[4][1] / m_dImpCf[4][4]; m_dK4Combo[7] = -m_dImpCf[4][2] / m_dImpCf[4][4]; m_dK4Combo[8] = -m_dExpCf[4][2] / m_dImpCf[4][4]; m_dK4Combo[9] = -m_dImpCf[4][3] / m_dImpCf[4][4]; m_dK4Combo[10] = -m_dExpCf[4][3] / m_dImpCf[4][4]; m_dK4Combo[11] = 0.0; // Kh4 combination m_dKh4Combo[0] = -1.0 / (dDeltaT * m_dExpCf[4][3]); m_dKh4Combo[1] = 1.0 / (dDeltaT * m_dExpCf[4][3]); m_dKh4Combo[2] = 0.0; m_dKh4Combo[3] = -m_dImpCf[4][0] / m_dExpCf[4][3]; m_dKh4Combo[4] = -m_dExpCf[4][0] / m_dExpCf[4][3]; m_dKh4Combo[5] = -m_dImpCf[4][1] / m_dExpCf[4][3]; m_dKh4Combo[6] = -m_dExpCf[4][1] / m_dExpCf[4][3]; m_dKh4Combo[7] = -m_dImpCf[4][2] / m_dExpCf[4][3]; m_dKh4Combo[8] = -m_dExpCf[4][2] / m_dExpCf[4][3]; m_dKh4Combo[9] = -m_dImpCf[4][3] / m_dExpCf[4][3]; m_dKh4Combo[10] = 0.0; // uf5 explicit evaluation combination m_du5fCombo[0] = 1.0; m_du5fCombo[1] = 0.0; m_du5fCombo[2] = 0.0; m_du5fCombo[3] = dDeltaT * m_dImpCf[5][0]; m_du5fCombo[4] = dDeltaT * m_dExpCf[5][0]; m_du5fCombo[5] = dDeltaT * m_dImpCf[5][1]; m_du5fCombo[6] = dDeltaT * m_dExpCf[5][1]; m_du5fCombo[7] = dDeltaT * m_dImpCf[5][2]; m_du5fCombo[8] = dDeltaT * m_dExpCf[5][2]; m_du5fCombo[9] = dDeltaT * m_dImpCf[5][3]; m_du5fCombo[10] = dDeltaT * m_dExpCf[5][3]; m_du5fCombo[11] = dDeltaT * m_dImpCf[5][4]; // K5 combination m_dK5Combo[0] = -1.0 / (dDeltaT * m_dImpCf[5][5]); m_dK5Combo[1] = 0.0; m_dK5Combo[2] = 1.0 / (dDeltaT * m_dImpCf[5][5]); m_dK5Combo[3] = -m_dImpCf[5][0] / m_dImpCf[5][5]; m_dK5Combo[4] = -m_dExpCf[5][0] / m_dImpCf[5][5]; m_dK5Combo[5] = -m_dImpCf[5][1] / m_dImpCf[5][5]; m_dK5Combo[6] = -m_dExpCf[5][1] / m_dImpCf[5][5]; m_dK5Combo[7] = -m_dImpCf[5][2] / m_dImpCf[5][5]; m_dK5Combo[8] = -m_dExpCf[5][2] / m_dImpCf[5][5]; m_dK5Combo[9] = -m_dImpCf[5][3] / m_dImpCf[5][5]; m_dK5Combo[10] = -m_dExpCf[5][3] / m_dImpCf[5][5]; m_dK5Combo[11] = -m_dImpCf[5][4] / m_dImpCf[5][5]; m_dK5Combo[12] = -m_dExpCf[5][4] / m_dImpCf[5][5]; m_dK5Combo[13] = 0.0; // Kh5 combination m_dKh5Combo[0] = -1.0 / (dDeltaT * m_dExpCf[5][4]); m_dKh5Combo[1] = 1.0 / (dDeltaT * m_dExpCf[5][4]); m_dKh5Combo[2] = 0.0; m_dKh5Combo[3] = -m_dImpCf[5][0] / m_dExpCf[5][4]; m_dKh5Combo[4] = -m_dExpCf[5][0] / m_dExpCf[5][4]; m_dKh5Combo[5] = -m_dImpCf[5][1] / m_dExpCf[5][4]; m_dKh5Combo[6] = -m_dExpCf[5][1] / m_dExpCf[5][4]; m_dKh5Combo[7] = -m_dImpCf[5][2] / m_dExpCf[5][4]; m_dKh5Combo[8] = -m_dExpCf[5][2] / m_dExpCf[5][4]; m_dKh5Combo[9] = -m_dImpCf[5][3] / m_dExpCf[5][4]; m_dKh5Combo[10] = -m_dExpCf[5][3] / m_dExpCf[5][4]; m_dKh5Combo[11] = -m_dImpCf[5][4] / m_dExpCf[5][4]; m_dKh5Combo[12] = 0.0; // uf6 explicit evaluation combination m_du6fCombo[0] = 1.0; m_du6fCombo[1] = 0.0; m_du6fCombo[2] = 0.0; m_du6fCombo[3] = dDeltaT * m_dImpCf[6][0]; m_du6fCombo[4] = dDeltaT * m_dExpCf[6][0]; m_du6fCombo[5] = dDeltaT * m_dImpCf[6][1]; m_du6fCombo[6] = dDeltaT * m_dExpCf[6][1]; m_du6fCombo[7] = dDeltaT * m_dImpCf[6][2]; m_du6fCombo[8] = dDeltaT * m_dExpCf[6][2]; m_du6fCombo[9] = dDeltaT * m_dImpCf[6][3]; m_du6fCombo[10] = dDeltaT * m_dExpCf[6][3]; m_du6fCombo[11] = dDeltaT * m_dImpCf[6][4]; m_du6fCombo[12] = dDeltaT * m_dExpCf[6][4]; m_du6fCombo[13] = dDeltaT * m_dImpCf[6][5]; // PRE-STAGE 1 - Implicit solve to start Time timeSub0 = time; double dtSub0 = m_dImpCf[0][0] * dDeltaT; pGrid->CopyData(0, 1, DataType_State); pHorizontalDynamics->StepImplicit(0, 1, timeSub0, dtSub0); pVerticalDynamics->StepImplicit(0, 1, timeSub0, dtSub0); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); // Store the evaluation K1 to index 3 pGrid->LinearCombineData(m_dK0Combo, 3, DataType_State); // SUBSTAGE 1 // Compute the explicit step to index 1 Time timeSub1 = time; double dtSub1 = m_dExpCf[1][0] * dDeltaT; pGrid->LinearCombineData(m_du1fCombo, 1, DataType_State); pHorizontalDynamics->StepExplicit(0, 1, timeSub1, dtSub1); pVerticalDynamics->StepExplicit(0, 1, timeSub1, dtSub1); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); // Store the evaluation Kh1 to index 4 pGrid->LinearCombineData(m_dKh1Combo, 4, DataType_State); // Compute implicit step based on known data to index 2 pGrid->CopyData(1, 2, DataType_State); dtSub1 = m_dImpCf[1][1] * dDeltaT; pVerticalDynamics->StepImplicit(1, 2, timeSub1, dtSub1); pGrid->PostProcessSubstage(2, DataType_State); pGrid->PostProcessSubstage(2, DataType_Tracers); // Store the evaluation K1 to index 3 pGrid->LinearCombineData(m_dK1Combo, 5, DataType_State); //std::cout << "Substage 1 done ... \n"; // SUBSTAGE 2 // Compute uf2 Time timeSub2 = time; double dtSub2 = m_dExpCf[2][1] * dDeltaT; pGrid->LinearCombineData(m_du2fCombo, 1, DataType_State); pHorizontalDynamics->StepExplicit(2, 1, timeSub2, dtSub2); pVerticalDynamics->StepExplicit(2, 1, timeSub2, dtSub2); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); // Store the evaluation Kh2 to index 6 pGrid->LinearCombineData(m_dKh2Combo, 6, DataType_State); // Compute u2 from uf2 and store it to index 2 (over u1) dtSub2 = m_dImpCf[2][2] * dDeltaT; pGrid->CopyData(1, 2, DataType_State); pVerticalDynamics->StepImplicit(1, 2, timeSub2, dtSub2); pGrid->PostProcessSubstage(2, DataType_State); pGrid->PostProcessSubstage(2, DataType_Tracers); // Store the evaluation K2 to index 7 pGrid->LinearCombineData(m_dK2Combo, 7, DataType_State); //std::cout << "Substage 2 done ... \n"; // SUBSTAGE 3 // Compute uf3 Time timeSub3 = time; double dtSub3 = m_dExpCf[3][2] * dDeltaT; pGrid->LinearCombineData(m_du3fCombo, 1, DataType_State); pHorizontalDynamics->StepExplicit(2, 1, timeSub2, dtSub2); pVerticalDynamics->StepExplicit(2, 1, timeSub2, dtSub2); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); // Store the evaluation Kh3 to index 8 pGrid->LinearCombineData(m_dKh3Combo, 8, DataType_State); // Compute u3 from uf3 and store it to index 2 (over u2) dtSub3 = m_dImpCf[3][3] * dDeltaT; pGrid->CopyData(1, 2, DataType_State); pVerticalDynamics->StepImplicit(1, 2, timeSub3, dtSub3); pGrid->PostProcessSubstage(2, DataType_State); pGrid->PostProcessSubstage(2, DataType_Tracers); // Store the evaluation K3 to index 9 pGrid->LinearCombineData(m_dK3Combo, 9, DataType_State); //std::cout << "Substage 3 done ... \n"; // SUBSTAGE 4 - MODIFIED DUE TO EXPLICIT ZERO EVALUATION // Compute uf4 from u3 and store it to index 2 Time timeSub4 = time; double dtSub4 = m_dExpCf[4][3] * dDeltaT; pGrid->LinearCombineData(m_du4fCombo, 1, DataType_State); pHorizontalDynamics->StepExplicit(2, 1, timeSub4, dtSub4); pVerticalDynamics->StepExplicit(2, 1, timeSub4, dtSub4); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); // Store the evaluation Kh4 to index 10 pGrid->LinearCombineData(m_dKh4Combo, 10, DataType_State); // Compute u4 from uf4 and store it to index 2 (over u3) dtSub4 = m_dImpCf[4][4] * dDeltaT; //pGrid->CopyData(1, 2, DataType_State); // Start with the previous data sum here because of the explicit zero pGrid->LinearCombineData(m_du4fCombo, 2, DataType_State); pVerticalDynamics->StepImplicit(2, 2, timeSub4, dtSub4); pGrid->PostProcessSubstage(2, DataType_State); pGrid->PostProcessSubstage(2, DataType_Tracers); // Store the evaluation K4 to index 11 pGrid->LinearCombineData(m_dK4Combo, 11, DataType_State); //std::cout << "Substage 4 done ... \n"; // SUBSTAGE 5 // Compute uf5 from u4 and store it to index 2 Time timeSub5 = time; double dtSub5 = m_dExpCf[5][4] * dDeltaT; pGrid->LinearCombineData(m_du5fCombo, 1, DataType_State); pHorizontalDynamics->StepExplicit(2, 1, timeSub5, dtSub5); pVerticalDynamics->StepExplicit(2, 1, timeSub5, dtSub5); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); // Store the evaluation Kh5 to index 12 pGrid->LinearCombineData(m_dKh5Combo, 12, DataType_State); // Compute u5 from uf5 and store it to index 2 (over u4) dtSub5 = m_dImpCf[5][5] * dDeltaT; pGrid->CopyData(1, 2, DataType_State); pVerticalDynamics->StepImplicit(1, 2, timeSub5, dtSub5); pGrid->PostProcessSubstage(2, DataType_State); pGrid->PostProcessSubstage(2, DataType_Tracers); // Store the evaluation K5 to index 13 pGrid->LinearCombineData(m_dK5Combo, 13, DataType_State); //std::cout << "Substage 5 done ... \n"; // SUBSTAGE 6 // Compute uf6 from u5 and store it to index 2 Time timeSub6 = time; double dtSub6 = m_dExpCf[6][5] * dDeltaT; pGrid->LinearCombineData(m_du6fCombo, 1, DataType_State); pHorizontalDynamics->StepExplicit(2, 1, timeSub6, dtSub6); pVerticalDynamics->StepExplicit(2, 1, timeSub6, dtSub6); pGrid->PostProcessSubstage(1, DataType_State); pGrid->PostProcessSubstage(1, DataType_Tracers); // Compute u5 from uf5 and store it to index 2 (over u4) dtSub5 = m_dImpCf[6][6] * dDeltaT; pGrid->CopyData(1, 2, DataType_State); pVerticalDynamics->StepImplicit(1, 2, timeSub6, dtSub6); pGrid->PostProcessSubstage(2, DataType_State); pGrid->PostProcessSubstage(2, DataType_Tracers); // Apply hyperdiffusion at the end of the explicit substep (ask Paul) pGrid->CopyData(2, 1, DataType_State); pHorizontalDynamics->StepAfterSubCycle(2, 1, 3, time, dDeltaT); pGrid->CopyData(1, 0, DataType_State); //*/ }
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); } */ }