WarpX
Loading...
Searching...
No Matches
MultiFabRegister.H
Go to the documentation of this file.
1/* Copyright 2024 The ABLASTR Community
2 *
3 * This file is part of ABLASTR.
4 *
5 * License: BSD-3-Clause-LBNL
6 * Authors: Axel Huebl
7 */
8#ifndef ABLASTR_FIELDS_MF_REGISTER_H
9#define ABLASTR_FIELDS_MF_REGISTER_H
10
11#include <AMReX_BaseFwd.H>
12#include <AMReX_Enum.H>
13#include <AMReX_Extension.H>
14#include <AMReX_IntVect.H>
15#include <AMReX_MultiFab.H>
16#include <AMReX_REAL.H>
17#include <AMReX_Vector.H>
18
19#include <array>
20#include <map>
21#include <memory>
22#include <optional>
23#include <stdexcept>
24#include <string>
25#include <type_traits>
26#include <utility>
27#include <vector>
28
29
30namespace
31{
32 // type trait helpers in lieu of an amrex::is_amrex_enum
33 template <typename, typename = std::void_t<>>
34 struct is_castable_to_string : std::false_type {};
35
36 template <typename T>
37 struct is_castable_to_string<T, std::void_t<decltype(static_cast<std::string>(std::declval<T>()))>> : std::true_type {};
38
40 template<typename T>
41 std::string getExtractedName (T name)
42 {
43 if constexpr(is_castable_to_string<T>())
44 {
45 // already a unique string key
46 return std::string(name);
47 } else
48 {
49 // user-defined AMREX_ENUM or compile error
50 return amrex::getEnumNameString(name);
51 }
52 }
53}
54
55namespace ablastr::fields
56{
71 {
72 int dir = 0;
73
74 public:
75 constexpr explicit Direction (int d) : dir(d) {}
76
77#if defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER) || defined(WARPX_DIM_RSPHERE)
78 static const Direction r;
79 static const Direction theta;
80
81 inline static const std::string r_string = "r";
82 inline static const std::string theta_string = "theta";
83#endif
84#if defined(WARPX_DIM_RSPHERE)
85 static const Direction phi;
86
87 inline static const std::string phi_string = "phi";
88#endif
89#if defined(WARPX_DIM_3D) || defined(WARPX_DIM_XZ) || defined(WARPX_DIM_1D_Z)
90 static const Direction x;
91 static const Direction y;
92
93 inline static const std::string x_string = "x";
94 inline static const std::string y_string = "y";
95#endif
96#if !defined(WARPX_DIM_RSPHERE)
97 static const Direction z;
98
99 inline static const std::string z_string = "z";
100#endif
101
102 bool operator<(const Direction& other) const
103 {
104 return other.dir < this->dir;
105 }
106
107 operator std::string() const // NOLINT(google-explicit-constructor)
108 {
109#if defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER) || defined(WARPX_DIM_RSPHERE)
110 if (dir == r) { return r_string; }
111 if (dir == theta) { return theta_string; }
112#endif
113#if defined(WARPX_DIM_RSPHERE)
114 if (dir == phi) { return phi_string; }
115#endif
116#if defined(WARPX_DIM_3D) || defined(WARPX_DIM_XZ) || defined(WARPX_DIM_1D_Z)
117 if (dir == x) { return x_string; }
118 if (dir == y) { return y_string; }
119#endif
120#if !defined(WARPX_DIM_RSPHERE)
121 if (dir == z) { return z_string; }
122#endif
123 throw std::runtime_error("invalid direction: " + std::to_string(dir));
124 return std::to_string(dir);
125 }
126
127 Direction (std::string const & s) : // NOLINT(google-explicit-constructor)
128 dir{-1}
129 {
130#if defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER) || defined(WARPX_DIM_RSPHERE)
131 if (s == r_string) { dir = r; }
132 if (s == theta_string) { dir = theta; }
133#endif
134#if defined(WARPX_DIM_RSPHERE)
135 if (s == phi_string) { dir = phi; }
136#endif
137#if defined(WARPX_DIM_3D) || defined(WARPX_DIM_XZ) || defined(WARPX_DIM_1D_Z)
138 if (s == x_string) { dir = x; }
139 if (s == y_string) { dir = y; }
140#endif
141#if !defined(WARPX_DIM_RSPHERE)
142 if (s == z_string) { dir = z; }
143#endif
144
145 if (dir == -1) {
146 throw std::runtime_error("invalid direction: " + s);
147 }
148 }
149
150 // e.g., "x"
151 Direction (char const * c) : dir{Direction{c}} {} // NOLINT(google-explicit-constructor)
152
153 // e.g., 'x'
154 Direction (char const c) : dir{Direction{c}} {} // NOLINT(google-explicit-constructor)
155
156 // rule of five: define default constructors and the destructor
157 // because we defined a special one above for char
158 ~Direction () = default;
159 Direction (const Direction&) = default;
160 Direction& operator= (const Direction&) = default;
161 Direction (Direction&&) = default;
163
164 /* TODO: just temporary int compatibility */
165 operator int() const { return dir; } // NOLINT(google-explicit-constructor)
166
167 };
168
169#if defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER) || defined(WARPX_DIM_RSPHERE)
170 inline constexpr Direction Direction::r = Direction{0};
171 inline constexpr Direction Direction::theta = Direction{1};
172#endif
173#if defined(WARPX_DIM_RSPHERE)
174 inline constexpr Direction Direction::phi = Direction{2};
175#endif
176
177#if defined(WARPX_DIM_3D) || defined(WARPX_DIM_XZ) || defined(WARPX_DIM_1D_Z)
178 inline constexpr Direction Direction::x = Direction{0};
179 inline constexpr Direction Direction::y = Direction{1};
180#endif
181
182#if defined(WARPX_DIM_3D) || defined(WARPX_DIM_XZ) || defined(WARPX_DIM_1D_Z) || defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER)
183 inline constexpr Direction Direction::z = Direction{2};
184#endif
185
191
197
200 //using VectorField = ablastr::utils::ConstMap<Direction, amrex::MultiFab *>;
201 using VectorField = std::array<amrex::MultiFab *, 3>;
202
205 //using VectorField = ablastr::utils::ConstMap<Direction, amrex::MultiFab const *>;
206 using ConstVectorField = std::array<amrex::MultiFab const *, 3>;
207
211
215
219
223
231 {
232 // TODO: also add iMultiFab via std::variant
233
236
238 std::optional<Direction> m_dir = std::nullopt;
239
241 int m_level = 0;
242
244 bool m_remake = true;
245
248
250 std::string m_owner;
251
254 bool
255 is_vector () const { return m_dir.has_value(); }
256
262 bool
263 is_alias () const { return !m_owner.empty(); }
264 };
265
272 {
273 // Avoid accidental copies when passing to member functions
274 MultiFabRegister() = default;
279 ~MultiFabRegister() = default;
280
297 template<typename T>
300 T name,
301 int level,
302 amrex::BoxArray const & ba,
304 int ncomp,
305 amrex::IntVect const & ngrow,
306 std::optional<amrex::Real const> initial_value = std::nullopt,
307 bool remake = true,
308 bool redistribute_on_remake = true
309 )
310 {
311 return internal_alloc_init(
312 getExtractedName(name),
313 level,
314 ba,
315 dm,
316 ncomp,
317 ngrow,
318 initial_value,
319 remake,
320 redistribute_on_remake
321 );
322 }
323
341 template<typename T>
344 T name,
345 Direction dir,
346 int level,
347 amrex::BoxArray const & ba,
349 int ncomp,
350 amrex::IntVect const & ngrow,
351 std::optional<amrex::Real const> initial_value = std::nullopt,
352 bool remake = true,
353 bool redistribute_on_remake = true
354 )
355 {
356 return internal_alloc_init(
357 getExtractedName(name),
358 dir,
359 level,
360 ba,
361 dm,
362 ncomp,
363 ngrow,
364 initial_value,
365 remake,
366 redistribute_on_remake
367 );
368 }
369
381 template<typename N, typename A>
384 N new_name,
385 A alias_name,
386 int level,
387 std::optional<amrex::Real const> initial_value = std::nullopt
388 )
389 {
390 return internal_alias_init(
391 getExtractedName(new_name),
392 getExtractedName(alias_name),
393 level,
394 initial_value
395 );
396 }
397
410 template<typename N, typename A>
413 N new_name,
414 A alias_name,
415 Direction dir,
416 int level,
417 std::optional<amrex::Real const> initial_value = std::nullopt
418 )
419 {
420 return internal_alias_init(
421 getExtractedName(new_name),
422 getExtractedName(alias_name),
423 dir,
424 level,
425 initial_value
426 );
427 }
428
435 template<typename T>
436 [[nodiscard]] bool
438 T name,
439 int level
440 ) const
441 {
442 return internal_has(
443 getExtractedName(name),
444 level
445 );
446 }
447
455 template<typename T>
456 [[nodiscard]] bool
458 T name,
459 Direction dir,
460 int level
461 ) const
462 {
463 return internal_has(
464 getExtractedName(name),
465 dir,
466 level
467 );
468 }
469
476 template<typename T>
477 [[nodiscard]] bool
479 T name,
480 int level
481 ) const
482 {
483 return internal_has_vector(
484 getExtractedName(name),
485 level
486 );
487 }
488
497 template<typename T>
498 [[nodiscard]] amrex::MultiFab*
500 T name,
501 int level
502 )
503 {
504 return internal_get(
505 getExtractedName(name),
506 level
507 );
508 }
509
519 template<typename T>
520 [[nodiscard]] amrex::MultiFab*
522 T name,
523 Direction dir,
524 int level
525 )
526 {
527 return internal_get(
528 getExtractedName(name),
529 dir,
530 level
531 );
532 }
533
542 template<typename T>
543 [[nodiscard]] amrex::MultiFab const *
545 T name,
546 int level
547 ) const
548 {
549 return internal_get(
550 getExtractedName(name),
551 level
552 );
553 }
554
564 template<typename T>
565 [[nodiscard]] amrex::MultiFab const *
567 T name,
568 Direction dir,
569 int level
570 ) const
571 {
572 return internal_get(
573 getExtractedName(name),
574 dir,
575 level
576 );
577 }
578
589 template<typename T>
590 [[nodiscard]] MultiLevelScalarField
592 T name,
593 int finest_level,
594 bool skip_level_0=false
595 )
596 {
598 getExtractedName(name),
599 finest_level,
600 skip_level_0
601 );
602 }
603 template<typename T>
604 [[nodiscard]] ConstMultiLevelScalarField
606 T name,
607 int finest_level,
608 bool skip_level_0=false
609 ) const
610 {
612 getExtractedName(name),
613 finest_level,
614 skip_level_0
615 );
616 }
617
618
628 template<typename T>
629 [[nodiscard]] VectorField
631 T name,
632 int level
633 )
634 {
636 getExtractedName(name),
637 level
638 );
639 }
640 template<typename T>
641 [[nodiscard]] ConstVectorField
643 T name,
644 int level
645 ) const
646 {
648 getExtractedName(name),
649 level
650 );
651 }
652
653
665 template<typename T>
666 [[nodiscard]] MultiLevelVectorField
668 T name,
669 int finest_level,
670 bool skip_level_0=false
671 )
672 {
674 getExtractedName(name),
675 finest_level,
676 skip_level_0
677 );
678 }
679 template<typename T>
680 [[nodiscard]] ConstMultiLevelVectorField
682 T name,
683 int finest_level,
684 bool skip_level_0=false
685 ) const
686 {
688 getExtractedName(name),
689 finest_level,
690 skip_level_0
691 );
692 }
693
694
699 [[nodiscard]] std::vector<std::string>
700 list () const;
701
707 template<typename T>
708 void
710 T name,
711 int level
712 )
713 {
714 internal_erase(getExtractedName(name), level);
715 }
716
723 template<typename T>
724 void
726 T name,
727 Direction dir,
728 int level
729 )
730 {
731 internal_erase(getExtractedName(name), dir, level);
732 }
733
740 void
742 int level
743 );
744
752 void
754 int other_level,
755 amrex::DistributionMapping const & new_dm
756 );
757
764 [[nodiscard]] std::string
765 mf_name (
766 std::string name,
767 int level
768 ) const;
769
777 [[nodiscard]] std::string
778 mf_name (
779 std::string name,
780 Direction dir,
781 int level
782 ) const;
783
785 [[nodiscard]] bool
787 std::string const & internal_name
788 );
789 [[nodiscard]] amrex::MultiFab *
791 std::string const & internal_name
792 );
793
794 private:
795
796 [[nodiscard]] amrex::MultiFab const *
798 std::string const & internal_name
799 ) const;
800
803 std::string const & name,
804 int level,
805 amrex::BoxArray const & ba,
807 int ncomp,
808 amrex::IntVect const & ngrow,
809 std::optional<amrex::Real const> initial_value = std::nullopt,
810 bool remake = true,
811 bool redistribute_on_remake = true
812 );
815 std::string const & name,
816 Direction dir,
817 int level,
818 amrex::BoxArray const & ba,
820 int ncomp,
821 amrex::IntVect const & ngrow,
822 std::optional<amrex::Real const> initial_value = std::nullopt,
823 bool remake = true,
824 bool redistribute_on_remake = true
825 );
826
829 std::string const & new_name,
830 std::string const & alias_name,
831 int level,
832 std::optional<amrex::Real const> initial_value = std::nullopt
833 );
836 std::string const & new_name,
837 std::string const & alias_name,
838 Direction dir,
839 int level,
840 std::optional<amrex::Real const> initial_value = std::nullopt
841 );
842
843 [[nodiscard]] bool
845 std::string const & name,
846 int level
847 ) const;
848 [[nodiscard]] bool
850 std::string const & name,
851 Direction dir,
852 int level
853 ) const;
854 [[nodiscard]] bool
856 std::string const & name,
857 int level
858 ) const;
859
860 [[nodiscard]] amrex::MultiFab *
862 std::string const & name,
863 int level
864 );
865 [[nodiscard]] amrex::MultiFab const *
867 std::string const & name,
868 int level
869 ) const;
870 [[nodiscard]] amrex::MultiFab *
872 std::string const & name,
873 Direction dir,
874 int level
875 );
876 [[nodiscard]] amrex::MultiFab const *
878 std::string const & name,
879 Direction dir,
880 int level
881 ) const;
882 [[nodiscard]] MultiLevelScalarField
884 std::string const & name,
885 int finest_level,
886 bool skip_level_0
887 );
888 [[nodiscard]] ConstMultiLevelScalarField
890 std::string const & name,
891 int finest_level,
892 bool skip_level_0
893 ) const;
894 [[nodiscard]] VectorField
896 std::string const & name,
897 int level
898 );
899 [[nodiscard]] ConstVectorField
901 std::string const & name,
902 int level
903 ) const;
904 [[nodiscard]] MultiLevelVectorField
906 std::string const & name,
907 int finest_level,
908 bool skip_level_0
909 );
910 [[nodiscard]] ConstMultiLevelVectorField
912 std::string const & name,
913 int finest_level,
914 bool skip_level_0
915 ) const;
916
917 void
919 std::string const & name,
920 int level
921 );
922 void
924 std::string const & name,
925 Direction dir,
926 int level
927 );
928
930 std::map<
931 std::string,
934
935 public:
944 static inline std::vector<Direction> m_all_dirs =
945#if defined(WARPX_DIM_3D) || defined(WARPX_DIM_XZ) || defined(WARPX_DIM_1D_Z)
947#elif defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER)
949#elif defined(WARPX_DIM_RSPHERE)
950 {Direction::r, Direction::theta, Direction::phi};
951#endif
952 };
953
959 a2m (
960 std::array< std::unique_ptr<amrex::MultiFab>, 3 > const & old_vectorfield
961 );
962
963} // namespace ablastr::fields
964
965#endif // ABLASTR_FIELDS_MF_REGISTER_H
#define AMREX_INLINE
Definition MultiFabRegister.H:71
static const Direction r
Definition MultiFabRegister.H:170
static const Direction z
Definition MultiFabRegister.H:183
static const Direction y
Definition MultiFabRegister.H:179
constexpr Direction(int d)
Definition MultiFabRegister.H:75
static const Direction x
Definition MultiFabRegister.H:178
static const Direction theta
Definition MultiFabRegister.H:171
Definition MultiFabRegister.H:71
static const Direction r
Definition MultiFabRegister.H:78
int dir
Definition MultiFabRegister.H:72
static const std::string z_string
Definition MultiFabRegister.H:99
Direction(Direction &&)=default
static const Direction z
Definition MultiFabRegister.H:97
Direction & operator=(const Direction &)=default
static const std::string y_string
Definition MultiFabRegister.H:94
Direction(std::string const &s)
Definition MultiFabRegister.H:127
static const Direction y
Definition MultiFabRegister.H:91
constexpr Direction(int d)
Definition MultiFabRegister.H:75
static const std::string r_string
Definition MultiFabRegister.H:81
static const Direction x
Definition MultiFabRegister.H:90
Direction(char const c)
Definition MultiFabRegister.H:154
bool operator<(const Direction &other) const
Definition MultiFabRegister.H:102
static const std::string x_string
Definition MultiFabRegister.H:93
static const std::string theta_string
Definition MultiFabRegister.H:82
Direction(char const *c)
Definition MultiFabRegister.H:151
Direction(const Direction &)=default
static const Direction theta
Definition MultiFabRegister.H:79
Definition EffectivePotentialPoissonSolver.H:63
VectorField a2m(std::array< std::unique_ptr< amrex::MultiFab >, 3 > const &old_vectorfield)
Definition MultiFabRegister.cpp:645
amrex::Vector< ConstVectorField > ConstMultiLevelVectorField
Definition MultiFabRegister.H:222
std::array< amrex::MultiFab const *, 3 > ConstVectorField
Definition MultiFabRegister.H:206
std::array< amrex::MultiFab *, 3 > VectorField
Definition MultiFabRegister.H:201
amrex::Vector< ScalarField > MultiLevelScalarField
Definition MultiFabRegister.H:210
amrex::MultiFab * ScalarField
Definition MultiFabRegister.H:190
amrex::Vector< ConstScalarField > ConstMultiLevelScalarField
Definition MultiFabRegister.H:214
amrex::MultiFab const * ConstScalarField
Definition MultiFabRegister.H:196
amrex::Vector< VectorField > MultiLevelVectorField
Definition MultiFabRegister.H:218
std::string getEnumNameString(T const &v)
IntVectND< 3 > IntVect
Definition MultiFabRegister.H:231
amrex::MultiFab m_mf
Definition MultiFabRegister.H:235
AMREX_INLINE bool is_alias() const
Definition MultiFabRegister.H:263
int m_level
Definition MultiFabRegister.H:241
std::optional< Direction > m_dir
Definition MultiFabRegister.H:238
AMREX_INLINE bool is_vector() const
Definition MultiFabRegister.H:255
bool m_redistribute_on_remake
Definition MultiFabRegister.H:247
std::string m_owner
Definition MultiFabRegister.H:250
bool m_remake
Definition MultiFabRegister.H:244
amrex::MultiFab * alias_init(N new_name, A alias_name, int level, std::optional< amrex::Real const > initial_value=std::nullopt)
Definition MultiFabRegister.H:383
bool internal_has(std::string const &internal_name)
Definition MultiFabRegister.cpp:342
ConstMultiLevelScalarField get_mr_levels(T name, int finest_level, bool skip_level_0=false) const
Definition MultiFabRegister.H:605
MultiFabRegister & operator=(MultiFabRegister &&)=delete
MultiLevelScalarField get_mr_levels(T name, int finest_level, bool skip_level_0=false)
Definition MultiFabRegister.H:591
amrex::MultiFab const * get(T name, Direction dir, int level) const
Definition MultiFabRegister.H:566
amrex::MultiFab * alloc_init(T name, int level, amrex::BoxArray const &ba, amrex::DistributionMapping const &dm, int ncomp, amrex::IntVect const &ngrow, std::optional< amrex::Real const > initial_value=std::nullopt, bool remake=true, bool redistribute_on_remake=true)
Definition MultiFabRegister.H:299
std::vector< std::string > list() const
Definition MultiFabRegister.cpp:560
std::string mf_name(std::string name, int level) const
Definition MultiFabRegister.cpp:615
MultiFabRegister(MultiFabRegister &&)=delete
VectorField get_alldirs(T name, int level)
Definition MultiFabRegister.H:630
ConstVectorField get_alldirs(T name, int level) const
Definition MultiFabRegister.H:642
bool internal_has_vector(std::string const &name, int level) const
Definition MultiFabRegister.cpp:326
void remake_level(int other_level, amrex::DistributionMapping const &new_dm)
Definition MultiFabRegister.cpp:247
void clear_level(int level)
Definition MultiFabRegister.cpp:599
void internal_erase(std::string const &name, int level)
Definition MultiFabRegister.cpp:570
static std::vector< Direction > m_all_dirs
Definition MultiFabRegister.H:944
MultiLevelScalarField internal_get_mr_levels(std::string const &name, int finest_level, bool skip_level_0)
Definition MultiFabRegister.cpp:418
amrex::MultiFab * alloc_init(T name, Direction dir, int level, amrex::BoxArray const &ba, amrex::DistributionMapping const &dm, int ncomp, amrex::IntVect const &ngrow, std::optional< amrex::Real const > initial_value=std::nullopt, bool remake=true, bool redistribute_on_remake=true)
Definition MultiFabRegister.H:343
std::map< std::string, MultiFabOwner > m_mf_register
Definition MultiFabRegister.H:933
amrex::MultiFab * get(T name, Direction dir, int level)
Definition MultiFabRegister.H:521
amrex::MultiFab * internal_get(std::string const &internal_name)
Definition MultiFabRegister.cpp:350
amrex::MultiFab * get(T name, int level)
Definition MultiFabRegister.H:499
MultiLevelVectorField internal_get_mr_levels_alldirs(std::string const &name, int finest_level, bool skip_level_0)
Definition MultiFabRegister.cpp:498
ConstMultiLevelVectorField get_mr_levels_alldirs(T name, int finest_level, bool skip_level_0=false) const
Definition MultiFabRegister.H:681
bool has_vector(T name, int level) const
Definition MultiFabRegister.H:478
MultiLevelVectorField get_mr_levels_alldirs(T name, int finest_level, bool skip_level_0=false)
Definition MultiFabRegister.H:667
amrex::MultiFab const * get(T name, int level) const
Definition MultiFabRegister.H:544
amrex::MultiFab * alias_init(N new_name, A alias_name, Direction dir, int level, std::optional< amrex::Real const > initial_value=std::nullopt)
Definition MultiFabRegister.H:412
amrex::MultiFab * internal_alloc_init(std::string const &name, int level, amrex::BoxArray const &ba, amrex::DistributionMapping const &dm, int ncomp, amrex::IntVect const &ngrow, std::optional< amrex::Real const > initial_value=std::nullopt, bool remake=true, bool redistribute_on_remake=true)
Definition MultiFabRegister.cpp:26
MultiFabRegister & operator=(MultiFabRegister const &)=delete
bool has(T name, int level) const
Definition MultiFabRegister.H:437
amrex::MultiFab * internal_alias_init(std::string const &new_name, std::string const &alias_name, int level, std::optional< amrex::Real const > initial_value=std::nullopt)
Definition MultiFabRegister.cpp:129
void erase(T name, int level)
Definition MultiFabRegister.H:709
VectorField internal_get_alldirs(std::string const &name, int level)
Definition MultiFabRegister.cpp:464
bool has(T name, Direction dir, int level) const
Definition MultiFabRegister.H:457
void erase(T name, Direction dir, int level)
Definition MultiFabRegister.H:725
MultiFabRegister(MultiFabRegister const &)=delete