Alamo
Disconnection.H
Go to the documentation of this file.
1//
2// This simulates the creation of "disconnection pairs" at a GB
3// by perturbing the order parameter :math:`\eta` with a gaussian.
4//
5// Disconnections can be nucleated randomly, or they can be added
6// in a controlled way through the "fixed" option.
7//
8// See the following reference for further details
9//
10// .. bibliography::
11// :list: none
12// :filter: False
13//
14// gokuli2021multiphase
15//
16//
17
18#ifndef MODEL_DEFECT_DISCONNECTION
19#define MODEL_DEFECT_DISCONNECTION
20
21#include <random>
22
23#include "AMReX_SPACE.H"
24#include "IO/ParmParse.H"
25#include "Set/Base.H"
26#include "Util/MPI.H"
27#include "Util/Util.H"
28
29namespace Model
30{
31namespace Defect
32{
34{
35public:
36
39
40 static void
42 {
43 if (AMREX_SPACEDIM != 2)
44 {
47 }
48 // time to start applying disconnections
49 pp.query_default ("tstart", value.tstart,0.0);
50 // nucleation energy
51 pp.query_default ("nucleation_energy", value.nucleation_energy,0.0);
52 // characteristic time
53 pp.query_default("tau_vol", value.tau_vol, 1.0);
54 // temperature
55 pp.query_default("temp", value.temp, 0.0);
56 // characteristic size
57 pp.query_default("box_size", value.box_size, 0.0);
58 // interval between generation events
59 pp.query_required("interval", value.interval);
60 // regularization epsilon
61 pp.query_default ("epsilon",value.epsilon,1E-20);
62 // whether to manually specify disconnection nucleation points
63 pp.query_if_else("disconnection.fixed.on", [&]() {
64 value.fixed.on = true;
65
66 // array of x locations
67 pp.queryarr("fixed.sitex",value.fixed.sitex);
68 // array of y locations
69 pp.queryarr("fixed.sitey",value.fixed.sitey);
70 // array of order parameter number
71 pp.queryarr("fixed.phases",value.fixed.phases);
72 // time to appear
73 pp.queryarr("fixed.time",value.fixed.time);
74 Util::Assert(INFO,TEST(value.fixed.sitex.size() == value.fixed.sitey.size()));
75 Util::Assert(INFO,TEST(value.fixed.sitex.size() == value.fixed.phases.size()));
76 Util::Assert(INFO,TEST(value.fixed.sitex.size() == value.fixed.time.size()));
77 value.fixed.done.resize(value.fixed.sitex.size(),false);
78
79 }, [&]() {
80
81 value.unif_dist = std::uniform_real_distribution<double>(0.0,1.0);
82 value.int_dist = std::uniform_int_distribution<int>(0,1);
83 value.rand_num_gen.seed(amrex::ParallelDescriptor::MyProc());
84 });
85
86 // verbosity
87 pp_query_default("verbose",value.verbose,false);
88 }
89
90
91 /// This operates on an entire field, and manages all of the MPI
92 /// communication necessary for consistent nucleation.
93 void
95 std::vector<amrex::Geometry> &geom,
96 Set::Scalar timestep,
98 int iter
99 )
100 {
101 Util::Assert(INFO,TEST(eta_mf[0]->nComp() == 2), "This only works for 2 component phase fields");
102
103 if (time < tstart) // wait until it's time to go
104 return;
105 if (iter % interval) // skip every [interval] timesteps
106 return;
107
108 sitex.clear();
109 sitey.clear();
110 phases.clear();
111
112 int max_lev = eta_mf.finest_level;
113
114 const Set::Scalar *DX = geom[max_lev].CellSize();
115 Set::Scalar exponent = DX[0] * DX[0] * (timestep * interval) / tau_vol;
116
117 // Determine the nucleation sites in the finest grid only
118 for (amrex::MFIter mfi(*eta_mf[max_lev], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
119 {
120 const amrex::Box &bx = mfi.tilebox();
121 amrex::Array4<amrex::Real> const &eta = (*eta_mf[max_lev]).array(mfi);
122 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k)
123 {
125 E0 /= epsilon + 256.0*eta(i,j,k,0)*eta(i,j,k,0)*eta(i,j,k,0)*eta(i,j,k,0)*eta(i,j,k,1)*eta(i,j,k,1)*eta(i,j,k,1)*eta(i,j,k,1);
126 Set::Scalar p = std::exp(-E0/(K_b*temp));
127 Set::Scalar P = 1.0 - std::pow(1.0 - p,exponent);
128 if (eta(i,j,k,0) < 0 || eta(i,j,k,0) > 1.0 || eta(i,j,k,1) < 0 || eta(i,j,k,1) > 1.0) P = 0.0;
129 Set::Scalar q = 0.0;
131 if (q < P)
132 {
133 sitex.push_back(geom[max_lev].ProbLo()[0] + ((amrex::Real)(i)) * DX[0]);
134 sitey.push_back(geom[max_lev].ProbLo()[1] + ((amrex::Real)(j)) * DX[1]);
135 int phase = int_dist(rand_num_gen);
136 phases.push_back(phase);
137 } });
138 }
139
140 // Sync up all the nucleation sites among processors
144
145 if (verbose)
146 {
147 Util::Message(INFO, "Nucleating ", phases.size(), " disconnections");
148 }
149
150 if (sitex.size() > 0)
151 {
152 // Now that we all know the nucleation locations, perform the nucleation
153 for (int lev = 0; lev <= max_lev; lev++)
154 {
155 amrex::Box domain = geom[lev].Domain();
156 domain.convert(amrex::IntVect::TheNodeVector());
157 const amrex::Real *DX = geom[lev].CellSize();
158 for (amrex::MFIter mfi(*eta_mf[lev], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
159 {
160 const amrex::Box bx = mfi.grownnodaltilebox() & domain;
161 amrex::Array4<Set::Scalar> const &eta = (*eta_mf[lev]).array(mfi);
162 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k)
163 {
164 Set::Vector x;
165 AMREX_D_TERM(
166 x(0) = geom[lev].ProbLo()[0] + ((amrex::Real)(i)) * DX[0];,
167 x(1) = geom[lev].ProbLo()[1] + ((amrex::Real)(j)) * DX[1];,
168 x(2) = geom[lev].ProbLo()[2] + ((amrex::Real)(k)) * DX[2];);
169 for (unsigned int m = 0; m < phases.size(); m++)
170 {
171 amrex::Real r_squared = 0;
172 Set::Vector nucleation_site(AMREX_D_DECL(sitex[m], sitey[m], 0.0));
173 for (int n = 0; n < AMREX_SPACEDIM; n++)
174 {
175 amrex::Real dist = nucleation_site(n) - x(n);
176 r_squared += dist * dist;
177 }
178 amrex::Real bump = exp(-r_squared / box_size);
179 eta(i, j, k, phases[m]) = bump * (1 - eta(i, j, k, phases[m])) + eta(i, j, k, phases[m]);
180 eta(i, j, k, 1 - phases[m]) = (1. - bump) * eta(i, j, k, 1 - phases[m]);
181 }
182 });
183 }
184 }
185 }
186 }
187
188
189
190private:
191
192 bool verbose = false;
193
200
201 int interval = -1;
202
203 std::uniform_real_distribution<double> unif_dist; /// random number distribution for spatial location
204 std::uniform_int_distribution<int> int_dist; /// random number generator for phase
205 std::default_random_engine rand_num_gen; /// generator object
206
207 struct {
208 int on = 0;
209 std::vector<Set::Scalar> sitex;
210 std::vector<Set::Scalar> sitey;
211 std::vector<int> phases;
212 std::vector<Set::Scalar> time;
213 std::vector<bool> done;
215
216
217 std::vector<Set::Scalar> sitex; /// list of nucleation site x coordinates
218 std::vector<Set::Scalar> sitey; /// list of nucleation stie y coordinates
219 std::vector<int> phases; /// list of nucleation site phases (up or down)
220
221 const Set::Scalar K_b = 8.617333262145e-5; // eV/K
222};
223}
224}
225
226#endif
#define pp_query_default(...)
Definition ParmParse.H:120
#define TEST(x)
Definition Util.H:25
#define INFO
Definition Util.H:24
int query_if_else(std::string name, TrueAction &&true_action, FalseAction &&false_action, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:862
int queryarr(std::string name, std::vector< T > &value, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:1024
int query_default(std::string name, T &value, T defaultvalue, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:492
static bool InTraversalMode()
Definition ParmParse.cpp:14
int query_required(std::string name, T &value, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:421
std::vector< int > phases
list of nucleation stie y coordinates
void Nucleate(Set::Field< Set::Scalar > &eta_mf, std::vector< amrex::Geometry > &geom, Set::Scalar timestep, Set::Scalar time, int iter)
This operates on an entire field, and manages all of the MPI communication necessary for consistent n...
std::vector< Set::Scalar > sitex
const Set::Scalar K_b
list of nucleation site phases (up or down)
std::uniform_int_distribution< int > int_dist
random number distribution for spatial location
std::vector< Set::Scalar > sitey
list of nucleation site x coordinates
std::default_random_engine rand_num_gen
random number generator for phase
std::uniform_real_distribution< double > unif_dist
static void Parse(Disconnection &value, IO::ParmParse &pp)
struct Model::Defect::Disconnection::@24 fixed
generator object
std::vector< Set::Scalar > time
int finest_level
Definition Set.H:67
amrex::Real Scalar
Definition Base.H:19
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
Definition Base.H:21
int Allgather(std::vector< T > &a_data)
Definition MPI.H:18
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE void Assert(const char *file, const char *func, int line, const char *smt, bool pass, Args const &... args)
Definition Util.H:60
void Message(std::string file, std::string func, int line, Args const &... args)
Definition Util.H:140
void ParmParseException(std::string file, std::string func, int line, std::string fullname, Args const &... args)
Definition Util.H:295