/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 bool has_overset,
38 bool mesh_mapping,
39 const std::string& prefix = "diffusion");
40
41 virtual ~DiffSolverIface() = default;
42
47 virtual void linsys_solve(amrex::Real dt);
48
49 virtual void linsys_solve_impl();
50
51 virtual void set_acoeffs(LinOp& linop, 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, amrex::Real alpha, amrex::Real beta, FieldState fstate);
97
98 virtual void setup_solver(amrex::MLMG& mlmg);
99
102
104
105 bool m_mesh_mapping{false};
106
107 std::unique_ptr<LinOp> m_solver;
108 std::unique_ptr<LinOp> m_applier;
109};
110
114template <typename PDE, typename Scheme>
116 PDE,
117 Scheme,
118 std::enable_if_t<std::is_base_of_v<ScalarTransport, PDE>>>
119 : public DiffSolverIface<typename PDE::MLDiffOp>
120{
121 static_assert(
122 PDE::ndim == 1, "DiffusionOp invoked for non-scalar PDE type");
123 static_assert(
124 std::is_same_v<typename PDE::MLDiffOp, amrex::MLABecLaplacian>,
125 "Invalid linear operator for scalar diffusion operator");
126
128 PDEFields& fields, const bool has_overset, const bool mesh_mapping)
129 : DiffSolverIface<typename PDE::MLDiffOp>(
130 fields, has_overset, mesh_mapping)
131 {
132 this->m_solver->setDomainBC(
134 this->m_pdefields.field, amrex::Orientation::low),
136 this->m_pdefields.field, amrex::Orientation::high));
137 this->m_applier->setDomainBC(
139 this->m_pdefields.field, amrex::Orientation::low),
141 this->m_pdefields.field, amrex::Orientation::high));
142 }
143
145 void compute_diff_term(const FieldState fstate)
146 {
147 this->setup_operator(*this->m_applier, 0.0_rt, -1.0_rt, fstate);
148
149 auto tau_state =
150 std::is_same_v<Scheme, fvm::Godunov> ? FieldState::New : fstate;
151
152 amrex::MLMG mlmg(*this->m_applier);
153 mlmg.apply(
154 this->m_pdefields.diff_term.state(tau_state).vec_ptrs(),
155 this->m_pdefields.field.vec_ptrs());
156
157 const auto& repo = this->m_pdefields.repo;
158 const int nlevels = repo.num_active_levels();
159 auto& divtau = this->m_pdefields.diff_term.state(tau_state);
160 const auto& density =
161 this->m_pdefields.repo.get_field("density").state(FieldState::NPH);
162 if (!PDE::multiply_rho) {
163 for (int lev = 0; lev < nlevels; ++lev) {
164 const auto& divtau_arrs = divtau(lev).arrays();
165 const auto& rho_arrs = density(lev).const_arrays();
166
167 amrex::ParallelFor(
168 divtau(lev), divtau.num_grow(), divtau.num_comp(),
169 [=] AMREX_GPU_DEVICE(int nbx, int i, int j, int k, int n) {
170 const amrex::Real rhoinv =
171 1.0_rt / rho_arrs[nbx](i, j, k);
172 divtau_arrs[nbx](i, j, k, n) *= rhoinv;
173 });
174 }
175 amrex::Gpu::streamSynchronize();
176 }
177 }
178};
179
180} // namespace amr_wind::pde
181
182#endif /* DIFFUSIONOPS_H */
Definition Field.H:112
virtual void setup_solver(amrex::MLMG &mlmg)
Definition DiffusionOps.cpp:104
PDEFields & m_pdefields
Definition DiffusionOps.H:100
Field & m_density
Definition DiffusionOps.H:101
virtual void linsys_solve(amrex::Real dt)
Definition DiffusionOps.cpp:154
std::unique_ptr< LinOp > m_applier
Definition DiffusionOps.H:108
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:103
virtual void set_acoeffs(LinOp &linop, FieldState fstate)
Definition DiffusionOps.cpp:76
virtual void linsys_solve_impl()
Definition DiffusionOps.cpp:112
bool m_mesh_mapping
Definition DiffusionOps.H:105
virtual void setup_operator(LinOp &linop, amrex::Real alpha, amrex::Real beta, FieldState fstate)
Sets up the linear operator (e.g., setup BCs, etc.)
Definition DiffusionOps.cpp:57
std::unique_ptr< LinOp > m_solver
Definition DiffusionOps.H:107
void set_bcoeffs(L &linop, std::enable_if_t< std::is_same_v< L, amrex::MLTensorOp > > *=nullptr)
Definition DiffusionOps.H:54
DiffSolverIface(PDEFields &fields, bool has_overset, bool mesh_mapping, const std::string &prefix="diffusion")
Definition DiffusionOps.cpp:12
virtual ~DiffSolverIface()=default
FieldState
Definition FieldDescTypes.H:16
@ New
Same as FieldState::NP1.
Definition FieldDescTypes.H:22
@ NPH
State at (n + 1/2) (intermediate) timestep.
Definition FieldDescTypes.H:20
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:206
amrex::Array< amrex::LinOpBCType, AMREX_SPACEDIM > get_diffuse_scalar_bc(amr_wind::Field &scalar, amrex::Orientation::Side side)
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:106
Definition MLMGOptions.H:27
DiffusionOp(PDEFields &fields, const bool has_overset, const bool mesh_mapping)
Definition DiffusionOps.H:127
void compute_diff_term(const FieldState fstate)
Computes the diffusion term that goes in the RHS.
Definition DiffusionOps.H:145
Definition PDEFields.H:27