/home/runner/work/kynema-sgf/kynema-sgf/src/equation_systems/tke/tke_ops.H Source File

Kynema-SGF API: /home/runner/work/kynema-sgf/kynema-sgf/src/equation_systems/tke/tke_ops.H Source File
Kynema-SGF API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
tke_ops.H
Go to the documentation of this file.
1#ifndef TKE_OPS_H
2#define TKE_OPS_H
3
7#include "AMReX_REAL.H"
8
9using namespace amrex::literals;
10
11namespace kynema_sgf::pde {
12
16template <>
18{
20 : m_tmodel(tmodel), m_fields(fields)
21 {}
22
24 {
25 auto& mueff = m_fields.mueff;
26 m_tmodel.update_scalar_diff(mueff, TKE::var_name());
27 }
28
31};
32
36template <>
38{
39 PostSolveOp(CFDSim& /*unused*/, PDEFields& fields) : m_fields(fields) {}
40
41 void operator()(const amrex::Real time)
42 {
43 auto& field = m_fields.field;
44 const auto& repo = field.repo();
45 const int nlevels = repo.num_active_levels();
46 const auto clip_value = m_clip_value;
47 for (int lev = 0; lev < nlevels; ++lev) {
48 const auto& field_arrs = field(lev).arrays();
49 amrex::ParallelFor(
50 field(lev), [=] AMREX_GPU_DEVICE(int nbx, int i, int j, int k) {
51 field_arrs[nbx](i, j, k) =
52 (field_arrs[nbx](i, j, k) < 0.0_rt)
53 ? clip_value
54 : field_arrs[nbx](i, j, k);
55 });
56 const bool has_terrain = repo.int_field_exists("terrain_blank");
57 if (has_terrain) {
58 const IntField& m_terrain_blank =
59 repo.get_int_field("terrain_blank");
60 const auto& blank_arrs = m_terrain_blank(lev).arrays();
61 amrex::ParallelFor(
62 field(lev),
63 [=] AMREX_GPU_DEVICE(int nbx, int i, int j, int k) {
64 field_arrs[nbx](i, j, k) =
65 (blank_arrs[nbx](i, j, k) == 1)
66 ? clip_value
67 : field_arrs[nbx](i, j, k);
68 });
69 }
70 }
71 amrex::Gpu::streamSynchronize();
72 m_fields.field.fillpatch(time);
73 }
74
76 amrex::Real m_clip_value{std::numeric_limits<float>::epsilon()};
77};
78
79template <typename Scheme>
80struct FieldRegOp<TKE, Scheme>
81{
82 explicit FieldRegOp(CFDSim& sim_in) : sim(sim_in)
83 {
84 amrex::ParmParse pp("TKE");
85
86 std::string interpolation;
87 pp.query("interpolation", interpolation);
88
89 if (interpolation == "PiecewiseConstant") {
91 amrex::Print()
92 << "using PiecewiseConstant interpolation for TKE fillpatch"
93 << '\n';
94 } else {
95 amrex::Print() << "using default CellConsLinear interpolation for "
96 "TKE fillpatch"
97 << '\n';
98 }
99 }
100
102 {
103 auto& repo = sim.repo();
104 auto fields = create_fields_instance<TKE, Scheme>(time, repo, m_itype);
105
106 repo.declare_cc_field(
107 TKE::var_name() + "_lhs_src_term", TKE::ndim, 1, 1);
108
109 sim.io_manager().register_io_var(fields.field.name());
110
111 return fields;
112 }
113
116};
117
121template <typename Scheme>
122struct DiffusionOp<TKE, Scheme> : public DiffSolverIface<typename TKE::MLDiffOp>
123{
124 static_assert(
125 TKE::ndim == 1, "DiffusionOp invoked for non-scalar TKE type");
126 static_assert(
127 std::is_same_v<typename TKE::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 TKE::MLDiffOp>(
133 fields, has_overset, mesh_mapping)
135 fields.repo.get_field(TKE::var_name() + "_lhs_src_term"))
136 {
137 this->m_solver->setDomainBC(
139 this->m_pdefields.field, amrex::Orientation::low),
141 this->m_pdefields.field, amrex::Orientation::high));
142 this->m_applier->setDomainBC(
144 this->m_pdefields.field, amrex::Orientation::low),
146 this->m_pdefields.field, amrex::Orientation::high));
147
148 m_lhs_src_term.setVal(0.0_rt);
149
151 }
152
154 void compute_diff_term(const FieldState fstate)
155 {
156 this->setup_operator(*this->m_applier, 0.0_rt, -1.0_rt, fstate);
157
158 auto tau_state =
159 std::is_same_v<Scheme, fvm::Godunov> ? FieldState::New : fstate;
160 amrex::MLMG mlmg(*this->m_applier);
161 mlmg.apply(
162 this->m_pdefields.diff_term.state(tau_state).vec_ptrs(),
163 this->m_pdefields.field.vec_ptrs());
164 }
165
166 void
167 set_acoeffs(typename TKE::MLDiffOp& linop, const FieldState fstate) override
168 {
169 BL_PROFILE("kynema-sgf::pde::set_acoeffs");
170 auto& repo = m_pdefields.repo;
171
172 const int nlevels = repo.num_active_levels();
173 auto& density = m_density.state(fstate);
175 *m_lhs_total, 1.0_rt, m_lhs_src_term, 0, 1.0_rt, density, 0, 0, 1,
176 1);
177
178 for (int lev = 0; lev < nlevels; ++lev) {
179 linop.setACoeffs(lev, (*m_lhs_total)(lev));
180 }
181 }
182
184 std::unique_ptr<ScratchField> m_lhs_total;
185};
186
187} // namespace kynema_sgf::pde
188
189#endif /* TKE_OPS_H */
Definition CFDSim.H:55
Definition Field.H:115
std::unique_ptr< ScratchField > create_scratch_field(const std::string &name, int ncomp=1, int nghost=0, FieldLoc floc=FieldLoc::CELL) const
Definition FieldRepo.cpp:312
Definition IntField.H:20
Definition SimTime.H:34
virtual void setup_operator(TKE::MLDiffOp &linop, amrex::Real alpha, amrex::Real beta, FieldState fstate)
Definition DiffusionOps.cpp:57
std::unique_ptr< TKE::MLDiffOp > m_solver
Definition DiffusionOps.H:107
std::unique_ptr< TKE::MLDiffOp > m_applier
Definition DiffusionOps.H:108
PDEFields & m_pdefields
Definition DiffusionOps.H:100
DiffSolverIface(PDEFields &fields, bool has_overset, bool mesh_mapping, const std::string &prefix="diffusion")
Definition DiffusionOps.cpp:12
Field & m_density
Definition DiffusionOps.H:101
Definition TurbulenceModel.H:32
void lincomb(T1 &dst, const amrex::Real a, const T2 &x, const int xcomp, const amrex::Real b, const T3 &y, const int ycomp, const int dstcomp, const int numcomp, const amrex::IntVect &nghost)
Definition field_ops.H:320
FieldState
Definition FieldDescTypes.H:16
FieldInterpolator
Coarse-to-fine field interpolation options.
Definition FieldDescTypes.H:39
@ New
Same as FieldState::NP1.
Definition FieldDescTypes.H:22
@ PiecewiseConstant
Constant across cell.
Definition FieldDescTypes.H:40
@ CellConsLinear
Linear interpolation.
Definition FieldDescTypes.H:41
amrex::Array< amrex::LinOpBCType, AMREX_SPACEDIM > get_diffuse_scalar_bc(kynema_sgf::Field &scalar, amrex::Orientation::Side side)
Definition incflo_diffusion.cpp:72
Definition AdvOp_Godunov.H:22
PDEFields create_fields_instance(const SimTime &time, FieldRepo &repo, const FieldInterpolator itype=FieldInterpolator::CellConsLinear)
Definition PDEHelpers.H:52
Field & m_lhs_src_term
Definition tke_ops.H:183
std::unique_ptr< ScratchField > m_lhs_total
Definition tke_ops.H:184
void compute_diff_term(const FieldState fstate)
Computes the diffusion term that goes in the RHS.
Definition tke_ops.H:154
DiffusionOp(PDEFields &fields, const bool has_overset, const bool mesh_mapping)
Definition tke_ops.H:130
void set_acoeffs(typename TKE::MLDiffOp &linop, const FieldState fstate) override
Definition tke_ops.H:167
CFDSim & sim
Definition tke_ops.H:114
PDEFields operator()(const SimTime &time)
Definition tke_ops.H:101
FieldRegOp(CFDSim &sim_in)
Definition tke_ops.H:82
FieldInterpolator m_itype
Definition tke_ops.H:115
Definition PDEFields.H:27
FieldRepo & repo
Reference to the field repository instance.
Definition PDEFields.H:31
amrex::Real m_clip_value
Definition tke_ops.H:76
PostSolveOp(CFDSim &, PDEFields &fields)
Definition tke_ops.H:39
PDEFields & m_fields
Definition tke_ops.H:75
void operator()(const amrex::Real time)
Definition tke_ops.H:41
Definition TKE.H:36
amrex::MLABecLaplacian MLDiffOp
Definition TKE.H:37
static std::string var_name()
Definition TKE.H:41
static constexpr int ndim
Definition TKE.H:45
void operator()()
Definition tke_ops.H:23
TurbulenceOp(turbulence::TurbulenceModel &tmodel, PDEFields &fields)
Definition tke_ops.H:19
turbulence::TurbulenceModel & m_tmodel
Definition tke_ops.H:29
PDEFields & m_fields
Definition tke_ops.H:30