Alamo
Voronoi.H
Go to the documentation of this file.
1// Initialize an N component field with a Voronoi tessellation.
2// (Mostly used by :code:`Integrator::PhaseFieldMicrostructure`).
3
4#ifndef IC_VORONOI_H_
5#define IC_VORONOI_H_
6
7#include "Set/Set.H"
8#include "IC/IC.H"
9#include "IO/ParmParse.H"
10
11namespace IC
12{
13class Voronoi : public IC<Set::Scalar>
14{
15public:
16 static constexpr const char* name = "voronoi";
17
19
20 Voronoi (amrex::Vector<amrex::Geometry> &_geom) : IC(_geom) {}
21 Voronoi (amrex::Vector<amrex::Geometry> &_geom,IO::ParmParse &pp, std::string name) : IC(_geom)
22 {pp_queryclass(name,*this);}
23 Voronoi (amrex::Vector<amrex::Geometry> &_geom, int _number_of_grains, Set::Scalar a_alpha) : IC(_geom)
24 {
25 Define(_number_of_grains,a_alpha);
26 }
27 Voronoi (amrex::Vector<amrex::Geometry> &a_geom, int a_number_of_grains) : IC(a_geom)
28 {
29 Define(a_number_of_grains,1.0);
30 }
31
32 void Define (int a_number_of_grains, Set::Scalar a_alpha)
33 {
34 Define(a_number_of_grains, std::vector<Set::Scalar>(a_number_of_grains,a_alpha),Type::Partition);
35 }
36
37 void Define (int a_number_of_grains,
38 std::vector<Set::Scalar> a_alpha,
39 Type a_type = Type::Values)
40 {
41 number_of_grains = a_number_of_grains;
42 alpha = a_alpha;
43 type = a_type;
44
45 if (a_alpha.size() == 1 && a_number_of_grains > 1)
46 alpha.resize(a_number_of_grains,a_alpha[0]);
47
49 srand(seed);
50 for (int n = 0; n<number_of_grains; n++)
51 {
52 AMREX_D_TERM(voronoi[n](0) = geom[0].ProbLo(0) + (geom[0].ProbHi(0)-geom[0].ProbLo(0))*Util::Random();,
53 voronoi[n](1) = geom[0].ProbLo(1) + (geom[0].ProbHi(1)-geom[0].ProbLo(1))*Util::Random();,
54 voronoi[n](2) = geom[0].ProbLo(2) + (geom[0].ProbHi(2)-geom[0].ProbLo(2))*Util::Random(););
55 }
56 };
57
58 void Add(const int &lev, Set::Field<Set::Scalar> &a_field, Set::Scalar)
59 {
60 Set::Vector size;
61 AMREX_D_TERM(size(0) = geom[0].ProbHi()[0] - geom[0].ProbLo()[0];,
62 size(1) = geom[0].ProbHi()[1] - geom[0].ProbLo()[1];,
63 size(2) = geom[0].ProbHi()[2] - geom[0].ProbLo()[2];)
64
65 for (amrex::MFIter mfi(*a_field[lev],amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
66 {
67 amrex::Box bx;
68 amrex::IndexType ixtype = a_field[lev]->ixType();
69 if (ixtype == amrex::IndexType::TheCellType()) bx = mfi.growntilebox();
70 else if (ixtype == amrex::IndexType::TheNodeType()) bx = mfi.grownnodaltilebox();
71
72 int ncomp = a_field[lev]->nComp();
73 amrex::Array4<Set::Scalar> const& field = a_field[lev]->array(mfi);
74 amrex::ParallelFor (bx,[=] AMREX_GPU_DEVICE(int i, int j, int k) {
75
77 AMREX_D_TERM(x(0) = geom[lev].ProbLo()[0] + ((amrex::Real)(i) + 0.5) * geom[lev].CellSize()[0];,
78 x(1) = geom[lev].ProbLo()[1] + ((amrex::Real)(j) + 0.5) * geom[lev].CellSize()[1];,
79 x(2) = geom[lev].ProbLo()[2] + ((amrex::Real)(k) + 0.5) * geom[lev].CellSize()[2];);
80
81 amrex::Real min_distance = std::numeric_limits<amrex::Real>::infinity();
82 int min_grain_id = -1;
83
84 for (int n = 0; n<number_of_grains; n++)
85 {
86 Set::Scalar d = (x - voronoi[n]).lpNorm<2>();
87
88 if (geom[0].isPeriodic(0))
89 {
90 d = std::min(d,
91 std::min( (x-voronoi[n] + size(0)*Set::Vector::Unit(0)).lpNorm<2>(),
92 (x-voronoi[n] - size(0)*Set::Vector::Unit(0)).lpNorm<2>()));
93 }
94#if AMREX_SPACEDIM>1
95 if (geom[0].isPeriodic(1))
96 {
97 d = std::min(d,
98 std::min( (x-voronoi[n] + size(0)*Set::Vector::Unit(1)).lpNorm<2>(),
99 (x-voronoi[n] - size(0)*Set::Vector::Unit(1)).lpNorm<2>()));
100 }
101#endif
102#if AMREX_SPACEDIM>2
103 if (geom[0].isPeriodic(2))
104 {
105 d = std::min(d,
106 std::min( (x-voronoi[n] + size(0)*Set::Vector::Unit(2)).lpNorm<2>(),
107 (x-voronoi[n] - size(0)*Set::Vector::Unit(2)).lpNorm<2>()));
108 }
109#endif
110 if (d<min_distance)
111 {
112 min_distance = d;
113 min_grain_id = n;
114 }
115 }
116
117 if (type == Type::Values) field(i,j,k) = alpha[min_grain_id];
118 else if (type == Type::Partition) field(i,j,k,min_grain_id % ncomp) = alpha[min_grain_id];
119 });
120 }
121 }
122
123 static void Parse(Voronoi &value, IO::ParmParse &pp)
124 {
125 pp.query("number_of_grains",value.number_of_grains); // Number of grains
126 pp.queryarr_default("alpha",value.alpha,{1.0}); // value that the field should take in each grain
127 pp.query("seed",value.seed); // Random seed to use
128
129 // Determine initialization type.
130 // "Partition" splits the tesselation across components, with voronoi region "n" being set to alpha[n]
131 // in field component n only.
132 // "Values" combines all cells into a single component of the field.
133 pp.query_switch("type",{
134 {"partition",[&](){ value.type = Type::Partition; }},
135 {"values", [&](){ value.type = Type::Values; }}
136 });
137
138 if (IO::ParmParse::InTraversalMode()) return;
139
140 value.Define(value.number_of_grains,value.alpha,value.type);
141 }
142
143private:
145 int seed = 1;
146 std::vector<Set::Scalar> alpha;
147 std::vector<Set::Vector> voronoi;
149};
150}
151#endif
#define pp_queryclass(...)
Definition ParmParse.H:130
amrex::Vector< amrex::Geometry > & geom
Definition IC.H:61
void Add(const int &lev, Set::Field< Set::Scalar > &a_field, Set::Scalar)
Definition Voronoi.H:58
static void Parse(Voronoi &value, IO::ParmParse &pp)
Definition Voronoi.H:123
std::vector< Set::Scalar > alpha
Definition Voronoi.H:146
int number_of_grains
Definition Voronoi.H:144
static constexpr const char * name
Definition Voronoi.H:16
Voronoi(amrex::Vector< amrex::Geometry > &_geom, int _number_of_grains, Set::Scalar a_alpha)
Definition Voronoi.H:23
void Define(int a_number_of_grains, std::vector< Set::Scalar > a_alpha, Type a_type=Type::Values)
Definition Voronoi.H:37
Type type
Definition Voronoi.H:148
Voronoi(amrex::Vector< amrex::Geometry > &_geom)
Definition Voronoi.H:20
Voronoi(amrex::Vector< amrex::Geometry > &a_geom, int a_number_of_grains)
Definition Voronoi.H:27
void Define(int a_number_of_grains, Set::Scalar a_alpha)
Definition Voronoi.H:32
std::vector< Set::Vector > voronoi
Definition Voronoi.H:147
Voronoi(amrex::Vector< amrex::Geometry > &_geom, IO::ParmParse &pp, std::string name)
Definition Voronoi.H:21
int query(std::string name, T &value, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:340
int query_switch(std::string name, std::initializer_list< std::pair< std::string, std::function< void()> > > cases, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:714
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
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
Set::Scalar Random()
Definition Set.cpp:34