/// <summary> /// Evaluate the state vector at the given point. /// </summary> virtual void EvaluatePointwiseState( const PhysicalConstants & phys, const Time & time, double dZp, double dXp, double dYp, double * dState, double * dTracer ) const { const double dG = phys.GetG(); const double dCv = phys.GetCv(); const double dCp = phys.GetCp(); const double dRd = phys.GetR(); const double dP0 = phys.GetP0(); // The Brunt-Vaisala frequency const double dNbar = dG / sqrt(dCp * m_dT0); // Base potential temperature field const double dTheta0 = m_dT0; double dThetaBar = dTheta0 * exp(dNbar * dNbar / dG * dZp); // Set the uniform U, V, W field for all time dState[0] = m_dU0; dState[1] = 0.0; dState[3] = 0.0; // Set the initial potential temperature field dState[2] = dThetaBar; // Set the initial density based on the Exner pressure double dExnerP = exp(-dG / (dCp * m_dT0) * dZp); double dRho = dP0 / (dRd * dThetaBar) * pow(dExnerP,(dCv / dRd)); dState[4] = dRho; }
/// <summary> /// Calculate the geopotential and temperature at the given point. /// </summary> void CalculateGeopotentialTemperature( const PhysicalConstants & phys, double dEta, double dXp, double dYp, double & dGeopotential, double & dTemperature ) const { // Get some constants const double dG = phys.GetG(); const double dCv = phys.GetCv(); const double dCp = phys.GetCp(); const double dRd = phys.GetR(); const double dP0 = phys.GetP0(); const double dae = phys.GetEarthRadius(); const double df0 = 2 * phys.GetOmega() * sin(m_dRefLat); //const double df0 = 0.0; const double dbeta0 = 2 * phys.GetOmega() * cos(m_dRefLat) / dae; //const double dbeta0 = 0.0; const double dLy = m_dGDim[3] - m_dGDim[2]; // Horizontally averaged temperature double dAvgTemperature = m_dT0 * pow(dEta, dRd * m_ddTdz / dG); // Horizontally averaged geopotential double dAvgGeopotential = m_dT0 * dG / m_ddTdz * (1.0 - pow(dEta, dRd * m_ddTdz / dG)); // Horizontal variation geopotential function double dXYGeopotential = 0.5 * m_dU0 * ((df0 - dbeta0 * m_dY0) * (dYp - m_dY0 - m_dY0 / m_dpiC * sin(2 * m_dpiC * dYp / dLy)) + 0.5 * dbeta0 * (dYp * dYp - dLy * dYp / m_dpiC * sin(2 * m_dpiC * dYp / dLy) - 0.5 * dLy * dLy / (m_dpiC * m_dpiC) * cos(2 * m_dpiC * dYp / dLy) - dLy * dLy / 3 - 0.5 * dLy * dLy / (m_dpiC * m_dpiC))); double dExpDecay = exp(-(log(dEta) / m_dbC) * (log(dEta) / m_dbC)); double dRefProfile1 = log(dEta); double dRefProfile2 = 2 / (m_dbC * m_dbC) * log(dEta) * log(dEta) - 1.0; // Total geopotential distribution dGeopotential = dAvgGeopotential + dXYGeopotential* dRefProfile1 * dExpDecay; // Total temperature distribution dTemperature = dAvgTemperature + dXYGeopotential / dRd * dRefProfile2 * dExpDecay; }
/// <summary> /// Evaluate the reference state at the given point. /// </summary> virtual void EvaluateReferenceState( const PhysicalConstants & phys, double dZp, double dXp, double dYp, double * dState ) const { const double dG = phys.GetG(); const double dCv = phys.GetCv(); const double dCp = phys.GetCp(); const double dRd = phys.GetR(); const double dP0 = phys.GetP0(); // Base potential temperature field double dThetaBar = m_dTheta0 * exp(m_dNbar * m_dNbar / dG * dZp); // Set the uniform U, V, W field for all time dState[0] = m_dU0; dState[1] = 0.0; dState[3] = 0.0; // Zero gravity case if (dG == 0.0) { static double dT0 = 300.0; dState[2] = dT0 * pow(dP0, (dRd / dCp)); dState[4] = dP0 / (dRd * dT0); // Stratification with gravity } else { // Set the initial density based on the Exner pressure double dExnerP = (dG * dG) / (dCp * m_dTheta0 * m_dNbar * m_dNbar); dExnerP *= (exp(-m_dNbar * m_dNbar / dG * dZp) - 1.0); dExnerP += 1.0; double dRho = dP0 / (dRd * dThetaBar) * pow(dExnerP,(dCv / dRd)); dState[4] = dRho; // Set the initial potential temperature field //dState[2] = phys.PressureFromRhoTheta(dThetaBar * dRho); //dState[2] = (dThetaBar * dRho); dState[2] = dThetaBar; } }
/// <summary> /// Evaluate the state vector at the given point. /// </summary> virtual void EvaluatePointwiseState( const PhysicalConstants & phys, const Time & time, double dZp, double dXp, double dYp, double * dState, double * dTracer ) const { const double dG = phys.GetG(); const double dCv = phys.GetCv(); const double dCp = phys.GetCp(); const double dRd = phys.GetR(); const double dP0 = phys.GetP0(); // Base potential temperature field double dThetaBar = m_dTheta0 * exp(m_dNbar * m_dNbar / dG * dZp); // Set the uniform U, V, W field for all time dState[0] = m_dU0; dState[1] = 0.0; dState[3] = 0.0; dState[3] = sin(M_PI * dZp / m_dGDim[5]); // Set the initial density based on the Exner pressure double dExnerP = (dG * dG) / (dCp * m_dTheta0 * m_dNbar * m_dNbar); dExnerP *= (exp(-m_dNbar * m_dNbar / dG * dZp) - 1.0); dExnerP += 1.0; double dRho = dP0 / (dRd * dThetaBar) * pow(dExnerP,(dCv / dRd)); dState[4] = dRho; // Set the initial theta field //dState[2] = phys.PressureFromRhoTheta(dThetaBar * dRho); //dState[2] = (dThetaBar * dRho); dState[2] = dThetaBar; }