Alamo
PerturbedInterface.H
Go to the documentation of this file.
1 // Initialize a perturbed interface using Fourier Modes
2 ///
3 // Notes:
4 // 1. \todo Extend this class to allow for 3D perturbations, currently only 2D are allowed
5 // 2. \todo Allow for cosine (or complex exponential) expansions rather than just sin.
6 // 3. \note This is a **two grain only** initial condition.
7 // 4. \note This replaces the depricated "perturbed_bar" initial condition from previous versions
8 //
9 // The interface is defined as the :math:`x=0` plane (2D), or the :math:`x=0,z=0` plane (3D).
10 // The equation for the interface is given by
11 // :math:`y(x,z) = \sum_{n\in \{n_1,\ldots,n_N\}} A_n \sin(n\pi x/L_x)`
12 // where :math:`A_n` are the amplitudes (stored in #wave_amplitudes),
13 // :math:`n_1,\ldots,n_N\subset\mathbb{Z}_+` are wave numbers (stored in #wave_numbers),
14 // and :math:`L_x` is the length in the x direction (obtained using the #geom object).
15 //
16 // Grain 1 is defined as being above :math:`y(x,z)`, Grain 2 is defined as being below.
17 
18 #ifndef IC_PERTURBEDINTERFACE_H_
19 #define IC_PERTURBEDINTERFACE_H_
20 
21 #include "IC/IC.H"
22 #include "Util/Util.H"
23 #include "IO/ParmParse.H"
24 
25 namespace IC
26 {
27 class PerturbedInterface : public IC
28 {
29 public:
31  PerturbedInterface (amrex::Vector<amrex::Geometry> &_geom) :
32  IC(_geom)
33  { }
34  PerturbedInterface(amrex::Vector<amrex::Geometry> &_geom,IO::ParmParse &pp, std::string name) : IC(_geom)
35  {pp_queryclass(name,*this);}
36  PerturbedInterface(amrex::Vector<amrex::Geometry> &_geom,IO::ParmParse &pp) : IC(_geom)
37  {pp_queryclass(*this);}
38 
39  void Add(const int &lev, Set::Field<Set::Scalar> &a_field, Set::Scalar)
40  {
41  Set::Scalar AMREX_D_DECL(L1 = geom[lev].ProbHi()[0] - geom[lev].ProbLo()[0],
42  L2 = geom[lev].ProbHi()[1] - geom[lev].ProbLo()[1],
43  L3 = geom[lev].ProbHi()[2] - geom[lev].ProbLo()[2]);
44 
45  for (amrex::MFIter mfi(*a_field[lev],true); mfi.isValid(); ++mfi)
46  {
47  amrex::Box bx = mfi.tilebox();
48  bx.grow(a_field[lev]->nGrow());
49  amrex::Array4<Set::Scalar> const& field = a_field[lev]->array(mfi);
50  amrex::IndexType type = a_field[lev]->ixType();
51 
52  amrex::ParallelFor (bx,[=] AMREX_GPU_DEVICE(int i, int j, int k) {
53  amrex::IntVect m(AMREX_D_DECL(i,j,k));
54 
55  Set::Vector x;
56  // NODE
57  if (type == amrex::IndexType::TheNodeType())
58  {
59  AMREX_D_TERM(x(0) = geom[lev].ProbLo()[0] + ((amrex::Real)(i)) * geom[lev].CellSize()[0];,
60  x(1) = geom[lev].ProbLo()[1] + ((amrex::Real)(j)) * geom[lev].CellSize()[1];,
61  x(2) = geom[lev].ProbLo()[2] + ((amrex::Real)(k)) * geom[lev].CellSize()[2];);
62  }
63  else if (type == amrex::IndexType::TheCellType())
64  {
65  AMREX_D_TERM(x(0) = geom[lev].ProbLo()[0] + ((amrex::Real)(i) + 0.5) * geom[lev].CellSize()[0];,
66  x(1) = geom[lev].ProbLo()[1] + ((amrex::Real)(j) + 0.5) * geom[lev].CellSize()[1];,
67  x(2) = geom[lev].ProbLo()[2] + ((amrex::Real)(k) + 0.5) * geom[lev].CellSize()[2];);
68  }
69 
70  Set::Scalar bdry = 0.;
71 #if AMREX_SPACEDIM == 2
72  Set::Scalar s1=NAN, l1=NAN;
73  if (normal==Direction::X) {s1 = x(1); l1 = L2;}
74  if (normal==Direction::Y) {s1 = x(0); l1 = L1;}
75  for (int n = 0; n < wave_numbers.size(); n++)
76  bdry += wave_amplitudes[n]
77  * ( fabs(std::cos(phis[n]))*std::cos(wave_numbers[n].real()*Set::Constant::Pi*s1 / l1) +
78  fabs(std::sin(phis[n]))*std::sin(wave_numbers[n].imag()*Set::Constant::Pi*s1 / l1));
79 #elif AMREX_SPACEDIM == 3
80  Set::Scalar s1=NAN, s2=NAN, l1=NAN, l2=NAN;
81  if (normal==Direction::X) {s1 = x(1); s2 = x(2); l1 = L2; l2 = L3;}
82  if (normal==Direction::Y) {s1 = x(2); s2 = x(0); l1 = L3; l2 = L1;}
83  if (normal==Direction::Z) {s1 = x(0); s2 = x(0); l1 = L1; l2 = L2;}
84  for (int n = 0; n < wave_numbers.size(); n++)
85  bdry += wave_amplitudes[n]
86  * ( fabs(std::cos(phis[n]))*std::cos(wave_numbers[n].real()*Set::Constant::Pi*s1 / l1) +
87  fabs(std::sin(phis[n]))*std::sin(wave_numbers[n].imag()*Set::Constant::Pi*s1 / l1))
88  * ( fabs(std::cos(phis[n]))*std::cos(wave_numbers[n].real()*Set::Constant::Pi*s2 / l2) +
89  fabs(std::sin(phis[n]))*std::sin(wave_numbers[n].imag()*Set::Constant::Pi*s2 / l2))
90  ;
91 #endif
92  if (mol == Mollifier::Dirac)
93  {
94  // Util::Message(INFO);
95  if ((normal == Direction::X && x(0) < bdry + offset)||
96  (normal == Direction::Y && x(1) < bdry + offset)||
97  (normal == Direction::Z && x(2) < bdry + offset))
98  {
99  field(i,j,k,reverse) = 1.;
100  field(i,j,k,1-reverse) = 0.;
101  }
102  else
103  {
104  field(i,j,k,reverse) = 0.;
105  field(i,j,k,1-reverse) = 1.;
106  }
107  }
108  else
109  {
110  Set::Scalar t = 0.0;
111  if (normal == Direction::X) t = x(0) - bdry - offset;
112  else if (normal == Direction::Y) t = x(1) - bdry - offset;
113  else if (normal == Direction::Z) t = x(2) - bdry - offset;
114 
115  Set::Scalar value = 0.5 + 0.5*std::erf(t/eps);
116  // Util::Message(INFO, "value = ", value);
117  field(i,j,k,reverse) = value;
118  field(i,j,k,1-reverse) = 1. - value;
119 
120  if (field(i,j,k,0) < 0.0) field(i,j,k,reverse) = 0.0;
121  if (field(i,j,k,0) > 1.0) field(i,j,k,reverse) = 1.0;
122  if (field(i,j,k,1) < 0.0) field(i,j,k,1-reverse) = 0.0;
123  if (field(i,j,k,1) > 1.0) field(i,j,k,1-reverse) = 1.0;
124  }
125  });
126  }
127 
128  };
129 
130 private:
131  enum Direction {X,Y,Z};
132  Direction normal = Direction::Y;
134  amrex::Vector<std::complex<int> > wave_numbers; ///< Store mode amplitudes \f$A_n\f$
135  amrex::Vector<Set::Scalar> wave_amplitudes;
136  std::vector<Set::Scalar> phis;
139  int reverse = 0;
140 
141 public:
142  static void Parse(PerturbedInterface & value, IO::ParmParse & pp)
143  {
144  std::vector<std::string> wave_numbers_str;
145  pp_queryarr("wave_numbers",wave_numbers_str); // Wave numbers
146  for (unsigned int i = 0; i<wave_numbers_str.size(); ++i)
147  {
148  value.wave_numbers.push_back(Util::String::Parse<std::complex<int> >(wave_numbers_str[i]));
149  value.phis.push_back(std::atan2(value.wave_numbers[i].imag(),value.wave_numbers[i].real()));
150  }
151  pp_queryarr("wave_amplitudes",value.wave_amplitudes); // Wave amplitudes
152 
153  std::string normal_str;
154  pp_query("normal",normal_str); // Which axis is normal to the interface (x,y,z)
155  if (normal_str == "x") value.normal = Direction::X;
156  if (normal_str == "y") value.normal = Direction::Y;
157  if (normal_str == "z") value.normal = Direction::Z;
158  std::string offset_str;
159  pp_query("offset",value.offset); // Interface offset from origin
160 
161  pp_query("reverse",value.reverse); // If true, flip the interface (default:false)
162  Util::Assert(INFO,TEST(value.reverse==0 || value.reverse==1));
163 
164  if (value.wave_numbers.size() != value.wave_amplitudes.size())
165  Util::Abort(INFO, "Number of wave numbers and amplitudes must match");
166 
167  std::string mollifier = "dirac";
168  pp_query("mollifier", mollifier); // Mollifier (options: dirac, [gaussian])
169 
170  if(mollifier == "dirac")
171  {
172  value.mol = Mollifier::Dirac;
173  if (pp.contains("eps")) Util::Warning(INFO,"eps defined but not needed for dirac mollifier");
174  }
175  else
176  {
177  value.mol = Mollifier::Gaussian;
178  pp_query("eps",value.eps); // Magnitude of mollifier
179  Util::Message(INFO, "eps = ", value.eps);
180  }
181  }
182 
183 };
184 }
185 #endif
IC::IC::geom
amrex::Vector< amrex::Geometry > & geom
Definition: IC.H:45
IC::PerturbedInterface::Parse
static void Parse(PerturbedInterface &value, IO::ParmParse &pp)
Definition: PerturbedInterface.H:142
IC::PerturbedInterface::X
@ X
Definition: PerturbedInterface.H:131
Util::String::Parse
std::complex< int > Parse(std::string input)
Definition: Util.cpp:308
IC::PerturbedInterface::mol
Mollifier mol
Definition: PerturbedInterface.H:137
IC::PerturbedInterface::phis
std::vector< Set::Scalar > phis
Definition: PerturbedInterface.H:136
BC::AMREX_D_DECL
@ AMREX_D_DECL
Definition: BC.H:34
Util.H
IC::PerturbedInterface::Add
void Add(const int &lev, Set::Field< Set::Scalar > &a_field, Set::Scalar)
Definition: PerturbedInterface.H:39
TEST
#define TEST(x)
Definition: Util.H:21
IC::PerturbedInterface::offset
Set::Scalar offset
Definition: PerturbedInterface.H:133
IC::PerturbedInterface::wave_numbers
amrex::Vector< std::complex< int > > wave_numbers
Store mode amplitudes .
Definition: PerturbedInterface.H:134
IC::PerturbedInterface::Direction
Direction
Definition: PerturbedInterface.H:131
t
std::time_t t
Definition: FileNameParse.cpp:12
Set::Field< Set::Scalar >
Definition: Set.H:236
X
#define X(name)
IC::PerturbedInterface::eps
Set::Scalar eps
Definition: PerturbedInterface.H:138
IC::PerturbedInterface::normal
Direction normal
Definition: PerturbedInterface.H:132
Set::Vector
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
Definition: Base.H:20
ParmParse.H
IC::PerturbedInterface::PerturbedInterface
PerturbedInterface(amrex::Vector< amrex::Geometry > &_geom)
Definition: PerturbedInterface.H:31
pp_query
#define pp_query(...)
Definition: ParmParse.H:104
IC::PerturbedInterface::PerturbedInterface
PerturbedInterface(amrex::Vector< amrex::Geometry > &_geom, IO::ParmParse &pp, std::string name)
Definition: PerturbedInterface.H:34
Util::Gaussian
Set::Scalar Gaussian(amrex::Real mean, amrex::Real std_deviation)
Definition: Set.cpp:13
IC::PerturbedInterface::PerturbedInterface
PerturbedInterface(amrex::Vector< amrex::Geometry > &_geom, IO::ParmParse &pp)
Definition: PerturbedInterface.H:36
Set::Scalar
amrex::Real Scalar
Definition: Base.H:19
pp_queryclass
#define pp_queryclass(...)
Definition: ParmParse.H:105
IC::PerturbedInterface::Dirac
@ Dirac
Definition: PerturbedInterface.H:30
IC::PerturbedInterface::Y
@ Y
Definition: PerturbedInterface.H:131
IC::PerturbedInterface
Definition: PerturbedInterface.H:27
IC::PerturbedInterface::Z
@ Z
Definition: PerturbedInterface.H:131
IO::ParmParse::contains
bool contains(std::string name)
Definition: ParmParse.H:151
Util::Assert
AMREX_FORCE_INLINE void Assert(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
Definition: Util.H:65
Util::Abort
void Abort(const char *msg)
Definition: Util.cpp:165
Set::Constant::Pi
static const Set::Scalar Pi
Definition: Set.H:286
IC
Definition: Affine.H:18
Util::Warning
void Warning(std::string file, std::string func, int line, Args const &... args)
Definition: Util.H:171
IO::ParmParse
Definition: ParmParse.H:110
IC::PerturbedInterface::Gaussian
@ Gaussian
Definition: PerturbedInterface.H:30
IC::PerturbedInterface::Mollifier
Mollifier
Definition: PerturbedInterface.H:30
IC::PerturbedInterface::wave_amplitudes
amrex::Vector< Set::Scalar > wave_amplitudes
Definition: PerturbedInterface.H:135
IC::PerturbedInterface::reverse
int reverse
Definition: PerturbedInterface.H:139
INFO
#define INFO
Definition: Util.H:20
IC.H
Util::Message
void Message(std::string file, std::string func, int line, Args const &... args)
Definition: Util.H:133
pp_queryarr
#define pp_queryarr(...)
Definition: ParmParse.H:103