diff --git a/Source/Initialization/ERF_Metgrid_utils.H b/Source/Initialization/ERF_Metgrid_utils.H index dad42f7c9..b0ed1f4b2 100644 --- a/Source/Initialization/ERF_Metgrid_utils.H +++ b/Source/Initialization/ERF_Metgrid_utils.H @@ -99,91 +99,6 @@ init_base_state_from_metgrid (const bool use_moisture, const amrex::Vector& NC_psfc_fab, amrex::Vector>& fabs_for_bcs); -AMREX_FORCE_INLINE -AMREX_GPU_DEVICE -void -calc_rho_p (const int& kmax, - const int& flag_psfc, - const amrex::Real& psfc, - const amrex::Real& grav, - amrex::Real* Thetad_vec, - amrex::Real* Thetam_vec, - amrex::Real* Q_vec, - amrex::Real* z_vec, - amrex::Real* Rhod_vec, - amrex::Real* Rhom_vec, - amrex::Real* Pd_vec, - amrex::Real* Pm_vec) -{ - const int maxiter = 10; - const amrex::Real tol = 1.0e-10; - - // Calculate or use moist pressure at the surface. - amrex::Real Psurf; - if (flag_psfc == 1) { - Psurf = psfc; - } else { - amrex::Real t_0 = 290.0; // WRF's model_config_rec%base_temp - amrex::Real a = 50.0; // WRF's model_config_rec%base_lapse - Psurf = p_0*exp(-t_0/a+std::pow((std::pow(t_0/a, 2)-2.0*grav*z_vec[0]/(a*R_d)), 0.5)); - } - - // Iterations for the first CC point that is 1/2 dz off the surface - { - amrex::Real half_dz = z_vec[0]; - amrex::Real qvf = 1.0+(R_v/R_d)*Q_vec[0]; - Thetam_vec[0] = Thetad_vec[0]*qvf; - for (int it=0; ittol) HSEutils::Newton_Raphson_hse(tol, R_d/Cp_d, dz, - grav, C, Thetad_vec[k], - Q_vec[k], Q_vec[k], - Pm_vec[k], Rhom_vec[k], F); - } // k - - // integrate from the top back down to get dry pressure and density. - Pd_vec[kmax] = Pm_vec[kmax]; - Rhod_vec[kmax] = (p_0/(R_d*Thetam_vec[kmax]))*std::pow(Pd_vec[kmax]/p_0, iGamma); - for (int k=kmax-1; k>=0; k--) { - amrex::Real dz = z_vec[k+1]-z_vec[k]; - Rhod_vec[k] = Rhod_vec[k+1]; // an initial guess. - for (int it=0; it z_vec_d(kmax+2,0); Real* z_vec = z_vec_d.data(); - Gpu::DeviceVector Thetad_vec_d(kmax+1,0); Real* Thetad_vec = Thetad_vec_d.data(); - Gpu::DeviceVector Thetam_vec_d(kmax+1,0); Real* Thetam_vec = Thetam_vec_d.data(); - Gpu::DeviceVector Rhod_vec_d(kmax+1,0); Real* Rhod_vec = Rhod_vec_d.data(); - Gpu::DeviceVector Rhom_vec_d(kmax+1,0); Real* Rhom_vec = Rhom_vec_d.data(); - Gpu::DeviceVector Pd_vec_d(kmax+1,0); Real* Pd_vec = Pd_vec_d.data(); - Gpu::DeviceVector Pm_vec_d(kmax+1,0); Real* Pm_vec = Pm_vec_d.data(); - Gpu::DeviceVector Q_vec_d(kmax+1,0); Real* Q_vec = Q_vec_d.data(); - // Device vectors for psfc flags Gpu::DeviceVectorflag_psfc_d(flag_psfc.size()); Gpu::copy(Gpu::hostToDevice, flag_psfc.begin(), flag_psfc.end(), flag_psfc_d.begin()); @@ -819,8 +809,8 @@ init_base_state_from_metgrid (const bool use_moisture, // Define the arena to be used for data allocation Arena* Arena_Used = The_Arena(); #ifdef AMREX_USE_GPU - // Make sure this lives on CPU and GPU - Arena_Used = The_Pinned_Arena(); + // Inside MFiter use async arena + Arena_Used = The_Async_Arena(); #endif // Expose for copy to GPU Real grav = CONST_GRAV; @@ -829,6 +819,7 @@ init_base_state_from_metgrid (const bool use_moisture, const Array4& r_hse_arr = r_hse_fab.array(); const Array4& p_hse_arr = p_hse_fab.array(); const Array4& pi_hse_arr = pi_hse_fab.array(); + auto psfc_flag = flag_psfc_vec[0]; // ******************************************************** // calculate dry density and dry pressure @@ -842,20 +833,86 @@ init_base_state_from_metgrid (const bool use_moisture, ParallelFor(valid_bx2d, [=] AMREX_GPU_DEVICE (int i, int j, int) noexcept { - for (int k=0; k<=kmax; k++) { - z_vec[k] = new_z(i,j,k); - Thetad_vec[k] = new_data(i,j,k,RhoTheta_comp); - Q_vec[k] = (use_moisture) ? new_data(i,j,k,RhoQ_comp) : 0.0; + const int maxiter = 10; + const amrex::Real tol = 1.0e-10; + + // Low and Hi column variables + Real psurf; + Real z_lo, z_hi; + Real p_lo, p_hi; + Real qv_lo, qv_hi; + Real rd_lo, rd_hi; + Real thetad_lo, thetad_hi; + + // Calculate or use pressure at the surface. + if (psfc_flag == 1) { + psurf = orig_psfc(i,j,0); + } else { + z_lo = new_z(i,j,0); + Real t_0 = 290.0; // WRF's model_config_rec%base_temp + Real a = 50.0; // WRF's model_config_rec%base_lapse + psurf = p_0*exp(-t_0/a+std::pow((std::pow(t_0/a, 2.)-2.0*grav*z_lo/(a*R_d)), 0.5)); } - z_vec[kmax+1] = new_z(i,j,kmax+1); - calc_rho_p(kmax, flag_psfc_vec[0], orig_psfc(i,j,0), - grav, Thetad_vec, Thetam_vec, Q_vec, z_vec, - Rhod_vec, Rhom_vec, Pd_vec, Pm_vec); + // Iterations for the first CC point that is 1/2 dz off the surface + { + z_lo = new_z(i,j,0); + qv_lo = (use_moisture) ? new_data(i,j,0,RhoQ_comp) : 0.0; + rd_lo = 0.0; // initial guess + thetad_lo = new_data(i,j,0,RhoTheta_comp); + Real half_dz = z_lo; + Real qvf = 1.0+(R_v/R_d)*qv_lo; + Real thetam = thetad_lo*qvf; + for (int it=0; ittol) HSEutils::Newton_Raphson_hse(tol, R_d/Cp_d, dz, + grav, C, thetad_hi, + qv_hi, qv_hi, p_hi, + rd_hi, F); + + // Copy solution to base state + p_hse_arr(i,j,k) = p_hi; + r_hse_arr(i,j,k) = rd_hi; + + // Copy hi to lo + z_lo = z_hi; + p_lo = p_hi; + qv_lo = qv_hi; + rd_lo = rd_hi; + thetad_lo = thetad_hi; } }); @@ -926,10 +983,11 @@ init_base_state_from_metgrid (const bool use_moisture, } int ntimes = NC_psfc_fab.size(); - for (int it=0; it{}; + auto Theta_arr = fabs_for_bcs[itime][MetGridBdyVars::T].array(); + auto Q_arr = (use_moisture ) ? fabs_for_bcs[itime][MetGridBdyVars::QV].array() : Array4{}; auto p_hse_arr = p_hse_bcs_fab.array(); ParallelFor(valid_bx2d, [=] AMREX_GPU_DEVICE (int i, int j, int) noexcept { - for (int k=0; k<=kmax; k++) { - z_vec[k] = new_z(i,j,k); - Thetad_vec[k] = Theta_arr(i,j,k); - Q_vec[k] = (use_moisture) ? Q_arr(i,j,k) : 0.0; + const int maxiter = 10; + const amrex::Real tol = 1.0e-10; + + // Low and Hi column variables + Real psurf; + Real z_lo, z_hi; + Real p_lo, p_hi; + Real qv_lo, qv_hi; + Real rd_lo, rd_hi; + Real thetad_lo, thetad_hi; + + // Calculate or use pressure at the surface. + if (psfc_flag == 1) { + psurf = orig_psfc(i,j,0); + } else { + z_lo = new_z(i,j,0); + Real t_0 = 290.0; // WRF's model_config_rec%base_temp + Real a = 50.0; // WRF's model_config_rec%base_lapse + psurf = p_0*exp(-t_0/a+std::pow((std::pow(t_0/a, 2.)-2.0*grav*z_lo/(a*R_d)), 0.5)); + } + + // Iterations for the first CC point that is 1/2 dz off the surface + { + z_lo = new_z(i,j,0); + qv_lo = (use_moisture) ? Q_arr(i,j,0) : 0.0; + rd_lo = 0.0; // initial guess + thetad_lo = Theta_arr(i,j,0); + Real half_dz = z_lo; + Real qvf = 1.0+(R_v/R_d)*qv_lo; + Real thetam = thetad_lo*qvf; + for (int it=0; ittol) HSEutils::Newton_Raphson_hse(tol, R_d/Cp_d, dz, + grav, C, thetad_hi, + qv_hi, qv_hi, p_hi, + rd_hi, F); + + // Copy solution to base state + p_hse_arr(i,j,k) = p_hi; + + // Copy hi to lo + z_lo = z_hi; + p_lo = p_hi; + qv_lo = qv_hi; + rd_lo = rd_hi; + thetad_lo = thetad_hi; + } - for (int k=0; k<=kmax; k++) { - p_hse_arr(i,j,k) = Pm_vec[k]; - } // k }); - } // it + } // itime }