/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
21
35template <typename T1, typename T2>
36inline void
37add(T1& dst,
38 const T2& src,
39 int srccomp,
40 int dstcomp,
41 int numcomp,
42 const amrex::IntVect& nghost)
43{
44 const int nlevels = dst.repo().num_active_levels();
45 for (int lev = 0; lev < nlevels; ++lev) {
46 amrex::MultiFab::Add(
47 dst(lev), src(lev), srccomp, dstcomp, numcomp, nghost);
48 }
49}
50
63template <typename T1, typename T2>
64inline void
65add(T1& dst, const T2& src, int srccomp, int dstcomp, int numcomp, int nghost)
66{
67 add(dst, src, srccomp, dstcomp, numcomp, amrex::IntVect(nghost));
68}
69
83template <typename T1, typename T2>
84inline void divide(
85 T1& dst,
86 const T2& src,
87 const int srccomp,
88 const int dstcomp,
89 const int ncomp_src,
90 const int ncomp_dst,
91 const amrex::IntVect& nghost)
92{
93 const int nlevels = dst.repo().num_active_levels();
94 for (int lev = 0; lev < nlevels; ++lev) {
95 if (ncomp_dst == ncomp_src) {
96 amrex::MultiFab::Divide(
97 dst(lev), src(lev), srccomp, dstcomp, ncomp_dst, nghost);
98 } else if (ncomp_src == 1) {
99 for (int n = 0; n < ncomp_dst; ++n) {
100 amrex::MultiFab::Divide(
101 dst(lev), src(lev), srccomp, dstcomp + n, ncomp_src,
102 nghost);
103 }
104 } else {
105 amrex::Abort(
106 "field_ops::divide : number of divisor components (ncomp_src) "
107 "must either be 1 or match number of dividend components "
108 "(ncomp_dst).");
109 }
110 }
111}
112
126template <typename T1, typename T2>
127inline void divide(
128 T1& dst,
129 const T2& src,
130 const int srccomp,
131 const int dstcomp,
132 const int ncomp_src,
133 const int ncomp_dst,
134 const int nghost)
135{
136 divide(
137 dst, src, srccomp, dstcomp, ncomp_src, ncomp_dst,
138 amrex::IntVect(nghost));
139}
140
153template <typename T1, typename T2>
154inline void copy(
155 T1& dst,
156 const T2& src,
157 const int srccomp,
158 const int dstcomp,
159 const int numcomp,
160 const amrex::IntVect& nghost)
161{
162 const int nlevels = dst.repo().num_active_levels();
163 for (int lev = 0; lev < nlevels; ++lev) {
164 amrex::MultiFab::Copy(
165 dst(lev), src(lev), srccomp, dstcomp, numcomp, nghost);
166 }
167}
168
181template <typename T1, typename T2>
182inline void
183copy(T1& dst, const T2& src, int srccomp, int dstcomp, int numcomp, int nghost)
184{
185 copy(dst, src, srccomp, dstcomp, numcomp, amrex::IntVect(nghost));
186}
187
201template <typename T1, typename T2>
202inline void saxpy(
203 T1& dst,
204 const amrex::Real a,
205 const T2& src,
206 const int srccomp,
207 const int dstcomp,
208 const int numcomp,
209 const amrex::IntVect& nghost)
210{
211 const int nlevels = dst.repo().num_active_levels();
212 for (int lev = 0; lev < nlevels; ++lev) {
213 amrex::MultiFab::Saxpy(
214 dst(lev), a, src(lev), srccomp, dstcomp, numcomp, nghost);
215 }
216}
217
231template <typename T1, typename T2>
232inline void saxpy(
233 T1& dst,
234 const amrex::Real a,
235 const T2& src,
236 const int srccomp,
237 const int dstcomp,
238 const int numcomp,
239 const int nghost)
240{
241 saxpy(dst, a, src, srccomp, dstcomp, numcomp, amrex::IntVect(nghost));
242}
243
257template <typename T1, typename T2>
258inline void xpay(
259 T1& dst,
260 const amrex::Real a,
261 const T2& src,
262 const int srccomp,
263 const int dstcomp,
264 const int numcomp,
265 const amrex::IntVect& nghost)
266{
267 const int nlevels = dst.repo().num_active_levels();
268 for (int lev = 0; lev < nlevels; ++lev) {
269 amrex::MultiFab::Xpay(
270 dst(lev), a, src(lev), srccomp, dstcomp, numcomp, nghost);
271 }
272}
273
287template <typename T1, typename T2>
288inline void xpay(
289 T1& dst,
290 const amrex::Real a,
291 const T2& src,
292 const int srccomp,
293 const int dstcomp,
294 const int numcomp,
295 const int nghost)
296{
297 xpay(dst, a, src, srccomp, dstcomp, numcomp, amrex::IntVect(nghost));
298}
299
316template <typename T1, typename T2, typename T3>
317inline void lincomb(
318 T1& dst,
319 const amrex::Real a,
320 const T2& x,
321 const int xcomp,
322 const amrex::Real b,
323 const T3& y,
324 const int ycomp,
325 const int dstcomp,
326 const int numcomp,
327 const amrex::IntVect& nghost)
328{
329 const int nlevels = dst.repo().num_active_levels();
330 for (int lev = 0; lev < nlevels; ++lev) {
331 amrex::MultiFab::LinComb(
332 dst(lev), a, x(lev), xcomp, b, y(lev), ycomp, dstcomp, numcomp,
333 nghost);
334 }
335}
336
353template <typename T1, typename T2, typename T3>
354inline void lincomb(
355 T1& dst,
356 const amrex::Real a,
357 const T2& x,
358 const int xcomp,
359 const amrex::Real b,
360 const T3& y,
361 const int ycomp,
362 const int dstcomp,
363 const int numcomp,
364 const int nghost)
365{
366 lincomb(
367 dst, a, x, xcomp, b, y, ycomp, dstcomp, numcomp,
368 amrex::IntVect(nghost));
369}
370
378template <typename FType>
379inline void
380lower_bound(FType& field, const amrex::Real min_value, const int icomp = 0)
381{
382 const auto& repo = field.repo();
383 const int nlevels = repo.num_active_levels();
384 for (int lev = 0; lev < nlevels; ++lev) {
385 const auto& farrs = field(lev).arrays();
386 amrex::ParallelFor(
387 field(lev),
388 [=] AMREX_GPU_DEVICE(int nbx, int i, int j, int k) noexcept {
389 farrs[nbx](i, j, k, icomp) =
390 amrex::max(min_value, farrs[nbx](i, j, k, icomp));
391 });
392 }
393 amrex::Gpu::synchronize();
394}
395
401template <typename FType>
402inline amrex::Real global_max_magnitude(FType& field)
403{
404 const auto& repo = field.repo();
405 const auto ncomp = field.num_comp();
406
407 amrex::Real maxglobal = 0.0;
408 const int nlevels = repo.num_active_levels();
409 for (int lev = 0; lev < nlevels; ++lev) {
410 amrex::Real maxglobal_lev = 0.0;
411 maxglobal_lev = amrex::ReduceMax(
412 field(lev), 0.,
413 [=] AMREX_GPU_HOST_DEVICE(
414 amrex::Box const& b,
415 amrex::Array4<amrex::Real const> const& field_arr)
416 -> amrex::Real {
417 amrex::Real mx = 0.0;
418 amrex::Loop(b, [=, &mx](int i, int j, int k) noexcept {
419 amrex::Real mag = 0.0;
420 for (int icomp = 0; icomp < ncomp; ++icomp) {
421 mag = mag + field_arr(i, j, k, icomp) *
422 field_arr(i, j, k, icomp);
423 }
424 mx = amrex::max(std::sqrt(mag), mx);
425 });
426 return mx;
427 });
428 maxglobal = amrex::max(maxglobal, maxglobal_lev);
429 }
430
431 amrex::ParallelAllReduce::Max<amrex::Real>(
432 maxglobal, amrex::ParallelContext::CommunicatorSub());
433 return maxglobal;
434}
435
441template <typename FType>
442inline void normalize(FType& field)
443{
444 const amrex::Real eps = 1.0e-12;
445 const auto& repo = field.repo();
446 const auto ncomp = field.num_comp();
447
448 const int nlevels = repo.num_active_levels();
449 for (int lev = 0; lev < nlevels; ++lev) {
450 const auto& farrs = field(lev).arrays();
451 amrex::ParallelFor(
452 field(lev),
453 [=] AMREX_GPU_DEVICE(int nbx, int i, int j, int k) noexcept {
454 auto farr = farrs[nbx];
455 // Compute magnitude
456 amrex::Real mag = 0.;
457 for (int icomp = 0; icomp < ncomp; ++icomp) {
458 mag = mag + farr(i, j, k, icomp) * farr(i, j, k, icomp);
459 }
460 if (mag > eps) {
461 for (int icomp = 0; icomp < ncomp; ++icomp) {
462 farr(i, j, k, icomp) =
463 farr(i, j, k, icomp) / std::sqrt(mag);
464 }
465 }
466 });
467 }
468 amrex::Gpu::synchronize();
469}
470
471} // namespace amr_wind::field_ops
472
473#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:84
void normalize(FType &field)
Definition field_ops.H:442
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:202
void add(T1 &dst, const T2 &src, int srccomp, int dstcomp, int numcomp, const amrex::IntVect &nghost)
Definition field_ops.H:37
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:258
void copy(T1 &dst, const T2 &src, const int srccomp, const int dstcomp, const int numcomp, const amrex::IntVect &nghost)
Definition field_ops.H:154
void lower_bound(FType &field, const amrex::Real min_value, const int icomp=0)
Definition field_ops.H:380
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:317
amrex::Real global_max_magnitude(FType &field)
Definition field_ops.H:402
Definition field_ops.H:20