-
Notifications
You must be signed in to change notification settings - Fork 83
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
Forest Canopy Model #1324
Open
hgopalan
wants to merge
43
commits into
Exawind:main
Choose a base branch
from
hgopalan:forest_drag
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Forest Canopy Model #1324
Changes from 15 commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
90de3b7
Initial commit for the forest drag model
hgopalan 80ca45b
Update amr-wind/physics/ForestDrag.cpp
hgopalan 96616ee
Update amr-wind/physics/ForestDrag.H
hgopalan f83db56
Fix docker CI (#1326)
jrood-nrel 91ec7a5
Use linear interpolation in DragForcing (#1323)
marchdf 660ecc3
Some cleaning
hgopalan ad80a56
Merge branch 'Exawind:main' into forest_drag
hgopalan 060a11e
Remove unused
hgopalan f257369
Merge branch 'Exawind:main' into forest_drag
hgopalan 75d0578
Merge branch 'Exawind:main' into forest_drag
hgopalan 8d8bd69
Merge branch 'main' into forest_drag
hgopalan 0f039e4
Clean up code with structures and some for loop rearrangement
hgopalan b5581d4
Structure does not work in lambda
hgopalan 29f6680
name case
hgopalan d0e053c
Adding documentation and option to specify forest file
hgopalan f21e818
Cleaning. Removing.
hgopalan ec6ccc0
Merge branch 'main' into forest_drag
hgopalan 02c3389
documentation broke
hgopalan 936fc25
Some clean-up.
hgopalan 0cd8e08
Update amr-wind/physics/ForestDrag.H
marchdf 36a1205
Update amr-wind/physics/ForestDrag.H
marchdf 296d493
Merge branch 'main' into forest_drag
marchdf 5e71e3f
Big rewrite
marchdf 64cf09b
enable tiling
marchdf 698484a
remove velocity
marchdf 1ad9634
grab the ghosts
marchdf 2a92d1e
refactor af
marchdf 0868db5
retweak
marchdf 79f60aa
remove anon namespace
marchdf 5fbc7b1
see if this builds for cuda/hip/rocm
marchdf 30d1cc0
format
marchdf df6dea8
Fixes
marchdf 745b433
rename
marchdf e100087
rename
marchdf 6f865e8
Unit Test
hgopalan 1d906a8
Fix unit test
marchdf 05e9450
add a check
marchdf 26bd187
Merge branch 'main' into forest_drag
marchdf 74fc7aa
Fix the integrals
marchdf 2800402
Better unit tests
marchdf 2644236
style thing
marchdf fb325d2
linting fix
marchdf de85d10
sigh
marchdf File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
amr-wind/equation_systems/icns/source_terms/ForestForcing.H
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#ifndef FORESTFORCING_H | ||
#define FORESTFORCING_H | ||
|
||
#include "amr-wind/equation_systems/icns/MomentumSource.H" | ||
#include "amr-wind/core/SimTime.H" | ||
#include "amr-wind/CFDSim.H" | ||
|
||
namespace amr_wind::pde::icns { | ||
|
||
/** Adds the forcing term to include the presence of immersed boundary | ||
* | ||
* \ingroup icns_src | ||
* | ||
* | ||
*/ | ||
class ForestForcing : public MomentumSource::Register<ForestForcing> | ||
{ | ||
public: | ||
static std::string identifier() { return "ForestForcing"; } | ||
|
||
explicit ForestForcing(const CFDSim& sim); | ||
|
||
~ForestForcing() override; | ||
|
||
void operator()( | ||
const int lev, | ||
const amrex::MFIter& mfi, | ||
const amrex::Box& bx, | ||
const FieldState fstate, | ||
const amrex::Array4<amrex::Real>& src_term) const override; | ||
|
||
private: | ||
const CFDSim& m_sim; | ||
const Field& m_velocity; | ||
}; | ||
|
||
} // namespace amr_wind::pde::icns | ||
|
||
#endif |
42 changes: 42 additions & 0 deletions
42
amr-wind/equation_systems/icns/source_terms/ForestForcing.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include "amr-wind/equation_systems/icns/source_terms/ForestForcing.H" | ||
#include "amr-wind/utilities/IOManager.H" | ||
|
||
#include "AMReX_Gpu.H" | ||
#include "AMReX_Random.H" | ||
#include "amr-wind/wind_energy/ABL.H" | ||
|
||
namespace amr_wind::pde::icns { | ||
|
||
ForestForcing::ForestForcing(const CFDSim& sim) | ||
: m_sim(sim), m_velocity(sim.repo().get_field("velocity")) | ||
{} | ||
|
||
ForestForcing::~ForestForcing() = default; | ||
|
||
void ForestForcing::operator()( | ||
const int lev, | ||
const amrex::MFIter& mfi, | ||
const amrex::Box& bx, | ||
const FieldState fstate, | ||
const amrex::Array4<amrex::Real>& src_term) const | ||
{ | ||
const auto& vel = | ||
m_velocity.state(field_impl::dof_state(fstate))(lev).const_array(mfi); | ||
const bool has_forest = this->m_sim.repo().field_exists("forest_drag"); | ||
if (!has_forest) { | ||
amrex::Abort("Need a forest to use this source term"); | ||
} | ||
auto* const m_forest_drag = &this->m_sim.repo().get_field("forest_drag"); | ||
const auto& forest_drag = (*m_forest_drag)(lev).const_array(mfi); | ||
amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { | ||
const amrex::Real ux = vel(i, j, k, 0); | ||
const amrex::Real uy = vel(i, j, k, 1); | ||
const amrex::Real uz = vel(i, j, k, 2); | ||
const amrex::Real windspeed = std::sqrt(ux * ux + uy * uy + uz * uz); | ||
src_term(i, j, k, 0) -= forest_drag(i, j, k) * ux * windspeed; | ||
src_term(i, j, k, 1) -= forest_drag(i, j, k) * uy * windspeed; | ||
src_term(i, j, k, 2) -= forest_drag(i, j, k) * uz * windspeed; | ||
}); | ||
} | ||
|
||
} // namespace amr_wind::pde::icns |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#ifndef ForestDrag_H | ||
#define ForestDrag_H | ||
|
||
#include "amr-wind/core/Physics.H" | ||
#include "amr-wind/core/Field.H" | ||
#include "amr-wind/CFDSim.H" | ||
|
||
namespace amr_wind::forestdrag { | ||
|
||
namespace {} // namespace | ||
|
||
/** Forestdrag Flow physics | ||
* \ingroup physics | ||
*/ | ||
|
||
class ForestDrag : public Physics::Register<ForestDrag> | ||
{ | ||
public: | ||
static std::string identifier() { return "ForestDrag"; } | ||
|
||
explicit ForestDrag(CFDSim& sim); | ||
|
||
~ForestDrag() override = default; | ||
|
||
void | ||
initialize_fields(int /*level*/, const amrex::Geometry& /*geom*/) override | ||
{} | ||
|
||
void pre_init_actions() override; | ||
|
||
void post_init_actions() override; | ||
|
||
void post_regrid_actions() override {} | ||
|
||
void pre_advance_work() override {} | ||
|
||
void post_advance_work() override {} | ||
|
||
int return_blank_value(int i, int j, int k); | ||
|
||
private: | ||
CFDSim& m_sim; | ||
const FieldRepo& m_repo; | ||
const amrex::AmrCore& m_mesh; | ||
Field& m_velocity; | ||
//! Forest Drag Force Term | ||
Field& m_forest_drag; | ||
Field& m_forest_blank; | ||
struct Forest | ||
marchdf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
amrex::Real type_forest; | ||
marchdf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
amrex::Real x_forest; | ||
amrex::Real y_forest; | ||
amrex::Real height_forest; | ||
amrex::Real diameter_forest; | ||
amrex::Real cd_forest; | ||
amrex::Real lai_forest; | ||
amrex::Real laimax_forest; | ||
}; | ||
amrex::Vector<Forest> m_forests; | ||
amrex::Gpu::DeviceVector<Forest> m_d_forests; | ||
}; | ||
} // namespace amr_wind::forestdrag | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
#include "amr-wind/physics/ForestDrag.H" | ||
#include "amr-wind/CFDSim.H" | ||
#include "AMReX_iMultiFab.H" | ||
#include "AMReX_MultiFabUtil.H" | ||
#include "AMReX_ParmParse.H" | ||
#include "AMReX_ParReduce.H" | ||
#include "amr-wind/utilities/trig_ops.H" | ||
#include "amr-wind/utilities/IOManager.H" | ||
|
||
namespace amr_wind::forestdrag { | ||
|
||
namespace {} // namespace | ||
|
||
ForestDrag::ForestDrag(CFDSim& sim) | ||
: m_sim(sim) | ||
, m_repo(sim.repo()) | ||
, m_mesh(sim.mesh()) | ||
, m_velocity(sim.repo().get_field("velocity")) | ||
, m_forest_drag(sim.repo().declare_field("forest_drag", 1, 1, 1)) | ||
, m_forest_blank(sim.repo().declare_field("forest_blank", 1, 1, 1)) | ||
{ | ||
std::string forestfile("forest.amrwind"); | ||
amrex::ParmParse pp(identifier()); | ||
pp.query("forest_file", forestfile); | ||
std::ifstream file(forestfile, std::ios::in); | ||
if (!file.good()) { | ||
amrex::Abort("Cannot find file " +forestfile); | ||
} | ||
//! TreeType xc yc height diameter cd lai laimax | ||
amrex::Real value1, value2, value3, value4, value5, value6, value7, value8; | ||
while (file >> value1 >> value2 >> value3 >> value4 >> value5 >> value6 >> | ||
value7 >> value8) { | ||
Forest f; | ||
marchdf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
f.type_forest = value1; | ||
f.x_forest = value2; | ||
f.y_forest = value3; | ||
f.height_forest = value4; | ||
f.diameter_forest = value5; | ||
f.cd_forest = value6; | ||
f.lai_forest = value7; | ||
f.laimax_forest = value8; | ||
m_forests.push_back(f); | ||
} | ||
file.close(); | ||
m_d_forests.resize(m_forests.size()); | ||
m_sim.io_manager().register_output_var("forest_drag"); | ||
marchdf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
m_sim.io_manager().register_output_var("forest_blank"); | ||
} | ||
|
||
void ForestDrag::post_init_actions() | ||
{ | ||
BL_PROFILE("amr-wind::" + this->identifier() + "::post_init_actions"); | ||
const auto& geom_vec = m_sim.repo().mesh().Geom(); | ||
const int nlevels = m_sim.repo().num_active_levels(); | ||
for (int level = 0; level < nlevels; ++level) { | ||
const auto& geom = geom_vec[level]; | ||
const auto& dx = geom.CellSizeArray(); | ||
const auto& prob_lo = geom.ProbLoArray(); | ||
auto& velocity = m_velocity(level); | ||
auto& drag = m_forest_drag(level); | ||
auto& blank = m_forest_blank(level); | ||
amrex::Gpu::copy( | ||
marchdf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
amrex::Gpu::hostToDevice, m_forests.begin(), m_forests.end(), | ||
m_d_forests.begin()); | ||
const auto* forests_ptr = m_d_forests.data(); | ||
const auto forestSize = m_d_forests.size(); | ||
for (unsigned ii = 0; ii < forestSize; ++ii) { | ||
amrex::Real treelaimax = 0; | ||
amrex::Real treeZm = 0.0; | ||
const amrex::Real type_forest = forests_ptr[ii].type_forest; | ||
marchdf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const amrex::Real x_forest = forests_ptr[ii].x_forest; | ||
const amrex::Real y_forest = forests_ptr[ii].y_forest; | ||
const amrex::Real height_forest = forests_ptr[ii].height_forest; | ||
const amrex::Real diameter_forest = forests_ptr[ii].diameter_forest; | ||
const amrex::Real cd_forest = forests_ptr[ii].cd_forest; | ||
const amrex::Real lai_forest = forests_ptr[ii].lai_forest; | ||
const amrex::Real laimax_forest = forests_ptr[ii].laimax_forest; | ||
if (type_forest == 2) { | ||
marchdf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
amrex::Real ztree = 0; | ||
amrex::Real expFun = 0; | ||
amrex::Real ratio = 0; | ||
treeZm = laimax_forest * height_forest; | ||
const amrex::Real dz = height_forest / 100; | ||
while (ztree <= height_forest) { | ||
marchdf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ratio = (height_forest - treeZm) / (height_forest - ztree); | ||
if (ztree < treeZm) { | ||
expFun = expFun + std::pow(ratio, 6.0) * | ||
std::exp(6 * (1 - ratio)); | ||
} else { | ||
expFun = expFun + std::pow(ratio, 0.5) * | ||
std::exp(0.5 * (1 - ratio)); | ||
} | ||
ztree = ztree + dz; | ||
} | ||
treelaimax = lai_forest / (expFun * dz); | ||
} | ||
for (amrex::MFIter mfi(velocity); mfi.isValid(); ++mfi) { | ||
marchdf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const auto& vbx = mfi.validbox(); | ||
auto levelDrag = drag.array(mfi); | ||
auto levelBlank = blank.array(mfi); | ||
amrex::ParallelFor( | ||
vbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { | ||
// compute the source term | ||
amrex::Real af = 0; | ||
const amrex::Real x = prob_lo[0] + (i + 0.5) * dx[0]; | ||
const amrex::Real y = prob_lo[1] + (j + 0.5) * dx[1]; | ||
const amrex::Real z = prob_lo[2] + (k + 0.5) * dx[2]; | ||
const amrex::Real radius = std::sqrt( | ||
(x - x_forest) * (x - x_forest) + | ||
(y - y_forest) * (y - y_forest)); | ||
if (z <= height_forest && | ||
marchdf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
radius <= (0.5 * diameter_forest)) { | ||
if (type_forest == 1) { | ||
af = lai_forest / height_forest; | ||
} else if (type_forest == 2) { | ||
const amrex::Real ratio = | ||
(height_forest - treeZm) / | ||
(height_forest - z); | ||
if (z < treeZm) { | ||
af = treelaimax * std::pow(ratio, 6.0) * | ||
std::exp(6 * (1 - ratio)); | ||
} else if (z <= height_forest) { | ||
af = treelaimax * std::pow(ratio, 0.5) * | ||
std::exp(0.5 * (1 - ratio)); | ||
} | ||
} | ||
levelBlank(i, j, k) = ii + 1; | ||
levelDrag(i, j, k) = cd_forest * af; | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
|
||
void ForestDrag::pre_init_actions() | ||
{ | ||
BL_PROFILE("amr-wind::" + this->identifier() + "::pre_init_actions"); | ||
} | ||
} // namespace amr_wind::forestdrag |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
1 1024 512 45 200 0.2 6 0.8 | ||
1 1024 1024 35 200 0.2 6 0.8 | ||
1 1024 1224 75 200 0.2 6 0.8 | ||
2 1024 1524 120 200 0.2 10 0.8 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
out of date comment