/home/runner/work/amr-wind/amr-wind/amr-wind/core/field_ops.H Source File

AMR-Wind API: /home/runner/work/amr-wind/amr-wind/amr-wind/core/field_ops.H Source File
AMR-Wind API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
field_ops.H
Go to the documentation of this file.
1#ifndef FIELD_OPS_H
2#define FIELD_OPS_H
3
5#include "AMReX_MultiFab.H"
6#include "AMReX_REAL.H"
7
8using namespace amrex::literals;
9
22
24
38template <typename T1, typename T2>
39inline void
40add(T1& dst,
41 const T2& src,
42 int srccomp,
43 int dstcomp,
44 int numcomp,
45 const amrex::IntVect& nghost)
46{
47 const int nlevels = dst.repo().num_active_levels();
48 for (int lev = 0; lev < nlevels; ++lev) {
49 amrex::MultiFab::Add(
50 dst(lev), src(lev), srccomp, dstcomp, numcomp, nghost);
51 }
52}
53
66template <typename T1, typename T2>
67inline void
68add(T1& dst, const T2& src, int srccomp, int dstcomp, int numcomp, int nghost)
69{
70 add(dst, src, srccomp, dstcomp, numcomp, amrex::IntVect(nghost));
71}
72
86template <typename T1, typename T2>
87inline void divide(
88 T1& dst,
89 const T2& src,
90 const int srccomp,
91 const int dstcomp,
92 const int ncomp_src,
93 const int ncomp_dst,
94 const amrex::IntVect& nghost)
95{
96 const int nlevels = dst.repo().num_active_levels();
97 for (int lev = 0; lev < nlevels; ++lev) {
98 if (ncomp_dst == ncomp_src) {
99 amrex::MultiFab::Divide(
100 dst(lev), src(lev), srccomp, dstcomp, ncomp_dst, nghost);
101 } else if (ncomp_src == 1) {
102 for (int n = 0; n < ncomp_dst; ++n) {
103 amrex::MultiFab::Divide(
104 dst(lev), src(lev), srccomp, dstcomp + n, ncomp_src,
105 nghost);
106 }
107 } else {
108 amrex::Abort(
109 "field_ops::divide : number of divisor components (ncomp_src) "
110 "must either be 1 or match number of dividend components "
111 "(ncomp_dst).");
112 }
113 }
114}
115
129template <typename T1, typename T2>
130inline void divide(
131 T1& dst,
132 const T2& src,
133 const int srccomp,
134 const int dstcomp,
135 const int ncomp_src,
136 const int ncomp_dst,
137 const int nghost)
138{
139 divide(
140 dst, src, srccomp, dstcomp, ncomp_src, ncomp_dst,
141 amrex::IntVect(nghost));
142}
143
156template <typename T1, typename T2>
157inline void copy(
158 T1& dst,
159 const T2& src,
160 const int srccomp,
161 const int dstcomp,
162 const int numcomp,
163 const amrex::IntVect& nghost)
164{
165 const int nlevels = dst.repo().num_active_levels();
166 for (int lev = 0; lev < nlevels; ++lev) {
167 amrex::MultiFab::Copy(
168 dst(lev), src(lev), srccomp, dstcomp, numcomp, nghost);
169 }
170}
171
184template <typename T1, typename T2>
185inline void
186copy(T1& dst, const T2& src, int srccomp, int dstcomp, int numcomp, int nghost)
187{
188 copy(dst, src, srccomp, dstcomp, numcomp, amrex::IntVect(nghost));
189}
190
204template <typename T1, typename T2>
205inline void saxpy(
206 T1& dst,
207 const amrex::Real a,
208 const T2& src,
209 const int srccomp,
210 const int dstcomp,
211 const int numcomp,
212 const amrex::IntVect& nghost)
213{
214 const int nlevels = dst.repo().num_active_levels();
215 for (int lev = 0; lev < nlevels; ++lev) {
216 amrex::MultiFab::Saxpy(
217 dst(lev), a, src(lev), srccomp, dstcomp, numcomp, nghost);
218 }
219}
220
234template <typename T1, typename T2>
235inline void saxpy(
236 T1& dst,
237 const amrex::Real a,
238 const T2& src,
239 const int srccomp,
240 const int dstcomp,
241 const int numcomp,
242 const int nghost)
243{
244 saxpy(dst, a, src, srccomp, dstcomp, numcomp, amrex::IntVect(nghost));
245}
246
260template <typename T1, typename T2>
261inline void xpay(
262 T1& dst,
263 const amrex::Real a,
264 const T2& src,
265 const int srccomp,
266 const int dstcomp,
267 const int numcomp,
268 const amrex::IntVect& nghost)
269{
270 const int nlevels = dst.repo().num_active_levels();
271 for (int lev = 0; lev < nlevels; ++lev) {
272 amrex::MultiFab::Xpay(
273 dst(lev), a, src(lev), srccomp, dstcomp, numcomp, nghost);
274 }
275}
276
290template <typename T1, typename T2>
291inline void xpay(
292 T1& dst,
293 const amrex::Real a,
294 const T2& src,
295 const int srccomp,
296 const int dstcomp,
297 const int numcomp,
298 const int nghost)
299{
300 xpay(dst, a, src, srccomp, dstcomp, numcomp, amrex::IntVect(nghost));
301}
302
319template <typename T1, typename T2, typename T3>
320inline void lincomb(
321 T1& dst,
322 const amrex::Real a,
323 const T2& x,
324 const int xcomp,
325 const amrex::Real b,
326 const T3& y,
327 const int ycomp,
328 const int dstcomp,
329 const int numcomp,
330 const amrex::IntVect& nghost)
331{
332 const int nlevels = dst.repo().num_active_levels();
333 for (int lev = 0; lev < nlevels; ++lev) {
334 amrex::MultiFab::LinComb(
335 dst(lev), a, x(lev), xcomp, b, y(lev), ycomp, dstcomp, numcomp,
336 nghost);
337 }
338}
339
356template <typename T1, typename T2, typename T3>
357inline void lincomb(
358 T1& dst,
359 const amrex::Real a,
360 const T2& x,
361 const int xcomp,
362 const amrex::Real b,
363 const T3& y,
364 const int ycomp,
365 const int dstcomp,
366 const int numcomp,
367 const int nghost)
368{
369 lincomb(
370 dst, a, x, xcomp, b, y, ycomp, dstcomp, numcomp,
371 amrex::IntVect(nghost));
372}
373
381template <typename FType>
382inline void
383lower_bound(FType& field, const amrex::Real min_value, const int icomp = 0)
384{
385 const auto& repo = field.repo();
386 const int nlevels = repo.num_active_levels();
387 for (int lev = 0; lev < nlevels; ++lev) {
388 const auto& farrs = field(lev).arrays();
389 amrex::ParallelFor(
390 field(lev),
391 [=] AMREX_GPU_DEVICE(int nbx, int i, int j, int k) noexcept {
392 farrs[nbx](i, j, k, icomp) =
393 amrex::max(min_value, farrs[nbx](i, j, k, icomp));
394 });
395 }
396 amrex::Gpu::streamSynchronize();
397}
398
404template <typename FType>
405inline amrex::Real global_max_magnitude(FType& field)
406{
407 const auto& repo = field.repo();
408 const auto ncomp = field.num_comp();
409
410 amrex::Real maxglobal = 0.0_rt;
411 const int nlevels = repo.num_active_levels();
412 for (int lev = 0; lev < nlevels; ++lev) {
413 amrex::Real maxglobal_lev = 0.0_rt;
414 maxglobal_lev = amrex::ReduceMax(
415 field(lev), 0.,
416 [=] AMREX_GPU_HOST_DEVICE(
417 amrex::Box const& b,
418 amrex::Array4<amrex::Real const> const& field_arr)
419 -> amrex::Real {
420 amrex::Real mx = 0.0_rt;
421 amrex::Loop(b, [=, &mx](int i, int j, int k) noexcept {
422 amrex::Real mag = 0.0_rt;
423 for (int icomp = 0; icomp < ncomp; ++icomp) {
424 mag = mag + field_arr(i, j, k, icomp) *
425 field_arr(i, j, k, icomp);
426 }
427 mx = amrex::max(std::sqrt(mag), mx);
428 });
429 return mx;
430 });
431 maxglobal = amrex::max(maxglobal, maxglobal_lev);
432 }
433
434 amrex::ParallelAllReduce::Max<amrex::Real>(
435 maxglobal, amrex::ParallelContext::CommunicatorSub());
436 return maxglobal;
437}
438
444template <typename FType>
445inline void normalize(FType& field)
446{
447 const amrex::Real eps =
448 std::numeric_limits<amrex::Real>::epsilon() * 1.0e4_rt;
449 const auto& repo = field.repo();
450 const auto ncomp = field.num_comp();
451
452 const int nlevels = repo.num_active_levels();
453 for (int lev = 0; lev < nlevels; ++lev) {
454 const auto& farrs = field(lev).arrays();
455 amrex::ParallelFor(
456 field(lev),
457 [=] AMREX_GPU_DEVICE(int nbx, int i, int j, int k) noexcept {
458 auto farr = farrs[nbx];
459 // Compute magnitude
460 amrex::Real mag = 0.0_rt;
461 for (int icomp = 0; icomp < ncomp; ++icomp) {
462 mag = mag + farr(i, j, k, icomp) * farr(i, j, k, icomp);
463 }
464 if (mag > eps) {
465 for (int icomp = 0; icomp < ncomp; ++icomp) {
466 farr(i, j, k, icomp) =
467 farr(i, j, k, icomp) / std::sqrt(mag);
468 }
469 }
470 });
471 }
472 amrex::Gpu::streamSynchronize();
473}
474
475} // namespace amr_wind::field_ops
476
477#endif /* FIELD_OPS_H */
void divide(T1 &dst, const T2 &src, const int srccomp, const int dstcomp, const int ncomp_src, const int ncomp_dst, const amrex::IntVect &nghost)
Definition field_ops.H:87
void normalize(FType &field)
Definition field_ops.H:445
void saxpy(T1 &dst, const amrex::Real a, const T2 &src, const int srccomp, const int dstcomp, const int numcomp, const amrex::IntVect &nghost)
Definition field_ops.H:205
void add(T1 &dst, const T2 &src, int srccomp, int dstcomp, int numcomp, const amrex::IntVect &nghost)
Definition field_ops.H:40
void xpay(T1 &dst, const amrex::Real a, const T2 &src, const int srccomp, const int dstcomp, const int numcomp, const amrex::IntVect &nghost)
Definition field_ops.H:261
void copy(T1 &dst, const T2 &src, const int srccomp, const int dstcomp, const int numcomp, const amrex::IntVect &nghost)
Definition field_ops.H:157
void lower_bound(FType &field, const amrex::Real min_value, const int icomp=0)
Definition field_ops.H:383
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
amrex::Real global_max_magnitude(FType &field)
Definition field_ops.H:405
Definition field_ops.H:23