Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <memory>
7 : #include <pup.h>
8 :
9 : #include "DataStructures/Tensor/TypeAliases.hpp"
10 : #include "Utilities/Serialization/CharmPupable.hpp"
11 : #include "Utilities/TMPL.hpp"
12 :
13 : /// \cond
14 : class DataVector;
15 :
16 : namespace gsl {
17 : template <typename T>
18 : class not_null;
19 : } // namespace gsl
20 : /// \endcond
21 :
22 : namespace grmhd::AnalyticData {
23 :
24 : /*!
25 : * \brief Things related to the initial (seed) magnetic field that can be
26 : * superposed on GRMHD initial data.
27 : *
28 : * In many cases we assign magnetic fields in terms of the vector potential,
29 : * which can be computed as
30 : *
31 : * \f{align*}{
32 : * B^i & = n_a\epsilon^{aijk}\partial_jA_k \\
33 : * & = \frac{1}{\sqrt{\gamma}}[ijk]\partial_j A_k,
34 : * \f}
35 : *
36 : * where \f$[ijk]\f$ is the total anti-symmetric symbol.
37 : *
38 : * For example, in the Cartesian coordinates,
39 : *
40 : * \f{align*}{
41 : * B^x & = \frac{1}{\sqrt{\gamma}} (\partial_y A_z - \partial_z A_y), \\
42 : * B^y & = \frac{1}{\sqrt{\gamma}} (\partial_z A_x - \partial_x A_z), \\
43 : * B^z & = \frac{1}{\sqrt{\gamma}} (\partial_x A_y - \partial_y A_x).
44 : * \f}
45 : *
46 : *
47 : * \warning The magnetic field classes assume the magnetic field is initialized,
48 : * both in size and value, before being passed into the `variables` function.
49 : * This is so that multiple magnetic fields can be superposed. Each magnetic
50 : * field configuration does a `+=` to make this possible.
51 : */
52 : namespace InitialMagneticFields {
53 :
54 : /*!
55 : * \brief The abstract base class for initial magnetic field configurations.
56 : *
57 : * \warning This assumes the magnetic field is initialized, both in size and
58 : * value, before being passed into the `variables` function. This is so that
59 : * multiple magnetic fields can be superposed. Each magnetic field
60 : * configuration does a `+=` to make this possible.
61 : */
62 1 : class InitialMagneticField : public PUP::able {
63 : protected:
64 0 : InitialMagneticField() = default;
65 :
66 : public:
67 0 : ~InitialMagneticField() override = default;
68 :
69 0 : virtual auto get_clone() const -> std::unique_ptr<InitialMagneticField> = 0;
70 :
71 0 : virtual void variables(
72 : gsl::not_null<tnsr::I<DataVector, 3>*> result,
73 : const tnsr::I<DataVector, 3>& coords, const Scalar<DataVector>& pressure,
74 : const Scalar<DataVector>& sqrt_det_spatial_metric,
75 : const tnsr::i<DataVector, 3>& deriv_pressure) const = 0;
76 :
77 0 : virtual void variables(gsl::not_null<tnsr::I<double, 3>*> result,
78 : const tnsr::I<double, 3>& coords,
79 : const Scalar<double>& pressure,
80 : const Scalar<double>& sqrt_det_spatial_metric,
81 : const tnsr::i<double, 3>& deriv_pressure) const = 0;
82 :
83 0 : virtual bool is_equal(const InitialMagneticField& rhs) const = 0;
84 :
85 : /// \cond
86 : explicit InitialMagneticField(CkMigrateMessage* msg) : PUP::able(msg) {}
87 : WRAPPED_PUPable_abstract(InitialMagneticField);
88 : /// \endcond
89 : };
90 :
91 : } // namespace InitialMagneticFields
92 : } // namespace grmhd::AnalyticData
|