Alamo
Ellipsoid.H
Go to the documentation of this file.
1// This IC initializes a single-component fab using the formula
2//
3// .. math::
4//
5// \phi = \begin{cases}
6// \alpha_{in} & (\mathbf{x}-\mathbf{x}_0)^T\mathbf{A}(\mathbf{x}-\mathbf{x}_0) \le r \\
7// \alpha_{out} & \text{else}
8// \end{cases}
9//
10// The boundary can be mollified using an error function with parameter :math:`\varepsilon`
11//
12// .. WARNING::
13//
14// This IC is redundant with :ref:`IC::Ellipse` and :ref:`IC::Expression` and will probably be consolidated
15//
16
17#ifndef IC_ELLIPSOID_H_
18#define IC_ELLIPSOID_H_
19
20#include "IC/IC.H"
21#include "Util/Util.H"
22#include "IO/ParmParse.H"
23
24/// \class Ellipsoid
25/// \brief Initialize an ellipsoidal inclusion
26namespace IC
27{
28class Ellipsoid : public IC<Set::Scalar>
29{
30public:
31 static constexpr const char* name = "ellipsoid";
32
34
35 Ellipsoid (amrex::Vector<amrex::Geometry> &_geom) : IC(_geom) {}
36 Ellipsoid (amrex::Vector<amrex::Geometry>& _geom, IO::ParmParse& pp, std::string name) : Ellipsoid(_geom)
37 {
38 pp_queryclass(name, *this);
39 }
40
41
42 void Add(const int &lev,Set::Field<Set::Scalar> &a_field, Set::Scalar)
43 {
44 for (amrex::MFIter mfi(*a_field[lev],amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
45 {
46 amrex::Box bx = mfi.tilebox();
47 bx.grow(a_field[lev]->nGrow());
48 amrex::IndexType type = a_field[lev]->ixType();
49
50 amrex::Array4<Set::Scalar> const& field = a_field[lev]->array(mfi);
51 amrex::ParallelFor (bx,[=] AMREX_GPU_DEVICE(int i, int j, int k) {
52
53 Set::Vector x = Set::Position(i,j,k,geom[lev],type);
54
55 Set::Scalar min_value = field(i,j,k);
56 for (int i=0 ; i < center.size(); i++)
57 {
58 Set::Scalar value = 0.;
59 Set::Scalar norm = (A[i]*(x-center[i])).lpNorm<2>();
60 value = 0.5 + 0.5*std::erf(((x-center[i]).transpose() * A[i] * (x-center[i]) - 1.0) / eps[i] / norm);
61 value = in_value + value*(out_value - in_value);
62 min_value = value < min_value ? value : min_value;
63 }
64 field(i,j,k) = min_value;
65 if (field(i,j,k) < std::min(in_value,out_value)) field(i,j,k) = std::min(in_value,out_value);
66 if (field(i,j,k) > std::max(in_value,out_value)) field(i,j,k) = std::max(in_value,out_value);
67 });
68 }
69 a_field[lev]->FillBoundary();
70 };
71
72private:
74 amrex::Vector<Set::Vector> center;
75 amrex::Vector<Set::Scalar> eps;
76 amrex::Vector<Set::Matrix> A;
78
79public:
80 static void Parse(Ellipsoid & value, IO::ParmParse & pp)
81 {
82 // This parser is not yet compliant with traversal mode.
84
85 amrex::Vector<Set::Scalar> center;
86 if(pp.contains("center")) pp_queryarr("center",center); // Center of the ellipse :math:`\mathbf{x}_0`
87
88 if(center.size() < AMREX_SPACEDIM) value.center.push_back(Set::Vector::Zero());
89 else
90 {
91 for (int i = 0; i<center.size(); i+=AMREX_SPACEDIM)
92 value.center.push_back(Set::Vector(AMREX_D_DECL(center[i],center[i+1],center[i+2])));
93 }
94
95 amrex::Vector<Set::Scalar> A;
96 if (pp.contains("A"))
97 {
98 pp_queryarr("A", A); // Matrix defining elipse radii and orientation
99 if(A.size() < AMREX_SPACEDIM*AMREX_SPACEDIM) value.A.push_back(Set::Matrix::Identity());
100 else
101 {
102 int i=0, j=0;
103 Set::Matrix temp = Set::Matrix::Zero();
104 for (i=0; i<A.size(); i+=AMREX_SPACEDIM)
105 {
106 for (j=0; j<AMREX_SPACEDIM; j++)
107 temp(i,j) = A[i+j];
108
109 if((i+j) % (AMREX_SPACEDIM*AMREX_SPACEDIM) == 0)
110 {
111 value.A.push_back(temp);
112 temp = Set::Matrix::Zero();
113 }
114 }
115 }
116 }
117 if (pp.contains("radius"))
118 {
119 amrex::Vector<Set::Scalar> a_radius;
120 pp_queryarr("radius",a_radius); // "Vector of radii (use instead of A)"
121
122 if (a_radius.size() < AMREX_SPACEDIM) value.A.push_back(Set::Matrix::Identity());
123 else
124 {
125 for (int i = 0; i<a_radius.size(); i+=AMREX_SPACEDIM)
126 {
127 Set::Matrix temp = Set::Matrix::Zero();
128 AMREX_D_TERM( temp(0,0) = 1./(a_radius[i]*a_radius[i]) ;, temp(1,1) = 1./(a_radius[i+1]*a_radius[i+1]) ;, temp(2,2) = 1./(a_radius[i+2]*a_radius[i+2]) ; );
129 value.A.push_back(temp);
130 }
131 }
132 }
133
134 amrex::Vector<Set::Scalar> eps;
135 pp_queryarr("eps", eps); // Mollifying value for erf
136
137 if(eps.size() < 1) value.eps.push_back(1.e-5);
138 for (int i =0; i < value.A.size(); i++)
139 {
140 if (eps[i] <= 0.0) eps[i] = 1.e-5;
141 value.eps.push_back(eps[i]);
142 }
143 //if(value.eps <= 0.) value.eps = 1.e-5;
144
145 pp_query_default("in_value", value.in_value, 0.0); // Value of field inside ellipse
146 pp_query_default("out_value", value.out_value, 1.0); // Value of field outside ellipse
147
148 std::string mollifier;
149 pp_query("mollifier",mollifier); // Type of mollifier to use (options: dirac, [gaussian])
150 if(mollifier == "Dirac" || mollifier == "dirac")
151 value.moll = Mollifier::Dirac;
152 else
154 }
155};
156}
157#endif
#define pp_queryarr(...)
Definition ParmParse.H:126
#define pp_query(...)
Definition ParmParse.H:129
#define pp_query_default(...)
Definition ParmParse.H:120
#define pp_queryclass(...)
Definition ParmParse.H:130
Ellipsoid(amrex::Vector< amrex::Geometry > &_geom)
Definition Ellipsoid.H:35
amrex::Vector< Set::Scalar > eps
Definition Ellipsoid.H:75
Mollifier moll
Definition Ellipsoid.H:77
static constexpr const char * name
Definition Ellipsoid.H:31
void Add(const int &lev, Set::Field< Set::Scalar > &a_field, Set::Scalar)
Definition Ellipsoid.H:42
Set::Scalar out_value
Definition Ellipsoid.H:73
Set::Scalar in_value
Definition Ellipsoid.H:73
Ellipsoid(amrex::Vector< amrex::Geometry > &_geom, IO::ParmParse &pp, std::string name)
Definition Ellipsoid.H:36
static void Parse(Ellipsoid &value, IO::ParmParse &pp)
Definition Ellipsoid.H:80
amrex::Vector< Set::Vector > center
Definition Ellipsoid.H:74
amrex::Vector< Set::Matrix > A
Definition Ellipsoid.H:76
amrex::Vector< amrex::Geometry > & geom
Definition IC.H:61
bool contains(std::string name, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:318
static bool IgnoreInTraversalMode(std::string note="This input parser is not yet compliant with traversal mode; its inputs are not fully documented.", const std::source_location &location=std::source_location::current())
Definition ParmParse.cpp:62
Initialize a spherical inclusion.
Definition BMP.H:20
amrex::Real Scalar
Definition Base.H:19
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
Definition Base.H:21
AMREX_FORCE_INLINE Vector Position(const int &i, const int &j, const int &k, const amrex::Geometry &geom, const amrex::IndexType &ixType)
Definition Base.H:122
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, AMREX_SPACEDIM > Matrix
Definition Base.H:24