/home/runner/work/kynema-sgf/kynema-sgf/src/fvm/qcriterion.H Source File

Kynema-SGF API: /home/runner/work/kynema-sgf/kynema-sgf/src/fvm/qcriterion.H Source File
Kynema-SGF API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
qcriterion.H
Go to the documentation of this file.
1#ifndef QCRITERION_H
2#define QCRITERION_H
3
4#include "src/fvm/fvm_utils.H"
5#include "AMReX_REAL.H"
6
7using namespace amrex::literals;
8
9namespace kynema_sgf::fvm {
10
14template <typename FTypeIn, typename FTypeOut>
16{
18 FTypeOut& qcritphi, const FTypeIn& phi, const bool nondim = false)
19 : m_qcritphi(qcritphi), m_phi(phi), m_nondim(nondim)
20 {
21 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
22 AMREX_SPACEDIM == m_phi.num_comp(),
23 "AMREX_SPACEDIM = " + std::to_string(AMREX_SPACEDIM) +
24 ", m_phi.num_comp() = " + std::to_string(m_phi.num_comp()));
25 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
26 m_phi.num_grow() > amrex::IntVect(0),
27 "m_phi.num_grow() = (" + std::to_string(m_phi.num_grow()[0]) +
28 ", " + std::to_string(m_phi.num_grow()[1]) + ", " +
29 std::to_string(m_phi.num_grow()[2]) + ")");
30 }
31
32 template <typename Stencil>
33 void apply(const int lev) const
34 {
35 const auto& geom = m_phi.repo().mesh().Geom(lev);
36 const auto& idx = geom.InvCellSizeArray();
37 const auto dlo = geom.Domain().smallEnd();
38 const auto dhi = geom.Domain().bigEnd();
39 const bool nondim = m_nondim;
40
41 auto& out_mf = m_qcritphi(lev);
42 auto const& in_arrs = m_phi(lev).const_arrays();
43 auto const& out_arrs = out_mf.arrays();
44
45 amrex::ParallelFor(
46 out_mf, amrex::IntVect(0),
47 [=] AMREX_GPU_DEVICE(int nbx, int i, int j, int k) {
48 if (!Stencil::applies_to(i, j, k, dlo, dhi)) {
49 return;
50 }
51 auto const& phi = in_arrs[nbx];
52 auto const& qcritphi = out_arrs[nbx];
53 const amrex::Real ux = ((Stencil::c00 * phi(i + 1, j, k, 0)) +
54 (Stencil::c01 * phi(i, j, k, 0)) +
55 (Stencil::c02 * phi(i - 1, j, k, 0))) *
56 idx[0];
57 const amrex::Real vx = ((Stencil::c00 * phi(i + 1, j, k, 1)) +
58 (Stencil::c01 * phi(i, j, k, 1)) +
59 (Stencil::c02 * phi(i - 1, j, k, 1))) *
60 idx[0];
61 const amrex::Real wx = ((Stencil::c00 * phi(i + 1, j, k, 2)) +
62 (Stencil::c01 * phi(i, j, k, 2)) +
63 (Stencil::c02 * phi(i - 1, j, k, 2))) *
64 idx[0];
65 const amrex::Real uy = ((Stencil::c10 * phi(i, j + 1, k, 0)) +
66 (Stencil::c11 * phi(i, j, k, 0)) +
67 (Stencil::c12 * phi(i, j - 1, k, 0))) *
68 idx[1];
69 const amrex::Real vy = ((Stencil::c10 * phi(i, j + 1, k, 1)) +
70 (Stencil::c11 * phi(i, j, k, 1)) +
71 (Stencil::c12 * phi(i, j - 1, k, 1))) *
72 idx[1];
73 const amrex::Real wy = ((Stencil::c10 * phi(i, j + 1, k, 2)) +
74 (Stencil::c11 * phi(i, j, k, 2)) +
75 (Stencil::c12 * phi(i, j - 1, k, 2))) *
76 idx[1];
77 const amrex::Real uz = ((Stencil::c20 * phi(i, j, k + 1, 0)) +
78 (Stencil::c21 * phi(i, j, k, 0)) +
79 (Stencil::c22 * phi(i, j, k - 1, 0))) *
80 idx[2];
81 const amrex::Real vz = ((Stencil::c20 * phi(i, j, k + 1, 1)) +
82 (Stencil::c21 * phi(i, j, k, 1)) +
83 (Stencil::c22 * phi(i, j, k - 1, 1))) *
84 idx[2];
85 const amrex::Real wz = ((Stencil::c20 * phi(i, j, k + 1, 2)) +
86 (Stencil::c21 * phi(i, j, k, 2)) +
87 (Stencil::c22 * phi(i, j, k - 1, 2))) *
88 idx[2];
89 const amrex::Real S2 = utils::powi(ux, 2) + utils::powi(vy, 2) +
90 utils::powi(wz, 2) +
91 (0.5_rt * utils::powi(uy + vx, 2)) +
92 (0.5_rt * utils::powi(vz + wy, 2)) +
93 (0.5_rt * utils::powi(wx + uz, 2));
94 const amrex::Real W2 = (0.5_rt * utils::powi(uy - vx, 2)) +
95 (0.5_rt * utils::powi(vz - wy, 2)) +
96 (0.5_rt * utils::powi(wx - uz, 2));
97 if (nondim) {
98 qcritphi(i, j, k) =
99 0.5_rt *
100 ((W2 / amrex::max<amrex::Real>(
101 std::numeric_limits<amrex::Real>::epsilon() *
102 1.0e2_rt,
103 S2)) -
104 1.0_rt);
105 } else {
106 qcritphi(i, j, k) = 0.5_rt * (W2 - S2);
107 }
108 });
109 }
110
111 FTypeOut& m_qcritphi;
112 const FTypeIn& m_phi;
114};
115
123template <typename FTypeIn, typename FTypeOut>
125 FTypeOut& qcritphi, const FTypeIn& phi, const bool nondim = false)
126{
127 BL_PROFILE("kynema-sgf::fvm::q_criterion");
128 Qcriterion<FTypeIn, FTypeOut> qcriterion(qcritphi, phi, nondim);
129 impl::apply(qcriterion, phi);
130}
131
137template <typename FType>
138std::unique_ptr<ScratchField> q_criterion(const FType& phi)
139{
140 const std::string gname = phi.name() + "_q_criterion";
141 auto qcritphi = phi.repo().create_scratch_field(gname, 1);
142 q_criterion(*qcritphi, phi);
143 return qcritphi;
144}
145
146} // namespace kynema_sgf::fvm
147
148#endif /* QCRITERION_H */
void q_criterion(FTypeOut &qcritphi, const FTypeIn &phi, const bool nondim=false)
Definition qcriterion.H:124
AMREX_INLINE void apply(const FvmOp &fvmop, const FType &fld)
Definition fvm_utils.H:20
Definition SchemeTraits.H:6
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real powi(const amrex::Real &x, const int &y)
Helper function to do pow() with integer exponents and output amrex::Real.
Definition math_ops.H:18
Definition qcriterion.H:16
FTypeOut & m_qcritphi
Definition qcriterion.H:111
void apply(const int lev) const
Definition qcriterion.H:33
bool m_nondim
Definition qcriterion.H:113
const FTypeIn & m_phi
Definition qcriterion.H:112
Qcriterion(FTypeOut &qcritphi, const FTypeIn &phi, const bool nondim=false)
Definition qcriterion.H:17