Alamo
PSRead.H
Go to the documentation of this file.
1//
2// Fill a domain (region where field=0) with packed spheres (regions where field=1).
3// Sphere locations and radii are determined from an xyzr file.
4//
5
6#ifndef IC_PSREAD_H_
7#define IC_PSREAD_H_
8
9#include "Set/Set.H"
10#include "IC/IC.H"
11#include "AMReX_GpuAsyncArray.H"
12#include "Util/Util.H"
13using namespace std;
14#include <iostream>
15#include <vector>
16#include <algorithm>
17#include <iterator>
18#include <mpi.h>
19#include "IO/ParmParse.H"
20
21namespace IC
22{
23class PSRead : public IC<Set::Scalar>
24{
25public:
26 static constexpr const char* name = "psread";
27
28 enum Type
29 {
31 Values
32 };
33
34 PSRead(amrex::Vector<amrex::Geometry>& _geom) : IC(_geom) {}
35
36 PSRead(amrex::Vector<amrex::Geometry>& _geom, IO::ParmParse& pp, std::string name) : IC(_geom)
37 {
38 pp.queryclass(name, *this);
39 }
40 void Define() {
41
42 };
43
44 void Add(const int& lev, Set::Field<Set::Scalar>& a_phi, Set::Scalar)
45 {
46 const Set::Vector size = Set::Size(geom[lev]);
47 const int ncomp = a_phi[lev]->nComp();
48 const auto prob_lo = geom[lev].ProbLoArray();
49 const auto cell_size = geom[lev].CellSizeArray();
50 const amrex::GpuArray<int, AMREX_SPACEDIM> periodic = {
51 AMREX_D_DECL( geom[0].isPeriodic(0),
52 geom[0].isPeriodic(1),
53 geom[0].isPeriodic(2))};
54 std::vector<Set::Scalar> coordinates(
55 X.size() * AMREX_SPACEDIM);
56 for (int n = 0; n < static_cast<int>(X.size()); ++n)
57 for (int d = 0; d < AMREX_SPACEDIM; ++d)
58 coordinates[n * AMREX_SPACEDIM + d] = X[n](d);
59 amrex::Gpu::AsyncArray<Set::Scalar> X_device(
60 coordinates.data(), coordinates.size());
61 amrex::Gpu::AsyncArray<Set::Scalar> R_device(R.data(), R.size());
62 const Set::Scalar* X = X_device.data();
63 const Set::Scalar* R = R_device.data();
64 const int sphere_count = static_cast<int>(this->X.size());
65 const Set::Scalar eps = this->eps;
66 const bool invert = this->invert;
67
68 for (amrex::MFIter mfi(*a_phi[lev], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
69 {
70 amrex::Box bx;
71 amrex::IndexType type = a_phi[lev]->ixType();
72 if (type == amrex::IndexType::TheCellType()) bx = mfi.growntilebox();
73 else if (type == amrex::IndexType::TheNodeType()) bx = mfi.grownnodaltilebox();
74 else Util::Abort(INFO, "Unkonwn index type");
75
76 amrex::Array4<Set::Scalar> const& phi = a_phi[lev]->array(mfi);
77 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k)
78 {
79 Set::Vector x =
80 Set::Position(i, j, k, prob_lo, cell_size, type);
81 Set::Scalar min_grain_id = 0;
82
83 for (int n = 0; n < sphere_count; n++)
84 {
86 Set::Scalar d1 = std::numeric_limits<Set::Scalar>::infinity();
87
88 Set::Vector center;
89 for ( int direction = 0;
90 direction < AMREX_SPACEDIM; ++direction)
91 center(direction) =
92 X[n * AMREX_SPACEDIM + direction];
93 d = (x - center).lpNorm<2>();
94
95 if (periodic[0])
96 {
97 d1 = std::min((x - center + size(0) * Set::Vector::Unit(0)).lpNorm<2>(),
98 (x - center - size(0) * Set::Vector::Unit(0)).lpNorm<2>());
99 }
100#if AMREX_SPACEDIM > 1
101 if (periodic[1])
102 {
103 d1 = std::min((x - center + size(1) * Set::Vector::Unit(1)).lpNorm<2>(),
104 (x - center - size(1) * Set::Vector::Unit(1)).lpNorm<2>());
105 }
106#endif
107#if AMREX_SPACEDIM > 2
108 if (periodic[2])
109 {
110 d1 = std::min((x - center + size(2) * Set::Vector::Unit(2)).lpNorm<2>(),
111 (x - center - size(2) * Set::Vector::Unit(2)).lpNorm<2>());
112 }
113#endif
114
115 d = std::min(d, d1);
116
117 if (d <= (R[n] + eps))
118
119 {
120 Set::Scalar m = 0.5 * (1 + erf((-d + R[n]) / (eps)));
121 min_grain_id = min_grain_id + m * (1. - min_grain_id);
122 }
123 }
124
125 phi(i, j, k, 0) = min_grain_id;
126 if (invert) phi(i,j,k,0) = 1.0 - min_grain_id;
127 if (ncomp > 1) phi(i, j, k, 1) = 1.0 - min_grain_id;
128 });
129 }
130 }
131
132 static void Parse(PSRead& value, IO::ParmParse& pp)
133 {
134 std::string filename;
135 int verbose = 0;
136 // Diffuseness of the sphere boundary
137 pp.query_default("eps", value.eps, "0.0", Unit::Length());
138
139 pp.forbid("filename", "use file.name instead");
140 // Location of .xyzr file
141 pp.query_file("file.name", filename);
142
143 // Verbosity (used in parser only)
144 pp.query_default("verbose", verbose, 0);
145
146 // Unitless coordinate multiplier
147 pp.query_default("mult",value.mult, "1.0", Unit::Less());
148
149 // Whether to invert (1 outside instead of inside spheres)
150 pp.query_default("invert",value.invert,false);
151
152 // X-offset
153 pp.queryarr_default("x0",value.x0,"0 0 0", Unit::Length());
154
155 if (pp.contains("x0"))
156 pp_queryarr("x0",value.x0); // Coordinate offset
157
158 Unit unit = Unit::Length();
159 // Units of length in the file
160 pp.queryunit("file.unit",unit);
161
162 if (IO::ParmParse::InTraversalMode()) return;
163
165 "Unit must be of type length but got unit ",unit.normalized_unitstring());
166
167 std::ifstream datafile(filename);
168 std::string line;
169 if (datafile.is_open())
170 {
171 value.X.clear();
172 value.R.clear();
173
174 while (getline(datafile, line))
175 {
176 std::istringstream in(line);
177
178 std::string strx, stry, strz, strR;
179 in >> strx >> stry >> strz >> strR;
180
181 Set::Scalar x = (std::stod(strx) * unit).normalized_value();
182 Set::Scalar y = (std::stod(stry) * unit).normalized_value();
183 #if AMREX_SPACEDIM > 2
184 Set::Scalar z = (std::stod(strz) * unit).normalized_value();
185 #endif
186 Set::Scalar r = (std::stod(strR) * unit).normalized_value();
187
188 Set::Vector X(AMREX_D_DECL(x,y,z));
189 X = value.x0 + value.mult*X;
190
191 value.X.push_back(X);
192 value.R.push_back(r);
193 if (verbose > 0)
194 Util::Message(INFO, "x=", value.X.back().transpose(), " r=", value.R.back());
195 }
196 datafile.close();
197 }
198 else
199 {
200 Util::Abort(INFO, "Unable to open file ", filename);
201 }
202 }
203
204private:
205 std::vector<Set::Vector> X;
206 std::vector<Set::Scalar> R;
209 Set::Vector x0 = Set::Vector::Zero();
210 bool invert = false;
211};
212}
213#endif
#define pp_queryarr(...)
Definition ParmParse.H:126
#define TEST(x)
Definition Util.H:25
#define INFO
Definition Util.H:24
amrex::Vector< amrex::Geometry > & geom
Definition IC.H:61
PSRead(amrex::Vector< amrex::Geometry > &_geom, IO::ParmParse &pp, std::string name)
Definition PSRead.H:36
static void Parse(PSRead &value, IO::ParmParse &pp)
Definition PSRead.H:132
std::vector< Set::Vector > X
Definition PSRead.H:205
void Define()
Definition PSRead.H:40
bool invert
Definition PSRead.H:210
@ Partition
Definition PSRead.H:30
PSRead(amrex::Vector< amrex::Geometry > &_geom)
Definition PSRead.H:34
Set::Scalar eps
Definition PSRead.H:207
void Add(const int &lev, Set::Field< Set::Scalar > &a_phi, Set::Scalar)
Definition PSRead.H:44
static constexpr const char * name
Definition PSRead.H:26
Set::Scalar mult
Definition PSRead.H:208
Set::Vector x0
Definition PSRead.H:209
std::vector< Set::Scalar > R
Definition PSRead.H:206
void queryclass(std::string name, T *value, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:1767
void forbid(std::string name, std::string explanation, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:301
int query_default(std::string name, T &value, T defaultvalue, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:492
int queryunit(std::string name, Unit &value, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:351
int query_file(std::string name, std::string &value, bool copyfile, bool checkfile, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:961
static bool InTraversalMode()
Definition ParmParse.cpp:14
int queryarr_default(std::string name, std::vector< std::string > &value, std::vector< std::string > defaultvalue, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:1303
bool contains(std::string name, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:318
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
AMREX_FORCE_INLINE Vector Size(const amrex::Geometry &geom)
Definition Base.H:177
AMREX_FORCE_INLINE void AssertException(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
Definition Util.H:265
void Message(std::string file, std::string func, int line, Args const &... args)
Definition Util.H:140
AMREX_GPU_HOST_DEVICE void Abort(const char *msg)
Definition Util.cpp:406
Definition Unit.H:21
bool isType(const Unit &test) const
Definition Unit.H:425
std::string normalized_unitstring() const
Definition Unit.H:515
static Unit Length()
Definition Unit.H:198
static Unit Less()
Definition Unit.H:197