/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>
39void add(
40 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>
67void add(
68 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>
87void 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>
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>
157void 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>
185void copy(
186 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>
205void 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>
235void 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>
261void 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>
291void 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>
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>
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>
382void lower_bound(FType& field, const amrex::Real min_value, const int icomp = 0)
383{
384 const auto& repo = field.repo();
385 const int nlevels = repo.num_active_levels();
386 for (int lev = 0; lev < nlevels; ++lev) {
387 const auto& farrs = field(lev).arrays();
388 amrex::ParallelFor(
389 field(lev), [=] AMREX_GPU_DEVICE(int nbx, int i, int j, int k) {
390 farrs[nbx](i, j, k, icomp) =
391 amrex::max(min_value, farrs[nbx](i, j, k, icomp));
392 });
393 }
394 amrex::Gpu::streamSynchronize();
395}
396
402template <typename FType>
403amrex::Real global_max_magnitude(FType& field)
404{
405 const auto& repo = field.repo();
406 const auto ncomp = field.num_comp();
407
408 amrex::Real maxglobal = 0.0_rt;
409 const int nlevels = repo.num_active_levels();
410 for (int lev = 0; lev < nlevels; ++lev) {
411 amrex::Real maxglobal_lev = 0.0_rt;
412 maxglobal_lev = amrex::ReduceMax(
413 field(lev), 0.,
414 [=] AMREX_GPU_HOST_DEVICE(
415 amrex::Box const& b,
416 amrex::Array4<amrex::Real const> const& field_arr)
417 -> amrex::Real {
418 amrex::Real mx = 0.0_rt;
419 amrex::Loop(b, [=, &mx](int i, int j, int k) {
420 amrex::Real mag = 0.0_rt;
421 for (int icomp = 0; icomp < ncomp; ++icomp) {
422 mag = mag + (field_arr(i, j, k, icomp) *
423 field_arr(i, j, k, icomp));
424 }
425 mx = amrex::max(std::sqrt(mag), mx);
426 });
427 return mx;
428 });
429 maxglobal = amrex::max(maxglobal, maxglobal_lev);
430 }
431
432 amrex::ParallelAllReduce::Max<amrex::Real>(
433 maxglobal, amrex::ParallelContext::CommunicatorSub());
434 return maxglobal;
435}
436
442template <typename FType>
443void normalize(FType& field)
444{
445 const amrex::Real eps =
446 std::numeric_limits<amrex::Real>::epsilon() * 1.0e4_rt;
447 const auto& repo = field.repo();
448 const auto ncomp = field.num_comp();
449
450 const int nlevels = repo.num_active_levels();
451 for (int lev = 0; lev < nlevels; ++lev) {
452 const auto& farrs = field(lev).arrays();
453 amrex::ParallelFor(
454 field(lev), [=] AMREX_GPU_DEVICE(int nbx, int i, int j, int k) {
455 auto farr = farrs[nbx];
456 // Compute magnitude
457 amrex::Real mag = 0.0_rt;
458 for (int icomp = 0; icomp < ncomp; ++icomp) {
459 mag = mag + (farr(i, j, k, icomp) * farr(i, j, k, icomp));
460 }
461 if (mag > eps) {
462 for (int icomp = 0; icomp < ncomp; ++icomp) {
463 farr(i, j, k, icomp) =
464 farr(i, j, k, icomp) / std::sqrt(mag);
465 }
466 }
467 });
468 }
469 amrex::Gpu::streamSynchronize();
470}
471
472} // namespace amr_wind::field_ops
473
474#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:443
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:39
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:382
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:403
Definition field_ops.H:23