108 (pmesh != NULL) ? pmesh->
FindPoints(point, elem_id_, ip_,
false) : -1;
112 if (pmesh != NULL && pt_found <= 0) {
return false; }
116 if (pt_found > 0 && elem_id_[0] >= 0 && pgf != NULL)
129 int glb_pt_root = -1;
130 MPI_Allreduce(&pt_root, &glb_pt_root, 1,
131 MPI_INT, MPI_MAX, MPI_COMM_WORLD);
134 if (pmesh != NULL && elem_id_[0] >= 0 && glb_pt_root != 0)
137 0, 1030, MPI_COMM_WORLD);
141 if (
Mpi::Root() && pmesh != NULL && glb_pt_root != 0)
145 glb_pt_root, 1030, MPI_COMM_WORLD, &status);
154 : charge_(charge), mass_(mass),
157 E_(3), B_(3), pxB_(3), pm_(3), pp_(3)
167 if (!GetValue(E_pmesh_, E_field_, q, E_)) {
return false; }
168 if (!GetValue(B_pmesh_, B_field_, q, B_)) {
return false; }
174 add(
p, 0.5 * dt * charge_, E_, pm_);
177 const real_t B2 = B_ * B_;
180 const real_t a1 = 4.0 * dt * charge_ * mass_;
185 const real_t a2 = 4.0 * mass_ * mass_ -
186 dt * dt * charge_ * charge_ * B2;
190 const real_t a3 = 2.0 * dt * dt * charge_ * charge_ * (B_ * pm_);
194 const real_t a4 = 4.0 * mass_ * mass_ +
195 dt * dt * charge_ * charge_ * B2;
199 add(pp_, 0.5 * dt * charge_, E_,
p);
202 q.
Add(dt / mass_,
p);
223 int pad_digits_cycle,
int pad_digits_rank,
int cycle,
243int main(
int argc,
char *argv[])
250 const char *E_coll_name =
"";
251 const char *E_field_name =
"E";
253 int E_pad_digits_cycle = 6;
254 int E_pad_digits_rank = 6;
256 const char *B_coll_name =
"";
257 const char *B_field_name =
"B";
259 int B_pad_digits_cycle = 6;
260 int B_pad_digits_rank = 6;
271 bool visualization =
true;
275 args.
AddOption(&E_coll_name,
"-er",
"--e-root-file",
276 "Set the VisIt data collection E field root file prefix.");
277 args.
AddOption(&E_field_name,
"-ef",
"--e-field-name",
278 "Set the VisIt data collection E field name");
279 args.
AddOption(&E_cycle,
"-ec",
"--e-cycle",
280 "Set the E field cycle index to read.");
281 args.
AddOption(&E_pad_digits_cycle,
"-epdc",
"--e-pad-digits-cycle",
282 "Number of digits in E field cycle.");
283 args.
AddOption(&E_pad_digits_rank,
"-epdr",
"--e-pad-digits-rank",
284 "Number of digits in E field MPI rank.");
285 args.
AddOption(&B_coll_name,
"-br",
"--b-root-file",
286 "Set the VisIt data collection B field root file prefix.");
287 args.
AddOption(&B_field_name,
"-bf",
"--b-field-name",
288 "Set the VisIt data collection B field name");
289 args.
AddOption(&B_cycle,
"-bc",
"--b-cycle",
290 "Set the B field cycle index to read.");
291 args.
AddOption(&B_pad_digits_cycle,
"-bpdc",
"--b-pad-digits-cycle",
292 "Number of digits in B field cycle.");
293 args.
AddOption(&B_pad_digits_rank,
"-bpdr",
"--b-pad-digits-rank",
294 "Number of digits in B field MPI rank.");
299 args.
AddOption(&dt,
"-dt",
"--time-step",
301 args.
AddOption(&t_init,
"-ti",
"--initial-time",
303 args.
AddOption(&t_final,
"-tf",
"--final-time",
305 args.
AddOption(&x_init,
"-x0",
"--initial-position",
306 "Initial position.");
307 args.
AddOption(&p_init,
"-p0",
"--initial-momentum",
308 "Initial momentum.");
309 args.
AddOption(&r_factor,
"-rf",
"--ribbon-factor",
310 "Scale factor for ribbon width (rf * (p1-p0) / (m * dt) "
311 "where p0 and p1 are computed momenta).");
312 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
313 "--no-visualization",
314 "Enable or disable GLVis visualization.");
315 args.
AddOption(&visit,
"-visit",
"--visit",
"-no-visit",
"--no-visit",
316 "Enable or disable VisIt visualization.");
317 args.
AddOption(&visport,
"-p",
"--send-port",
"Socket for GLVis.");
339 if (strcmp(E_coll_name,
""))
342 E_pad_digits_rank, E_cycle, E_dc, E_gf))
344 mfem::out <<
"Error loading E field" << endl;
352 if (strcmp(B_coll_name,
""))
355 B_pad_digits_rank, B_cycle, B_dc, B_gf))
357 mfem::out <<
"Error loading B field" << endl;
362 if (x_init.
Size() < 3)
366 if (p_init.
Size() < 3)
368 p_init.
SetSize(3); p_init = 0.0;
376 BorisAlgorithm boris(E_gf, B_gf, q, m);
380 ofstream ofs(
"Lorentz.dat");
383 int nsteps = 1 + (int)ceil((t_final - t_init) / dt);
386 mom_data.
SetCol(0, p_init);
390 mfem::out <<
"Maximum number of steps: " << nsteps << endl;
400 <<
'\t' << pos[0] <<
'\t' << pos[1] <<
'\t' << pos[2]
401 <<
'\t' << mom[0] <<
'\t' << mom[1] <<
'\t' << mom[2]
406 pos_data.
SetCol(step, pos);
407 mom_data.
SetCol(step + 1, mom);
409 while (boris.Step(pos, mom, t, dt) && step < nsteps - 1);
411 if (
Mpi::Root() && (visit || visualization))
419 for (
int i=0; i<step; i++)
421 traj_time[i] = dt * i;
436 traj_sock.precision(8);
441 int Ww = 350,
Wh = 350;
444 traj_time,
"Trajectory",
Wx,
Wy,
Ww,
Wh);
449 mfem::out <<
"Number of steps taken: " << step << endl;
462 <<
" | | ___________ ____ _____/ |_________"
464 <<
" | | / _ \\_ __ \\_/ __ \\ / \\ __\\___ /"
466 <<
" | |__( <_> ) | \\/\\ ___/| | \\ | / / "
468 <<
" |_______ \\____/|__| \\___ >___| /__| /_____ \\"
470 <<
" \\/ \\/ \\/ \\/"
475 int pad_digits_cycle,
int pad_digits_rank,
int cycle,
485 mfem::out <<
"Error loading VisIt data collection: "
486 << coll_name << endl;
492 mfem::out <<
"Field must be defined on a three dimensional mesh"
509 x_init.
SetSize(3); x_init = 0.0;
511 if (E_dc != NULL || B_dc != NULL)
529 for (
int d = 0; d<3; d++)
531 const real_t p_min = std::max(E_p_min[d], B_p_min[d]);
532 const real_t p_max = std::min(E_p_max[d], B_p_max[d]);
533 x_init[d] = 0.5 * (p_min + p_max);
542 Mesh trajectory(2, 2 * (step + 1), step, 0, 3);
544 for (
int i=0; i<=step; i++)
546 trajectory.
AddVertex(pos_data(0,i), pos_data(1,i), pos_data(2,i));
548 real_t dpx = (mom_data(0, i + 1) - mom_data(0, i)) / (m * dt);
549 real_t dpy = (mom_data(1, i + 1) - mom_data(1, i)) / (m * dt);
550 real_t dpz = (mom_data(2, i + 1) - mom_data(2, i)) / (m * dt);
552 trajectory.
AddVertex(pos_data(0,i) + r_factor * dpx,
553 pos_data(1,i) + r_factor * dpy,
554 pos_data(2,i) + r_factor * dpz);
558 for (
int i=0; i<step; i++)
562 v[2] = 2 * (i + 1) + 1;
bool HasField(const std::string &field_name) const
Check if a grid function is part of the collection.
virtual void SetPadDigitsRank(int digits)
Set the number of digits used for the MPI rank in filenames.
int Error() const
Get the current error state.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
ParGridFunction * GetParField(const std::string &field_name)
Get a pointer to a parallel grid function in the collection.
void SetTime(real_t t)
Set physical time (for time-dependent simulations)
Mesh * GetMesh()
Get a pointer to the mesh in the collection.
GFieldMap::MapType FieldMapType
virtual void SetPadDigitsCycle(int digits)
Set the number of digits used for the cycle.
Data type dense matrix using column-major storage.
void SetCol(int c, const real_t *col)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Class for grid function - Vector with associated FE space.
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Arbitrary order "L2-conforming" discontinuous finite elements.
int AddQuad(int v1, int v2, int v3, int v4, int attr=1)
Adds a quadrilateral to the mesh given by 4 vertices v1 through v4.
int AddVertex(real_t x, real_t y=0.0, real_t z=0.0)
int Dimension() const
Dimension of the reference space used within the elements.
void FinalizeQuadMesh(int generate_edges=0, int refine=0, bool fix_orientation=true)
Finalize the construction of a quadrilateral Mesh.
static bool Root()
Return true if the rank in MPI_COMM_WORLD is zero.
static void Init(int &argc, char **&argv, int required=default_thread_required, int *provided=nullptr)
Singleton creation with Mpi::Init(argc, argv).
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
bool Good() const
Return true if the command line options were parsed successfully.
ParMesh * GetParMesh() const
Class for parallel grid function.
ParFiniteElementSpace * ParFESpace() const
void GetVectorValue(int i, const IntegrationPoint &ip, Vector &val) const override
Class for parallel meshes.
int FindPoints(DenseMatrix &point_mat, Array< int > &elem_ids, Array< IntegrationPoint > &ips, bool warn=true, InverseElementTransformation *inv_trans=NULL) override
Find the ids of the elements that contain the given points, and their corresponding reference coordin...
void GetBoundingBox(Vector &p_min, Vector &p_max, int ref=2)
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
Vector & Set(const real_t a, const Vector &x)
(*this) = a * x
int Size() const
Returns the size of the vector.
void SetSize(int s)
Resize the vector to size s.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
void cross3D(const Vector &vin, Vector &vout) const
Data collection with VisIt I/O routines.
void Load(int cycle_=0) override
Load the collection based on its VisIt data (described in its root file)
void Save() override
Save the collection and a VisIt root file.
void RegisterField(const std::string &field_name, GridFunction *gf) override
Add a grid function to the collection and update the root file.
int ReadGridFunction(const char *coll_name, const char *field_name, int pad_digits_cycle, int pad_digits_rank, int cycle, VisItDataCollection *&dc, ParGridFunction *&gf)
DataCollection::FieldMapType fields_t
Mesh MakeTrajectoryMesh(int step, real_t m, real_t dt, real_t r_factor, const DenseMatrix &pos_data, const DenseMatrix &mom_data)
void SetInitialPosition(VisItDataCollection *E_dc, VisItDataCollection *B_dc, Vector &x_init)
void display_banner(ostream &os)
void VisualizeField(socketstream &sock, const char *vishost, int visport, GridFunction &gf, const char *title, int x, int y, int w, int h, const char *keys, bool vec)
real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void add(const Vector &v1, const Vector &v2, Vector &v)
real_t p(const Vector &x, real_t t)
Helper struct to convert a C++ type to an MPI type.