-
Notifications
You must be signed in to change notification settings - Fork 97
Terrain Drag Marking Update #1668
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
27b0cb7
f42a948
85eff5a
106583b
6970b41
4df09ee
c806552
cf0060c
eb69556
bf6a513
ba9a4c5
f003446
5abea33
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,30 @@ | |
#include "AMReX_ParmParse.H" | ||
#include "AMReX_Gpu.H" | ||
#include "AMReX_Random.H" | ||
#include "amr-wind/utilities/constants.H" | ||
|
||
namespace { | ||
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_target_theta( | ||
const amrex::Real ux, | ||
const amrex::Real uy, | ||
const amrex::Real theta, | ||
const amrex::Real monin_obukhov_length, | ||
const amrex::Real gravity_mod, | ||
const amrex::Real dx, | ||
const amrex::Real z0, | ||
const amrex::Real kappa) | ||
{ | ||
const amrex::Real wspd = std::sqrt(ux * ux + uy * uy); | ||
const amrex::Real ustar = wspd * kappa / std::log(1.5 * dx / z0); | ||
const amrex::Real thetastar = | ||
theta * ustar * ustar / (kappa * gravity_mod * monin_obukhov_length); | ||
const amrex::Real surf_temp = | ||
theta - thetastar / kappa * (std::log(1.5 * dx / z0)); | ||
const amrex::Real tTarget = | ||
surf_temp + thetastar / kappa * (std::log(0.5 * dx / z0)); | ||
return tTarget; | ||
} | ||
} // namespace | ||
namespace amr_wind::pde::temperature { | ||
|
||
DragTempForcing::DragTempForcing(const CFDSim& sim) | ||
|
@@ -87,6 +110,7 @@ void DragTempForcing::operator()( | |
const amrex::Real cd_max = 10.0; | ||
const amrex::Real T0 = m_soil_temperature; | ||
amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { | ||
const int cell_drag = (drag(i, j, k) > 0) ? 1 : 0; | ||
const amrex::Real z0 = std::max(terrainz0(i, j, k), z0_min); | ||
const amrex::Real ux1 = vel(i, j, k, 0); | ||
const amrex::Real uy1 = vel(i, j, k, 1); | ||
|
@@ -106,13 +130,38 @@ void DragTempForcing::operator()( | |
const amrex::Real tTarget = | ||
surf_temp + | ||
thetastar / kappa * (std::log(0.5 * dx[2] / z0) - psi_h_cell); | ||
const amrex::Real bc_forcing_t = -(tTarget - theta) / dt; | ||
amrex::Real bc_forcing_t = -(tTarget - theta) / dt; | ||
//! West | ||
if (drag(i, j, k) > 1) { | ||
amrex::Real tmp_temp_target = compute_target_theta( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another for loop opportunity |
||
vel(i - 1, j, k, 2), vel(i - 1, j, k, 1), theta, | ||
monin_obukhov_length, gravity_mod, dx[0], z0, kappa); | ||
bc_forcing_t += | ||
-(tmp_temp_target - theta) / dt * blank(i - 1, j, k); | ||
//! East | ||
tmp_temp_target = compute_target_theta( | ||
vel(i + 1, j, k, 2), vel(i + 1, j, k, 1), theta, | ||
monin_obukhov_length, gravity_mod, dx[0], z0, kappa); | ||
bc_forcing_t += | ||
-(tmp_temp_target - theta) / dt * blank(i + 1, j, k); | ||
//! South | ||
tmp_temp_target = compute_target_theta( | ||
vel(i, j - 1, k, 2), vel(i, j - 1, k, 0), theta, | ||
monin_obukhov_length, gravity_mod, dx[1], z0, kappa); | ||
bc_forcing_t += | ||
-(tmp_temp_target - theta) / dt * blank(i, j - 1, k); | ||
//! North | ||
tmp_temp_target = compute_target_theta( | ||
vel(i, j + 1, k, 2), vel(i, j + 1, k, 0), theta, | ||
monin_obukhov_length, gravity_mod, dx[1], z0, kappa); | ||
bc_forcing_t += | ||
-(tmp_temp_target - theta) / dt * blank(i, j + 1, k); | ||
} | ||
const amrex::Real m = std::sqrt(ux1 * ux1 + uy1 * uy1 + uz1 * uz1); | ||
const amrex::Real Cd = | ||
std::min(drag_coefficient / (m + tiny), cd_max / dx[2]); | ||
src_term(i, j, k, 0) -= | ||
(Cd * (theta - T0) * blank(i, j, k, 0) + | ||
bc_forcing_t * drag(i, j, k)); | ||
(Cd * (theta - T0) * blank(i, j, k, 0) + bc_forcing_t * cell_drag); | ||
}); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,21 @@ | |
#include "amr-wind/wind_energy/MOData.H" | ||
#include "amr-wind/utilities/linear_interpolation.H" | ||
#include "amr-wind/utilities/constants.H" | ||
|
||
namespace { | ||
|
||
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_target_ustar( | ||
const amrex::Real ux, | ||
const amrex::Real uy, | ||
const amrex::Real dx, | ||
const amrex::Real z0, | ||
const amrex::Real kappa) | ||
{ | ||
const amrex::Real wspd = std::sqrt(ux * ux + uy * uy); | ||
const amrex::Real ustar = wspd * kappa / std::log(1.5 * dx / z0); | ||
return ustar; | ||
} | ||
} // namespace | ||
namespace amr_wind::pde::tke { | ||
|
||
KransAxell::KransAxell(const CFDSim& sim) | ||
|
@@ -164,16 +179,17 @@ void KransAxell::operator()( | |
const auto& terrainz0 = (*m_terrainz0)(lev).const_array(mfi); | ||
amrex::ParallelFor( | ||
bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { | ||
const int cell_drag = (drag_arr(i, j, k) > 0) ? 1 : 0; | ||
const amrex::Real cell_z0 = | ||
drag_arr(i, j, k) * std::max(terrainz0(i, j, k), z0_min) + | ||
(1 - drag_arr(i, j, k)) * z0; | ||
cell_drag * std::max(terrainz0(i, j, k), z0_min) + | ||
(1 - cell_drag) * z0; | ||
amrex::Real terrainforcing = 0; | ||
amrex::Real dragforcing = 0; | ||
amrex::Real ux = vel(i, j, k + 1, 0); | ||
amrex::Real uy = vel(i, j, k + 1, 1); | ||
amrex::Real z = 0.5 * dx[2]; | ||
amrex::Real m = std::sqrt(ux * ux + uy * uy); | ||
const amrex::Real ustar = | ||
amrex::Real ustar = | ||
m * kappa / (std::log(3 * z / cell_z0) - psi_m); | ||
const amrex::Real T0 = ref_theta_arr(i, j, k); | ||
const amrex::Real hf = std::abs(gravity[2]) / T0 * heat_flux; | ||
|
@@ -183,6 +199,36 @@ void KransAxell::operator()( | |
terrainforcing = | ||
(ustar * ustar / (Cmu * Cmu) + rans_b - tke_arr(i, j, k)) / | ||
dt; | ||
if (drag_arr(i, j, k) > 1) { | ||
//! West | ||
ustar = compute_target_ustar( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we do a for loop? if you cast as iv and then loop on dir and to iv +/- thedimensionvector(dir) it should do this automatically. |
||
vel(i - 1, j, k, 2), vel(i - 1, j, k, 1), dx[0], z0, | ||
kappa); | ||
terrainforcing += | ||
(ustar * ustar / (Cmu * Cmu) - tke_arr(i, j, k)) / dt * | ||
blank_arr(i - 1, j, k); | ||
//! East | ||
ustar = compute_target_ustar( | ||
vel(i + 1, j, k, 2), vel(i + 1, j, k, 1), dx[0], z0, | ||
kappa); | ||
terrainforcing += | ||
(ustar * ustar / (Cmu * Cmu) - tke_arr(i, j, k)) / dt * | ||
blank_arr(i + 1, j, k); | ||
//! South | ||
ustar = compute_target_ustar( | ||
vel(i, j - 1, k, 2), vel(i, j - 1, k, 0), dx[1], z0, | ||
kappa); | ||
terrainforcing += | ||
(ustar * ustar / (Cmu * Cmu) - tke_arr(i, j, k)) / dt * | ||
blank_arr(i, j - 1, k); | ||
//! North | ||
ustar = compute_target_ustar( | ||
vel(i, j + 1, k, 2), vel(i, j + 1, k, 0), dx[1], z0, | ||
kappa); | ||
terrainforcing += | ||
(ustar * ustar / (Cmu * Cmu) - tke_arr(i, j, k)) / dt * | ||
blank_arr(i, j + 1, k); | ||
} | ||
amrex::Real bcforcing = 0; | ||
if (k == 0) { | ||
bcforcing = (1 - blank_arr(i, j, k)) * terrainforcing; | ||
|
@@ -211,7 +257,7 @@ void KransAxell::operator()( | |
1.0 / dt * (tke_arr(i, j, k) - ref_tke); | ||
src_term(i, j, k) = | ||
(1 - blank_arr(i, j, k)) * src_term(i, j, k) + | ||
drag_arr(i, j, k) * terrainforcing + | ||
cell_drag * terrainforcing + | ||
blank_arr(i, j, k) * dragforcing - | ||
static_cast<int>(has_terrain) * | ||
(sponge_forcing - bcforcing); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,8 @@ | |
#include "amr-wind/utilities/IOManager.H" | ||
#include "amr-wind/utilities/io_utils.H" | ||
#include "amr-wind/utilities/linear_interpolation.H" | ||
|
||
#include "amr-wind/fvm/gradient.H" | ||
#include "amr-wind/utilities/constants.H" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think these includes are necessary? |
||
namespace amr_wind::terraindrag { | ||
|
||
namespace {} // namespace | ||
|
@@ -142,12 +143,29 @@ void TerrainDrag::initialize_fields(int level, const amrex::Geometry& geom) | |
amrex::Gpu::streamSynchronize(); | ||
amrex::ParallelFor( | ||
blanking, [=] AMREX_GPU_DEVICE(int nbx, int i, int j, int k) noexcept { | ||
if ((levelBlanking[nbx](i, j, k, 0) == 0) && (k > 0) && | ||
(levelBlanking[nbx](i, j, k - 1, 0) == 1)) { | ||
levelDrag[nbx](i, j, k, 0) = 1; | ||
} else { | ||
levelDrag[nbx](i, j, k, 0) = 0; | ||
} | ||
const int blankxp = std::abs( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we do a for loop? see comment above |
||
levelBlanking[nbx](i + 1, j, k, 0) - | ||
levelBlanking[nbx](i, j, k, 0)); | ||
const int blankxm = std::abs( | ||
levelBlanking[nbx](i - 1, j, k, 0) - | ||
levelBlanking[nbx](i, j, k, 0)); | ||
const int blankyp = std::abs( | ||
levelBlanking[nbx](i, j + 1, k, 0) - | ||
levelBlanking[nbx](i, j, k, 0)); | ||
const int blankym = std::abs( | ||
levelBlanking[nbx](i, j - 1, k, 0) - | ||
levelBlanking[nbx](i, j, k, 0)); | ||
const int blankzp = std::abs( | ||
levelBlanking[nbx](i, j, k + 1, 0) - | ||
levelBlanking[nbx](i, j, k, 0)); | ||
const int blankzm = std::abs( | ||
levelBlanking[nbx](i, j, k - 1, 0) - | ||
levelBlanking[nbx](i, j, k, 0)); | ||
levelDrag[nbx](i, j, k, 0) = | ||
((k == 0 && levelBlanking[nbx](i, j, k, 0) == 1)) | ||
? 0 | ||
: (blankxp + blankxm + blankyp + blankym + blankzp + | ||
blankzm); | ||
}); | ||
amrex::Gpu::streamSynchronize(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for loop opportunity (see comments below)