/home/runner/work/amr-wind/amr-wind/amr-wind/overset/overset_ops_K.H Source File

AMR-Wind API: /home/runner/work/amr-wind/amr-wind/amr-wind/overset/overset_ops_K.H Source File
AMR-Wind API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
overset_ops_K.H
Go to the documentation of this file.
1#ifndef OVERSET_OPS_K_H_
2#define OVERSET_OPS_K_H_
3
5#include <AMReX_FArrayBox.H>
6
8
9// Approximate signed distance function
10amrex::Real AMREX_GPU_DEVICE AMREX_FORCE_INLINE
11asdf(const amrex::Real a_vof, const amrex::Real i_th, const amrex::Real tiny)
12{
13 // function of local vof value and interface thickness
14 return (i_th * log((a_vof + tiny) / (1. - a_vof + tiny)));
15}
16
17amrex::Real AMREX_GPU_DEVICE AMREX_FORCE_INLINE alpha_flux(
18 const int i,
19 const int j,
20 const int k,
21 const int dir,
22 const amrex::Real margin,
23 amrex::Array4<amrex::Real const> const& vof,
24 amrex::Array4<amrex::Real const> const& tg_vof,
25 amrex::Array4<amrex::Real const> const& normal)
26{
27 // Set up neighbor indices
28 const amrex::IntVect iv{i, j, k};
29 const amrex::IntVect dv{(int)(dir == 0), (int)(dir == 1), (int)(dir == 2)};
30 const amrex::IntVect ivm = iv - dv;
31
32 // Gradient of phi normal to interface
33 const amrex::Real gphi = (vof(iv) - vof(ivm));
34 // Normal vector in each cell (already normalized)
35 const amrex::Real norm_ = std::abs(normal(iv, dir));
36 const amrex::Real norm_nb = std::abs(normal(ivm, dir));
37
38 // Determine which delta_phi (and multiply by normal)
39 // The sign depends on side of flux face
40 const amrex::Real dphi_ = (vof(iv) - tg_vof(iv)) * norm_;
41 const amrex::Real dphi_nb = (tg_vof(ivm) - vof(ivm)) * norm_nb;
42 // Average value used across the interface
43 amrex::Real dphi_eval = 0.5 * (dphi_ + dphi_nb);
44 // Upwinding when on the gas side, downwinding on the liquid
45 // Across the interface defined as crossing 0.5 or within margin of 0.5
46 if ((std::abs(vof(iv) - 0.5) > margin ||
47 std::abs(vof(ivm) - 0.5) > margin)) {
48 if (gphi > 0.0) {
49 dphi_eval = (vof(ivm) < 0.5 && vof(iv) <= 0.5 + margin) ? dphi_nb
50 : dphi_eval;
51 dphi_eval =
52 (vof(ivm) >= 0.5 - margin && vof(iv) > 0.5) ? dphi_ : dphi_eval;
53 }
54 if (gphi < 0.0) {
55 dphi_eval =
56 (vof(iv) < 0.5 && vof(ivm) <= 0.5 + margin) ? dphi_ : dphi_eval;
57 dphi_eval = (vof(iv) >= 0.5 - margin && vof(ivm) > 0.5) ? dphi_nb
58 : dphi_eval;
59 }
60 }
61 return dphi_eval;
62}
63
64void AMREX_GPU_DEVICE AMREX_FORCE_INLINE velocity_face(
65 const int i,
66 const int j,
67 const int k,
68 const int dir,
69 amrex::Array4<amrex::Real const> const& vof,
70 amrex::Array4<amrex::Real const> const& velocity,
71 amrex::Real& uface,
72 amrex::Real& vface,
73 amrex::Real& wface)
74{
75 // Set up neighbor indices
76 const amrex::IntVect iv{i, j, k};
77 const amrex::IntVect dv{(int)(dir == 0), (int)(dir == 1), (int)(dir == 2)};
78 const amrex::IntVect ivm = iv - dv;
79
80 // Gradient of phi normal to interface
81 const amrex::Real gphi = (vof(iv) - vof(ivm));
82
83 // Get velocities on both sides
84 const amrex::Real u_ = velocity(iv, 0);
85 const amrex::Real v_ = velocity(iv, 1);
86 const amrex::Real w_ = velocity(iv, 2);
87 const amrex::Real u_nb = velocity(ivm, 0);
88 const amrex::Real v_nb = velocity(ivm, 1);
89 const amrex::Real w_nb = velocity(ivm, 2);
90 // Average value when gphi = 0
91 uface = 0.5 * (u_ + u_nb);
92 vface = 0.5 * (v_ + v_nb);
93 wface = 0.5 * (w_ + w_nb);
94 // Use simple upwinding
95 if (gphi > 0.0) {
96 uface = u_nb;
97 vface = v_nb;
98 wface = w_nb;
99 }
100 if (gphi < 0.0) {
101 uface = u_;
102 vface = v_;
103 wface = w_;
104 }
105}
106
107void AMREX_GPU_DEVICE AMREX_FORCE_INLINE gp_rho_face(
108 const int i,
109 const int j,
110 const int k,
111 const int dir,
112 amrex::Array4<amrex::Real const> const& vof,
113 amrex::Array4<amrex::Real const> const& gp,
114 amrex::Array4<amrex::Real const> const& rho,
115 amrex::Real& uface,
116 amrex::Real& vface,
117 amrex::Real& wface)
118{
119 // Set up neighbor indices
120 const amrex::IntVect iv{i, j, k};
121 const amrex::IntVect dv{(int)(dir == 0), (int)(dir == 1), (int)(dir == 2)};
122 const amrex::IntVect ivm = iv - dv;
123
124 // Gradient of phi normal to interface
125 const amrex::Real gphi = (vof(iv) - vof(ivm));
126
127 // Get velocities on both sides
128 const amrex::Real u_ = gp(iv, 0) / rho(iv);
129 const amrex::Real v_ = gp(iv, 1) / rho(iv);
130 const amrex::Real w_ = gp(iv, 2) / rho(iv);
131 const amrex::Real u_nb = gp(ivm, 0) / rho(ivm);
132 const amrex::Real v_nb = gp(ivm, 1) / rho(ivm);
133 const amrex::Real w_nb = gp(ivm, 2) / rho(ivm);
134 // Average value when gphi = 0
135 uface = 0.5 * (u_ + u_nb);
136 vface = 0.5 * (v_ + v_nb);
137 wface = 0.5 * (w_ + w_nb);
138 // Use simple upwinding
139 if (gphi > 0.0) {
140 uface = u_nb;
141 vface = v_nb;
142 wface = w_nb;
143 }
144 if (gphi < 0.0) {
145 uface = u_;
146 vface = v_;
147 wface = w_;
148 }
149}
150
151vs::Tensor AMREX_GPU_DEVICE AMREX_FORCE_INLINE gp_flux_tensor(
152 const int i,
153 const int j,
154 const int k,
155 amrex::Array4<amrex::Real const> const& fx,
156 amrex::Array4<amrex::Real const> const& fy,
157 amrex::Array4<amrex::Real const> const& fz,
158 const amrex::Real tiny)
159{
160 // Averaging depends on iblank array, encoded in 8th component
161 const amrex::Real avg_fx = fx(i, j, k, 8) + fx(i, j, k - 1, 8) +
162 fx(i, j - 1, k, 8) + fx(i, j - 1, k - 1, 8) +
163 tiny;
164 const amrex::Real avg_fy = fy(i, j, k, 8) + fy(i - 1, j, k, 8) +
165 fy(i, j, k - 1, 8) + fy(i - 1, j, k - 1, 8) +
166 tiny;
167 const amrex::Real avg_fz = fz(i, j, k, 8) + fz(i - 1, j, k, 8) +
168 fz(i, j - 1, k, 8) + fz(i - 1, j - 1, k, 8) +
169 tiny;
170
171 auto f_otimes_gradp = vs::Tensor::identity();
172 // Average fluxes (faces) to nodes where pressure exists
173 f_otimes_gradp.xx() = (fx(i, j, k, 5) + fx(i, j, k - 1, 5) +
174 fx(i, j - 1, k, 5) + fx(i, j - 1, k - 1, 5)) /
175 avg_fx;
176 f_otimes_gradp.xy() = (fx(i, j, k, 6) + fx(i, j, k - 1, 6) +
177 fx(i, j - 1, k, 6) + fx(i, j - 1, k - 1, 6)) /
178 avg_fx;
179 f_otimes_gradp.xz() = (fx(i, j, k, 7) + fx(i, j, k - 1, 7) +
180 fx(i, j - 1, k, 7) + fx(i, j - 1, k - 1, 7)) /
181 avg_fx;
182 f_otimes_gradp.yx() = (fy(i, j, k, 5) + fy(i - 1, j, k, 5) +
183 fy(i, j, k - 1, 5) + fy(i - 1, j, k - 1, 5)) /
184 avg_fy;
185 f_otimes_gradp.yy() = (fy(i, j, k, 6) + fy(i - 1, j, k, 6) +
186 fy(i, j, k - 1, 6) + fy(i - 1, j, k - 1, 6)) /
187 avg_fy;
188 f_otimes_gradp.yz() = (fy(i, j, k, 7) + fy(i - 1, j, k, 7) +
189 fy(i, j, k - 1, 7) + fy(i - 1, j, k - 1, 7)) /
190 avg_fy;
191 f_otimes_gradp.zx() = (fz(i, j, k, 5) + fz(i - 1, j, k, 5) +
192 fz(i, j - 1, k, 5) + fz(i - 1, j - 1, k, 5)) /
193 avg_fz;
194 f_otimes_gradp.zy() = (fz(i, j, k, 6) + fz(i - 1, j, k, 6) +
195 fz(i, j - 1, k, 6) + fz(i - 1, j - 1, k, 6)) /
196 avg_fz;
197 f_otimes_gradp.zz() = (fz(i, j, k, 7) + fz(i - 1, j, k, 7) +
198 fz(i, j - 1, k, 7) + fz(i - 1, j - 1, k, 7)) /
199 avg_fz;
200
201 return f_otimes_gradp;
202}
203
204vs::Tensor AMREX_GPU_DEVICE AMREX_FORCE_INLINE normal_reinit_tensor(
205 const int i,
206 const int j,
207 const int k,
208 amrex::Array4<amrex::Real const> const& fx,
209 amrex::Array4<amrex::Real const> const& fy,
210 amrex::Array4<amrex::Real const> const& fz,
211 amrex::Array4<amrex::Real const> const& vof,
212 const amrex::Real tiny)
213{
214 // Averaging depends on iblank array, encoded in 8th component
215 const amrex::Real avg_fx = fx(i, j, k, 8) + fx(i, j, k - 1, 8) +
216 fx(i, j - 1, k, 8) + fx(i, j - 1, k - 1, 8) +
217 tiny;
218 const amrex::Real avg_fy = fy(i, j, k, 8) + fy(i - 1, j, k, 8) +
219 fy(i, j, k - 1, 8) + fy(i - 1, j, k - 1, 8) +
220 tiny;
221 const amrex::Real avg_fz = fz(i, j, k, 8) + fz(i - 1, j, k, 8) +
222 fz(i, j - 1, k, 8) + fz(i - 1, j - 1, k, 8) +
223 tiny;
224
225 auto n_zeta = vs::Vector::one();
226 // Get components of normal in each position
227 n_zeta.x() =
228 ((vof(i, j, k) - vof(i - 1, j, k)) * fx(i, j, k, 8) +
229 (vof(i, j - 1, k) - vof(i - 1, j - 1, k)) * fx(i, j - 1, k, 8) +
230 (vof(i, j, k - 1) - vof(i - 1, j, k - 1)) * fx(i, j, k - 1, 8) +
231 (vof(i, j - 1, k - 1) - vof(i - 1, j - 1, k - 1)) *
232 fx(i, j - 1, k - 1, 8)) /
233 avg_fx;
234 n_zeta.y() =
235 ((vof(i, j, k) - vof(i, j - 1, k)) * fy(i, j, k, 8) +
236 (vof(i - 1, j, k) - vof(i - 1, j - 1, k)) * fy(i - 1, j, k, 8) +
237 (vof(i, j, k - 1) - vof(i, j - 1, k - 1)) * fy(i, j, k - 1, 8) +
238 (vof(i - 1, j, k - 1) - vof(i - 1, j - 1, k - 1)) *
239 fy(i - 1, j, k - 1, 8)) /
240 avg_fy;
241 n_zeta.z() =
242 ((vof(i, j, k) - vof(i, j, k - 1)) * fz(i, j, k, 8) +
243 (vof(i - 1, j, k) - vof(i - 1, j, k - 1)) * fz(i - 1, j, k, 8) +
244 (vof(i, j - 1, k) - vof(i, j - 1, k - 1)) * fz(i, j - 1, k, 8) +
245 (vof(i - 1, j - 1, k) - vof(i - 1, j - 1, k - 1)) *
246 fz(i - 1, j - 1, k, 8)) /
247 avg_fz;
248
249 n_zeta.normalize();
250
251 // To do outer product between vectors, set up tensors
252 auto n_tensor = vs::Tensor::identity();
253 auto n_tensor_T = vs::Tensor::identity();
254 n_tensor.rows(n_zeta, n_zeta, n_zeta);
255 n_tensor_T.cols(n_zeta, n_zeta, n_zeta);
256 // Multiply tensors elementwise
257 auto n_otimes_n = vs::Tensor::identity();
258 n_otimes_n.rows(
259 n_tensor.x() * n_tensor_T.x(), n_tensor.y() * n_tensor_T.y(),
260 n_tensor.z() * n_tensor_T.z());
261
262 return n_otimes_n;
263}
264
265} // namespace amr_wind::overset_ops
266
267#endif
Definition overset_ops_K.H:7
amrex::Real AMREX_GPU_DEVICE AMREX_FORCE_INLINE alpha_flux(const int i, const int j, const int k, const int dir, const amrex::Real margin, amrex::Array4< amrex::Real const > const &vof, amrex::Array4< amrex::Real const > const &tg_vof, amrex::Array4< amrex::Real const > const &normal)
Definition overset_ops_K.H:17
void AMREX_GPU_DEVICE AMREX_FORCE_INLINE velocity_face(const int i, const int j, const int k, const int dir, amrex::Array4< amrex::Real const > const &vof, amrex::Array4< amrex::Real const > const &velocity, amrex::Real &uface, amrex::Real &vface, amrex::Real &wface)
Definition overset_ops_K.H:64
vs::Tensor AMREX_GPU_DEVICE AMREX_FORCE_INLINE gp_flux_tensor(const int i, const int j, const int k, amrex::Array4< amrex::Real const > const &fx, amrex::Array4< amrex::Real const > const &fy, amrex::Array4< amrex::Real const > const &fz, const amrex::Real tiny)
Definition overset_ops_K.H:151
amrex::Real AMREX_GPU_DEVICE AMREX_FORCE_INLINE asdf(const amrex::Real a_vof, const amrex::Real i_th, const amrex::Real tiny)
Definition overset_ops_K.H:11
vs::Tensor AMREX_GPU_DEVICE AMREX_FORCE_INLINE normal_reinit_tensor(const int i, const int j, const int k, amrex::Array4< amrex::Real const > const &fx, amrex::Array4< amrex::Real const > const &fy, amrex::Array4< amrex::Real const > const &fz, amrex::Array4< amrex::Real const > const &vof, const amrex::Real tiny)
Definition overset_ops_K.H:204
void AMREX_GPU_DEVICE AMREX_FORCE_INLINE gp_rho_face(const int i, const int j, const int k, const int dir, amrex::Array4< amrex::Real const > const &vof, amrex::Array4< amrex::Real const > const &gp, amrex::Array4< amrex::Real const > const &rho, amrex::Real &uface, amrex::Real &vface, amrex::Real &wface)
Definition overset_ops_K.H:107
Definition tensor.H:14
AMREX_GPU_HOST_DEVICE static AMREX_FORCE_INLINE constexpr TensorT< T > identity() noexcept
Definition tensor.H:65
AMREX_GPU_HOST_DEVICE static AMREX_FORCE_INLINE constexpr VectorT< T > one()
Definition vector.H:50