-
Notifications
You must be signed in to change notification settings - Fork 78
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
Terrain-Aware Immersed Forcing Method #1115
base: main
Are you sure you want to change the base?
Conversation
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.
Here's some quick comments from a first pass
const amrex::Real gpu_startY = (m_spongeDistanceY > 0) | ||
? prob_hi[1] - m_spongeDistanceY | ||
: prob_lo[1] - m_spongeDistanceY; | ||
const amrex::Real gpu_spongeX = (m_spongeDistanceX > 0) ? 1 : 0; |
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.
Do these need to be amrex::Real
? Looks like the value is just 0 or 1.
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.
Does not have to be real. Can change it to int.
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.
or bool?
amrex::Real gpu_spongeVelZ = 0.0; | ||
amrex::Real residual = 1000; | ||
amrex::Real height_error = 0.0; | ||
for (unsigned ii = 0; ii < vsize; ++ii) { |
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.
There might be a better way to find the first closest index to the reference height x3
using std::lower_bound
and std::upper_bound
or some such instead of this loop?
const amrex::Real uy1 = vel(i, j, k, 1); | ||
const amrex::Real uz1 = vel(i, j, k, 2); | ||
const amrex::Real m = std::sqrt(ux1 * ux1 + uy1 * uy1 + uz1 * uz1); | ||
if (drag(i, j, k) == 1) { |
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.
Similar to Michael's comments, is drag
an integer/bool field? Also, perhaps call this something more descriptive than drag
to not confuse this with m_drag
?
amr-wind/turbulence/LES/Kosovic.cpp
Outdated
@@ -18,7 +18,7 @@ Kosovic<Transport>::Kosovic(CFDSim& sim) | |||
, m_vel(sim.repo().get_field("velocity")) | |||
, m_rho(sim.repo().get_field("density")) | |||
, m_Nij(sim.repo().declare_field("Nij", 9, 1, 1)) | |||
, m_divNij(sim.repo().declare_field("divNij", 3)) | |||
, m_divNij(sim.repo().declare_field("divNij", 3, 1, 1)) |
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.
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.
I updated to latest repo updated and included the changes. Not sure why it changed back.
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.
Made a first pass at the non code stuff. My main comment has to do with how we want to present this work.
test/CMakeLists.txt
Outdated
@@ -242,6 +242,9 @@ add_test_re(burggraf_flow) | |||
add_test_re(abl_godunov_rayleigh_damping) | |||
add_test_re(rankine) | |||
add_test_re(rankine-sym) | |||
add_test_re(terrainbox) | |||
add_test_re(nrel_precursor) |
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.
If you want to test the whole chain you can add test dependencies. The input-output runs do this.
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.
Modified
test/test_files/nrel_terrain/README
Outdated
@@ -0,0 +1,6 @@ | |||
This is the sample terrain case. You need to run "python3.XX backendinterface.py NREL.yaml" in the tools/terrain folder. |
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.
Let's remove this readme (kinda strange to have that in a reg test folder) and move it to proper documentation.
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.
Also, remove/move the png from here.
test/test_files/terrainbox/README
Outdated
@@ -0,0 +1,6 @@ | |||
This is a simple test case to verify the terrain setup. A box is created and a freestream velocity |
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.
Same comment about the readme here.
@@ -0,0 +1,13 @@ | |||
from netCDF4 import Dataset |
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.
Let's remove this file or follow the MMS test template (which has a python call). Still my preference would be to remove/move to documentation.
@@ -0,0 +1,15 @@ | |||
import numpy as np |
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.
Same thing here. I guess these regtests are really "tutorials". I like the regtest and think the tutorial part should be moved to documenation.
tools/terrain/SRTM_to_STL_example.py
Outdated
@@ -0,0 +1,414 @@ | |||
def SRTM_Converter(outputDir,refLat,refLon,refHeight,left,right,bottom,top): |
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.
this looks copy-pasted from jupyter. Can we make this a proper script?
tools/terrain/SRTM_to_STL_example.py
Outdated
# In[26]: | ||
|
||
|
||
if getWRFdata is True: |
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.
shouldn't need to test like this
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.
Removed
pp.addarr("physics", physics); | ||
amr_wind::terraindrag::TerrainDrag terrain_drag(sim()); | ||
terrain_drag.post_init_actions(); | ||
int value = 100; |
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.
const int
amrex::Gpu::DeviceVector<amrex::Real> gpu_vel_ht; | ||
amrex::Gpu::DeviceVector<amrex::Real> gpu_vel_vals; | ||
amrex::Real m_drag{100.0}; | ||
amrex::Real m_spongeStrength{1.0}; |
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.
let's maintain the consistent naming case. These should be m_sponge_strength
etc.
{ | ||
amrex::ParmParse pp("DragForcing"); | ||
pp.query("dragCoefficient", m_drag); | ||
pp.query("spongeStrength", m_spongeStrength); |
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.
same remark about case here. I think we typically use snake case in the input files
const auto& phy_mgr = m_sim.physics_manager(); | ||
if (phy_mgr.contains("ABL")) { | ||
const auto& abl = m_sim.physics_manager().get<amr_wind::ABL>(); | ||
const VelPlaneAveraging& fa_velocity = |
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.
const auto&
const CFDSim& m_sim; | ||
const amrex::AmrCore& m_mesh; | ||
const Field& m_velocity; | ||
amrex::Gpu::DeviceVector<amrex::Real> gpu_vel_ht; |
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.
rename gpu_
to device_
{ | ||
const auto& vel = | ||
m_velocity.state(field_impl::dof_state(fstate))(lev).const_array(mfi); | ||
bool is_terrain = this->m_sim.repo().field_exists("terrainBlank"); |
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.
const bool
amr-wind/physics/TerrainDrag.H
Outdated
// Terrain Drag Force Term | ||
Field& m_terrainDrag; | ||
// Reading the Terrain Coordinates from file | ||
amrex::Vector<amrex::Real> m_xterrain, m_yterrain, m_zterrain; |
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.
just to be consistent with other things, can you declare on 1 line? Even better an amrex::Array of size AMREX_SPACEDIM. Same comment for line 56
} | ||
amrex::Real value1, value2, value3; | ||
while (file >> value1 >> value2 >> value3) { | ||
m_xterrain.push_back(value1); |
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.
so if you use Array, these become nice loops.
amr-wind/physics/TerrainDrag.cpp
Outdated
auto& terrainz0 = m_terrainz0(level); | ||
auto& drag = m_terrainDrag(level); | ||
// copy terrain data to gpu | ||
amrex::Gpu::DeviceVector<amrex::Real> gpu_xterrain(m_xterrain.size()); |
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.
gpu -> device
amr-wind/physics/TerrainDrag.cpp
Outdated
amrex::ParallelFor( | ||
vbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { | ||
// compute the source term | ||
const amrex::Real x1 = prob_lo[0] + (i + 0.5) * dx[0]; |
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.
call these x/y/z? or number from 0? Or stuff into gpuarray.
amr-wind/physics/TerrainDrag.cpp
Outdated
break; | ||
} | ||
} | ||
int turnOn = (x3 <= terrainHt) ? 1 : 0; |
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.
just do levelBlanking(i, j, k, 0) = static_cast(x3 <= terrainHt)
… into hgopalan-terrain
… into hgopalan-terrain
Have addressed the comments |
There's a stray update to the amrex submods that shouldn't be there. Can you remove that? |
const CFDSim& m_sim; | ||
const amrex::AmrCore& m_mesh; | ||
const Field& m_velocity; | ||
amrex::Gpu::DeviceVector<amrex::Real> device_vel_ht; |
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.
need the m_
prefix on these 2
const auto& dx = geom.CellSize(); | ||
const auto& prob_lo = geom.ProbLoArray(); | ||
const auto& prob_hi = geom.ProbHiArray(); | ||
const amrex::Real device_drag = m_drag; |
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.
sorry to be a pain. But you can remove all the device_
prefix here. That's the nice thing about using the m_
pfx in the first place. There's a bunch of places like that here.
const auto& geom_vec = m_mesh.Geom(); | ||
const auto& geom = geom_vec[lev]; | ||
const auto& dx = geom.CellSize(); | ||
const amrex::Real gpu_drag = m_drag; |
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.
similar to above. Just call this drag
etc.
m_z0rough.push_back(value3); | ||
} | ||
file1.close(); | ||
m_sim.io_manager().register_output_int_var("terrainDrag"); |
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.
I would use snake case for the output variables. It keeps things consistent.
@@ -0,0 +1,63 @@ | |||
#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨# |
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.
I think this case/file should be named terrain_box
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.
Agreed that this should be named terrain_box. But more importantly, the input file must have the same name as the directory in order for it to run with ctest. When you update the directory and input file names, make sure you update the CMakeLists.txt too
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.
Fixed.
tools/terrain/NREL.yaml
Outdated
@@ -0,0 +1,29 @@ | |||
solver: "amrWind" |
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.
We should remove these python scripts. There are no tests for these and we don't support python in the CI so these are liable to drift. We need to think of a better place to put these things. Right now it feels like they would belong to the amr-wind-frontend. Any thoughts on where this could live?
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.
I am not sure of the best way. I can create a separate toolkit GitHub repo for terrain.
The setting up of a terrain case by hand is not feasible and this was the reason I had to create the python codes. The user typically creates the terrain and then zooms in to see that the region of interest is sufficient for him and again reruns the script to create the workflow. Also when we create the refinement boxes, the python script lets us keep it at the terrain height and reduces the marking of unnecessary cells.
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.
This sure sounds useful. I would recommend a bunch of hardening: linting, proper packaging (with clear dependencies, python versions, etc), scripting (users don't edit the scripts, they pass arguments to the scripts).
The amr-wind-frontend could be a good place since that's what a lot of people are using to set up complex cases. I would hesitate to create yet another repo...
… GPU errors. Added a test case to show that IB does not affect the MOST BC.
Summary
This draft PR introduces an immersed forcing method for representing terrain within AMR-Wind. The terrain is generated outside amr-wind and this method does not rely on the existing immersed boundary method. The terrain runs are performed in steps:
The method can also be used to run cases without terrain such as an array of bluff bodies. The user has to create a XYZ file with the relevant information to do perform these simulations. The user can also use the stl2XYZ.py in tools/terrain folder to convert a STL file to XYZ file for AMR-Wind. It is recommended to have a smooth boundary near the inflow and outflow to reduce the number of iterations of the nodal and Mac projections.
The terrain modules have been designed to run with the Kosovic turbulence model. To use other turbulence models, the terrainBlanking information should be used to set the turbulent viscosity to zero in the solid region.
Pull request type
This is a draft PR and will be updated over the next weeks.
Please check the type of change introduced:
Checklist
The following is included:
This PR was tested by running:
Additional background
Issue Number: