/home/runner/work/amr-wind/amr-wind/amr-wind/equation_systems/DiffusionOps.H Source File

AMR-Wind API: /home/runner/work/amr-wind/amr-wind/amr-wind/equation_systems/DiffusionOps.H Source File
AMR-Wind API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
DiffusionOps.H
Go to the documentation of this file.
1#ifndef DIFFUSIONOPS_H
2#define DIFFUSIONOPS_H
3
10
11#include "AMReX_MLABecLaplacian.H"
12#include "AMReX_MLTensorOp.H"
13#include "AMReX_MLMG.H"
14#include "AMReX_AmrCore.H"
15#include "AMReX_MultiFabUtil.H"
16#include "AMReX_REAL.H"
17
18using namespace amrex::literals;
19
20namespace amr_wind::pde {
21
31template <typename LinOp>
33{
34public:
36 PDEFields& fields,
37 const bool has_overset,
38 const bool mesh_mapping,
39 const std::string& prefix = "diffusion");
40
41 virtual ~DiffSolverIface() = default;
42
47 virtual void linsys_solve(const amrex::Real dt);
48
49 virtual void linsys_solve_impl();
50
51 virtual void set_acoeffs(LinOp& linop, const FieldState fstate);
52
53 template <typename L>
55 L& linop,
56 std::enable_if_t<std::is_same_v<L, amrex::MLTensorOp>>* /*unused*/
57 = nullptr)
58 {
59 const int nlevels = m_pdefields.repo.num_active_levels();
60 const auto& viscosity = m_pdefields.mueff;
61 const auto& geom = m_pdefields.repo.mesh().Geom();
62
63 for (int lev = 0; lev < nlevels; ++lev) {
65 geom[lev], viscosity(lev));
66 if (m_mesh_mapping) {
68 }
69 linop.setShearViscosity(lev, amrex::GetArrOfConstPtrs(b));
70 }
71 }
72
73 template <typename L>
75 L& linop,
76 std::enable_if_t<std::is_same_v<L, amrex::MLABecLaplacian>>* /*unused*/
77 = nullptr)
78 {
79 const int nlevels = m_pdefields.repo.num_active_levels();
80 const auto& viscosity = m_pdefields.mueff;
81 const auto& geom = m_pdefields.repo.mesh().Geom();
82
83 for (int lev = 0; lev < nlevels; ++lev) {
85 geom[lev], viscosity(lev));
86 if (m_mesh_mapping) {
88 }
89 linop.setBCoeffs(lev, amrex::GetArrOfConstPtrs(b));
90 }
91 }
92
93protected:
95 virtual void setup_operator(
96 LinOp& linop,
97 const amrex::Real alpha,
98 const amrex::Real beta,
99 const FieldState fstate);
100
101 virtual void setup_solver(amrex::MLMG& mlmg);
102
105
107
108 bool m_mesh_mapping{false};
109
110 std::unique_ptr<LinOp> m_solver;
111 std::unique_ptr<LinOp> m_applier;
112};
113
117template <typename PDE, typename Scheme>
119 PDE,
120 Scheme,
121 std::enable_if_t<std::is_base_of_v<ScalarTransport, PDE>>>
122 : public DiffSolverIface<typename PDE::MLDiffOp>
123{
124 static_assert(
125 PDE::ndim == 1, "DiffusionOp invoked for non-scalar PDE type");
126 static_assert(
127 std::is_same_v<typename PDE::MLDiffOp, amrex::MLABecLaplacian>,
128 "Invalid linear operator for scalar diffusion operator");
129
131 PDEFields& fields, const bool has_overset, const bool mesh_mapping)
132 : DiffSolverIface<typename PDE::MLDiffOp>(
133 fields, has_overset, mesh_mapping)
134 {
135 this->m_solver->setDomainBC(
137 this->m_pdefields.field, amrex::Orientation::low),
139 this->m_pdefields.field, amrex::Orientation::high));
140 this->m_applier->setDomainBC(
142 this->m_pdefields.field, amrex::Orientation::low),
144 this->m_pdefields.field, amrex::Orientation::high));
145 }
146
148 void compute_diff_term(const FieldState fstate)
149 {
150 this->setup_operator(*this->m_applier, 0.0_rt, -1.0_rt, fstate);
151
152 auto tau_state = std::is_same<Scheme, fvm::Godunov>::value
154 : fstate;
155
156 amrex::MLMG mlmg(*this->m_applier);
157 mlmg.apply(
158 this->m_pdefields.diff_term.state(tau_state).vec_ptrs(),
159 this->m_pdefields.field.vec_ptrs());
160
161 const auto& repo = this->m_pdefields.repo;
162 const int nlevels = repo.num_active_levels();
163 auto& divtau = this->m_pdefields.diff_term.state(tau_state);
164 const auto& density =
165 this->m_pdefields.repo.get_field("density").state(FieldState::NPH);
166 if (!PDE::multiply_rho) {
167 for (int lev = 0; lev < nlevels; ++lev) {
168 const auto& divtau_arrs = divtau(lev).arrays();
169 const auto& rho_arrs = density(lev).const_arrays();
170
171 amrex::ParallelFor(
172 divtau(lev), divtau.num_grow(), divtau.num_comp(),
173 [=] AMREX_GPU_DEVICE(
174 int nbx, int i, int j, int k, int n) noexcept {
175 const amrex::Real rhoinv =
176 1.0_rt / rho_arrs[nbx](i, j, k);
177 divtau_arrs[nbx](i, j, k, n) *= rhoinv;
178 });
179 }
180 amrex::Gpu::streamSynchronize();
181 }
182 }
183};
184
185} // namespace amr_wind::pde
186
187#endif /* DIFFUSIONOPS_H */
Definition Field.H:116
virtual void setup_solver(amrex::MLMG &mlmg)
Definition DiffusionOps.cpp:104
PDEFields & m_pdefields
Definition DiffusionOps.H:103
Field & m_density
Definition DiffusionOps.H:104
std::unique_ptr< LinOp > m_applier
Definition DiffusionOps.H:111
virtual void setup_operator(LinOp &linop, const amrex::Real alpha, const amrex::Real beta, const FieldState fstate)
Sets up the linear operator (e.g., setup BCs, etc.)
Definition DiffusionOps.cpp:57
void set_bcoeffs(L &linop, std::enable_if_t< std::is_same_v< L, amrex::MLABecLaplacian > > *=nullptr)
Definition DiffusionOps.H:74
MLMGOptions m_options
Definition DiffusionOps.H:106
virtual void linsys_solve_impl()
Definition DiffusionOps.cpp:112
bool m_mesh_mapping
Definition DiffusionOps.H:108
virtual void linsys_solve(const amrex::Real dt)
Definition DiffusionOps.cpp:154
std::unique_ptr< LinOp > m_solver
Definition DiffusionOps.H:110
void set_bcoeffs(L &linop, std::enable_if_t< std::is_same_v< L, amrex::MLTensorOp > > *=nullptr)
Definition DiffusionOps.H:54
virtual void set_acoeffs(LinOp &linop, const FieldState fstate)
Definition DiffusionOps.cpp:76
DiffSolverIface(PDEFields &fields, const bool has_overset, const bool mesh_mapping, const std::string &prefix="diffusion")
Definition DiffusionOps.cpp:12
virtual ~DiffSolverIface()=default
FieldState
Definition FieldDescTypes.H:14
@ New
Same as FieldState::NP1.
Definition FieldDescTypes.H:20
@ NPH
State at (n + 1/2) (intermediate) timestep.
Definition FieldDescTypes.H:18
Definition AdvOp_Godunov.H:21
void viscosity_to_uniform_space(amrex::Array< amrex::MultiFab, AMREX_SPACEDIM > &b, const amr_wind::FieldRepo &repo, int lev)
Definition incflo_diffusion.cpp:207
amrex::Array< amrex::LinOpBCType, AMREX_SPACEDIM > get_diffuse_scalar_bc(amr_wind::Field &scalar, amrex::Orientation::Side side) noexcept
Definition incflo_diffusion.cpp:70
amrex::Array< amrex::MultiFab, AMREX_SPACEDIM > average_velocity_eta_to_faces(const amrex::Geometry &geom, amrex::MultiFab const &cc_eta)
Definition incflo_diffusion.cpp:107
Definition MLMGOptions.H:27
DiffusionOp(PDEFields &fields, const bool has_overset, const bool mesh_mapping)
Definition DiffusionOps.H:130
void compute_diff_term(const FieldState fstate)
Computes the diffusion term that goes in the RHS.
Definition DiffusionOps.H:148
Definition PDEFields.H:27