MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
lorentz.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11//
12// -----------------------------------------------------
13// Lorentz Miniapp: Simple Lorentz Force Particle Mover
14// -----------------------------------------------------
15//
16// This miniapp computes the trajectory of a single charged particle subject to
17// Lorentz forces.
18//
19// dp/dt = q (E + v x B)
20//
21// The method used is the explicit Boris algortihm which conserves phase space
22// volume for long term accuracy.
23//
24// The electric and magnetic fields are read from VisItDataCollection objects
25// such as those produced by the Volta and Tesla miniapps. It is notable that
26// these two fields do not need to be defined on the same mesh. Of course, the
27// particle trajectory can only be computed on the intersection of the two
28// domains. The starting point of the path must be chosen within in this
29// intersection and the trajectory will terminate when it leaves the
30// intersection or reaches a specified time duration.
31//
32// Note that the VisItDataCollection objects must have been stored using the
33// parallel format e.g. visit_dc.SetFormat(DataCollection::PARALLEL_FORMAT);.
34// Without this optional format specifier the vector field lookups will fail.
35//
36// Compile with: make lorentz
37//
38// Sample runs:
39//
40// Free particle moving with constant velocity
41// mpirun -np 4 lorentz -p0 '1 1 1'
42//
43// Particle accelerating in a constant electric field
44// mpirun -np 4 volta -m ../../data/inline-hex.mesh -dbcs '1 6' -dbcv '0 1'
45// mpirun -np 4 lorentz -er Volta-AMR-Parallel -x0 '0.5 0.5 0.9' -p0 '1 0 0'
46//
47// Particle accelerating in a constant magnetic field
48// mpirun -np 4 tesla -m ../../data/inline-hex.mesh -ubbc '0 0 1'
49// mpirun -np 4 lorentz -br Tesla-AMR-Parallel -x0 '0.1 0.5 0.1' -p0 '0 0.4 0.1' -tf 9
50//
51// Magnetic mirror effect near a charged sphere and a bar magnet
52// mpirun -np 4 volta -m ../../data/ball-nurbs.mesh -dbcs 1 -cs '0 0 0 0.1 2e-11' -rs 2 -maxit 4
53// mpirun -np 4 tesla -m ../../data/fichera.mesh -maxit 4 -rs 3 -bm '-0.1 -0.1 -0.1 0.1 0.1 0.1 0.1 -1e10'
54// mpirun -np 4 lorentz -er Volta-AMR-Parallel -ec 4 -br Tesla-AMR-Parallel -bc 4 -x0 '0.8 0 0' -p0 '-8 -4 4' -q -10 -tf 0.2 -dt 1e-3 -rf 1e-6
55//
56// This miniapp demonstrates the use of the ParMesh::FindPoints functionality
57// to evaluate field data from stored DataCollection objects. While this
58// miniapp is far from a full particle-in-cell (PIC) code it does demonstrate
59// some of the building blocks that might be used to construct the particle
60// mover portion of a PIC code.
61
62#include "mfem.hpp"
65#include "electromagnetics.hpp"
66#include <fstream>
67#include <iostream>
68
69using namespace std;
70using namespace mfem;
71using namespace mfem::common;
72using namespace mfem::electromagnetics;
73
75
76/// This class implements the Boris algorithm as described in the
77/// article `Why is Boris algorithm so good?` by H. Qin et al in
78/// Physics of Plasmas, Volume 20 Issue 8, August 2013,
79/// https://doi.org/10.1063/1.4818428.
80class BorisAlgorithm
81{
82private:
83 real_t charge_;
84 real_t mass_;
85
86 ParMesh *E_pmesh_;
87 ParGridFunction *E_field_;
88
89 ParMesh *B_pmesh_;
90 ParGridFunction *B_field_;
91
92 mutable Array<int> elem_id_;
93 mutable Array<IntegrationPoint> ip_;
94
95 mutable Vector E_;
96 mutable Vector B_;
97 mutable Vector pxB_;
98 mutable Vector pm_;
99 mutable Vector pp_;
100
101 // Returns true if a usable V has been found. If @a pgf is NULL, V = 0 is
102 // returned as a default value.
103 bool GetValue(ParMesh *pmesh, ParGridFunction *pgf, Vector q, Vector &V)
104 {
105 DenseMatrix point(q.GetData(), 3, 1);
106
107 int pt_found =
108 (pmesh != NULL) ? pmesh->FindPoints(point, elem_id_, ip_, false) : -1;
109
110 // We have a mesh but the point was not found. The path must be outside
111 // the domain of interest.
112 if (pmesh != NULL && pt_found <= 0) { return false; }
113
114 int pt_root = -1;
115
116 if (pt_found > 0 && elem_id_[0] >= 0 && pgf != NULL)
117 {
118 pt_root = pmesh->GetMyRank();
119
120 pgf->GetVectorValue(elem_id_[0], ip_[0], V);
121 }
122 else
123 {
124 pt_root = 0;
125 V = 0.0;
126 }
127
128 // Determine processor which found the field point
129 int glb_pt_root = -1;
130 MPI_Allreduce(&pt_root, &glb_pt_root, 1,
131 MPI_INT, MPI_MAX, MPI_COMM_WORLD);
132
133 // Send the field value to the root processor
134 if (pmesh != NULL && elem_id_[0] >= 0 && glb_pt_root != 0)
135 {
136 MPI_Send(V.GetData(), 3, MPITypeMap<real_t>::mpi_type,
137 0, 1030, MPI_COMM_WORLD);
138 }
139
140 // Receive the field value on the root processor
141 if (Mpi::Root() && pmesh != NULL && glb_pt_root != 0)
142 {
143 MPI_Status status;
144 MPI_Recv(V.GetData(), 3, MPITypeMap<real_t>::mpi_type,
145 glb_pt_root, 1030, MPI_COMM_WORLD, &status);
146 }
147 return true;
148 }
149
150public:
151 BorisAlgorithm(ParGridFunction *E_gf,
152 ParGridFunction *B_gf,
153 real_t charge, real_t mass)
154 : charge_(charge), mass_(mass),
155 E_field_(E_gf),
156 B_field_(B_gf),
157 E_(3), B_(3), pxB_(3), pm_(3), pp_(3)
158 {
159 E_pmesh_ = (E_field_) ? E_field_->ParFESpace()->GetParMesh() : NULL;
160 B_pmesh_ = (B_field_) ? B_field_->ParFESpace()->GetParMesh() : NULL;
161 }
162
163 bool Step(Vector &q, Vector &p, real_t &t, real_t &dt)
164 {
165 // Locate current point in each mesh, evaluate the fields, and collect
166 // field values on the root processor.
167 if (!GetValue(E_pmesh_, E_field_, q, E_)) { return false; }
168 if (!GetValue(B_pmesh_, B_field_, q, B_)) { return false; }
169
170 // Compute updated position and momentum using the Boris algorithm
171 if (Mpi::Root())
172 {
173 // Compute half of the contribution from q E
174 add(p, 0.5 * dt * charge_, E_, pm_);
175
176 // Compute the contributiobn from q p x B
177 const real_t B2 = B_ * B_;
178
179 // ... along pm x B
180 const real_t a1 = 4.0 * dt * charge_ * mass_;
181 pm_.cross3D(B_, pxB_);
182 pp_.Set(a1, pxB_);
183
184 // ... along pm
185 const real_t a2 = 4.0 * mass_ * mass_ -
186 dt * dt * charge_ * charge_ * B2;
187 pp_.Add(a2, pm_);
188
189 // ... along B
190 const real_t a3 = 2.0 * dt * dt * charge_ * charge_ * (B_ * pm_);
191 pp_.Add(a3, B_);
192
193 // scale by common denominator
194 const real_t a4 = 4.0 * mass_ * mass_ +
195 dt * dt * charge_ * charge_ * B2;
196 pp_ /= a4;
197
198 // Update the momentum
199 add(pp_, 0.5 * dt * charge_, E_, p);
200
201 // Update the position
202 q.Add(dt / mass_, p);
203 }
204
205 // Update the time
206 t += dt;
207
208 // Broadcast the updated position
209 MPI_Bcast(q.GetData(), 3, MPITypeMap<real_t>::mpi_type,
210 0, MPI_COMM_WORLD);
211
212 // Broadcast the updated momentum
213 MPI_Bcast(p.GetData(), 3, MPITypeMap<real_t>::mpi_type,
214 0, MPI_COMM_WORLD);
215
216 return true;
217 }
218};
219
220// Open the named VisItDataCollection and read the named field.
221// Returns pointers to the two new objects.
222int ReadGridFunction(const char * coll_name, const char * field_name,
223 int pad_digits_cycle, int pad_digits_rank, int cycle,
225
226// By default the initial position will be the center of the intersection
227// of the bounding boxes of the meshes containing the E and B fields.
230 Vector &x_init);
231
232// Build a quadrilateral mesh approximating the trajectory as a
233// ribbon. One edge of the ribbon follows the trajectory of the
234// particle. The opposite edge is offset by the acceleration vector
235// (scaled by a constant called the r_factor).
236Mesh MakeTrajectoryMesh(int step, real_t m, real_t dt, real_t r_factor,
237 const DenseMatrix &pos_data,
238 const DenseMatrix &mom_data);
239
240// Prints the program's logo to the given output stream
241void display_banner(ostream & os);
242
243int main(int argc, char *argv[])
244{
245 Mpi::Init(argc, argv);
246 Hypre::Init();
247
248 if ( Mpi::Root() ) { display_banner(cout); }
249
250 const char *E_coll_name = "";
251 const char *E_field_name = "E";
252 int E_cycle = 10;
253 int E_pad_digits_cycle = 6;
254 int E_pad_digits_rank = 6;
255
256 const char *B_coll_name = "";
257 const char *B_field_name = "B";
258 int B_cycle = 10;
259 int B_pad_digits_cycle = 6;
260 int B_pad_digits_rank = 6;
261
262 real_t q = 1.0;
263 real_t m = 1.0;
264 real_t dt = 1e-2;
265 real_t t_init = 0.0;
266 real_t t_final = 1.0;
267 real_t r_factor = -1.0;
268 Vector x_init;
269 Vector p_init;
270 int visport = 19916;
271 bool visualization = true;
272 bool visit = true;
273
274 OptionsParser args(argc, argv);
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.");
295 args.AddOption(&q, "-q", "--charge",
296 "Particle charge.");
297 args.AddOption(&m, "-m", "--mass",
298 "Particle mass.");
299 args.AddOption(&dt, "-dt", "--time-step",
300 "Time Step.");
301 args.AddOption(&t_init, "-ti", "--initial-time",
302 "Initial Time.");
303 args.AddOption(&t_final, "-tf", "--final-time",
304 "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.");
318 args.Parse();
319 if (!args.Good())
320 {
321 if (Mpi::Root())
322 {
323 args.PrintUsage(cout);
324 }
325 return 1;
326 }
327 if (r_factor <= 0.0)
328 {
329 r_factor = dt;
330 }
331 if (Mpi::Root())
332 {
333 args.PrintOptions(cout);
334 }
335
336 VisItDataCollection *E_dc = NULL;
337 ParGridFunction *E_gf = NULL;
338
339 if (strcmp(E_coll_name, ""))
340 {
341 if (ReadGridFunction(E_coll_name, E_field_name, E_pad_digits_cycle,
342 E_pad_digits_rank, E_cycle, E_dc, E_gf))
343 {
344 mfem::out << "Error loading E field" << endl;
345 return 1;
346 }
347 }
348
349 VisItDataCollection *B_dc = NULL;
350 ParGridFunction *B_gf = NULL;
351
352 if (strcmp(B_coll_name, ""))
353 {
354 if (ReadGridFunction(B_coll_name, B_field_name, B_pad_digits_cycle,
355 B_pad_digits_rank, B_cycle, B_dc, B_gf))
356 {
357 mfem::out << "Error loading B field" << endl;
358 return 1;
359 }
360 }
361
362 if (x_init.Size() < 3)
363 {
364 SetInitialPosition(E_dc, B_dc, x_init);
365 }
366 if (p_init.Size() < 3)
367 {
368 p_init.SetSize(3); p_init = 0.0;
369 }
370 if (Mpi::Root())
371 {
372 mfem::out << "Initial position: "; x_init.Print(mfem::out);
373 mfem::out << "Initial momentum: "; p_init.Print(mfem::out);
374 }
375
376 BorisAlgorithm boris(E_gf, B_gf, q, m);
377 Vector pos(x_init);
378 Vector mom(p_init);
379
380 ofstream ofs("Lorentz.dat");
381 ofs.precision(14);
382
383 int nsteps = 1 + (int)ceil((t_final - t_init) / dt);
384 DenseMatrix pos_data(3, nsteps);
385 DenseMatrix mom_data(3, nsteps + 1);
386 mom_data.SetCol(0, p_init);
387
388 if (Mpi::Root())
389 {
390 mfem::out << "Maximum number of steps: " << nsteps << endl;
391 }
392
393 int step = -1;
394 real_t t = t_init;
395 do
396 {
397 if (Mpi::Root())
398 {
399 ofs << t
400 << '\t' << pos[0] << '\t' << pos[1] << '\t' << pos[2]
401 << '\t' << mom[0] << '\t' << mom[1] << '\t' << mom[2]
402 << '\n';
403 }
404 step++;
405
406 pos_data.SetCol(step, pos);
407 mom_data.SetCol(step + 1, mom);
408 }
409 while (boris.Step(pos, mom, t, dt) && step < nsteps - 1);
410
411 if (Mpi::Root() && (visit || visualization))
412 {
413 Mesh trajectory = MakeTrajectoryMesh(step, m, dt, r_factor,
414 pos_data, mom_data);
415
416 L2_FECollection fec_l2(0, 2);
417 FiniteElementSpace fes_l2(&trajectory, &fec_l2);
418 GridFunction traj_time(&fes_l2);
419 for (int i=0; i<step; i++)
420 {
421 traj_time[i] = dt * i;
422 }
423
424 if (visit)
425 {
426 VisItDataCollection visit_dc("Lorentz", &trajectory);
427 visit_dc.RegisterField("Time", &traj_time);
428 visit_dc.SetCycle(step);
429 visit_dc.SetTime(step * dt);
430 visit_dc.Save();
431 }
432
433 if (visualization)
434 {
435 socketstream traj_sock;
436 traj_sock.precision(8);
437
438 char vishost[] = "localhost";
439
440 int Wx = 0, Wy = 0; // window position
441 int Ww = 350, Wh = 350; // window size
442
443 VisualizeField(traj_sock, vishost, visport,
444 traj_time, "Trajectory", Wx, Wy, Ww, Wh);
445 }
446 }
447 if (Mpi::Root())
448 {
449 mfem::out << "Number of steps taken: " << step << endl;
450 }
451
452 // Clean up
453 delete E_dc;
454 delete B_dc;
455}
456
457// Print the Lorentz ascii logo to the given ostream
458void display_banner(ostream & os)
459{
460 os << " ____ __ "
461 << endl
462 << " | | ___________ ____ _____/ |_________"
463 << endl
464 << " | | / _ \\_ __ \\_/ __ \\ / \\ __\\___ /"
465 << endl
466 << " | |__( <_> ) | \\/\\ ___/| | \\ | / / "
467 << endl
468 << " |_______ \\____/|__| \\___ >___| /__| /_____ \\"
469 << endl
470 << " \\/ \\/ \\/ \\/"
471 << endl << flush;
472}
473
474int ReadGridFunction(const char * coll_name, const char * field_name,
475 int pad_digits_cycle, int pad_digits_rank, int cycle,
477{
478 dc = new VisItDataCollection(MPI_COMM_WORLD, coll_name);
479 dc->SetPadDigitsCycle(pad_digits_cycle);
480 dc->SetPadDigitsRank(pad_digits_rank);
481 dc->Load(cycle);
482
483 if (dc->Error() != DataCollection::No_Error)
484 {
485 mfem::out << "Error loading VisIt data collection: "
486 << coll_name << endl;
487 return 1;
488 }
489
490 if (dc->GetMesh()->Dimension() < 3)
491 {
492 mfem::out << "Field must be defined on a three dimensional mesh"
493 << endl;
494 return 1;
495 }
496
497 if (dc->HasField(field_name))
498 {
499 gf = dc->GetParField(field_name);
500 }
501
502 return 0;
503}
504
507 Vector &x_init)
508{
509 x_init.SetSize(3); x_init = 0.0;
510
511 if (E_dc != NULL || B_dc != NULL)
512 {
513 Vector E_p_min(3); E_p_min = -infinity();
514 Vector E_p_max(3); E_p_max = infinity();
515 if (E_dc != NULL)
516 {
517 ParMesh * E_pmesh = dynamic_cast<ParMesh*>(E_dc->GetMesh());
518 E_pmesh->GetBoundingBox(E_p_min, E_p_max);
519 }
520
521 Vector B_p_min(3); B_p_min = -infinity();
522 Vector B_p_max(3); B_p_max = infinity();
523 if (B_dc != NULL)
524 {
525 ParMesh *B_pmesh = dynamic_cast<ParMesh*>(B_dc->GetMesh());
526 B_pmesh->GetBoundingBox(B_p_min, B_p_max);
527 }
528
529 for (int d = 0; d<3; d++)
530 {
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);
534 }
535 }
536}
537
538Mesh MakeTrajectoryMesh(int step, real_t m, real_t dt, real_t r_factor,
539 const DenseMatrix &pos_data,
540 const DenseMatrix &mom_data)
541{
542 Mesh trajectory(2, 2 * (step + 1), step, 0, 3);
543
544 for (int i=0; i<=step; i++)
545 {
546 trajectory.AddVertex(pos_data(0,i), pos_data(1,i), pos_data(2,i));
547
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);
551
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);
555 }
556
557 int v[4];
558 for (int i=0; i<step; i++)
559 {
560 v[0] = 2 * i;
561 v[1] = 2 * (i + 1);
562 v[2] = 2 * (i + 1) + 1;
563 v[3] = 2 * i + 1;
564
565 trajectory.AddQuad(v);
566 }
567
568 trajectory.FinalizeQuadMesh(1);
569
570 return trajectory;
571}
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.
Definition densemat.hpp:24
void SetCol(int c, const real_t *col)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:208
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:32
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Definition hypre.cpp:33
Arbitrary order "L2-conforming" discontinuous finite elements.
Definition fe_coll.hpp:350
Mesh data type.
Definition mesh.hpp:65
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.
Definition mesh.cpp:2085
int AddVertex(real_t x, real_t y=0.0, real_t z=0.0)
Definition mesh.cpp:2000
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1306
void FinalizeQuadMesh(int generate_edges=0, int refine=0, bool fix_orientation=true)
Finalize the construction of a quadrilateral Mesh.
Definition mesh.cpp:2531
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...
Definition optparser.hpp:82
bool Good() const
Return true if the command line options were parsed successfully.
ParMesh * GetParMesh() const
Definition pfespace.hpp:341
Class for parallel grid function.
Definition pgridfunc.hpp:50
ParFiniteElementSpace * ParFESpace() const
void GetVectorValue(int i, const IntegrationPoint &ip, Vector &val) const override
Class for parallel meshes.
Definition pmesh.hpp:34
int GetMyRank() const
Definition pmesh.hpp:407
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...
Definition pmesh.cpp:6493
void GetBoundingBox(Vector &p_min, Vector &p_max, int ref=2)
Definition pmesh.cpp:6181
Vector data type.
Definition vector.hpp:82
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
Definition vector.cpp:870
Vector & Set(const real_t a, const Vector &x)
(*this) = a * x
Definition vector.cpp:341
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:584
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
Definition vector.hpp:243
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
Definition vector.cpp:326
void cross3D(const Vector &vin, Vector &vout) const
Definition vector.cpp:639
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 main()
int Ww
int Wy
int Wx
int Wh
int ReadGridFunction(const char *coll_name, const char *field_name, int pad_digits_cycle, int pad_digits_rank, int cycle, VisItDataCollection *&dc, ParGridFunction *&gf)
Definition lorentz.cpp:474
DataCollection::FieldMapType fields_t
Definition lorentz.cpp:74
Mesh MakeTrajectoryMesh(int step, real_t m, real_t dt, real_t r_factor, const DenseMatrix &pos_data, const DenseMatrix &mom_data)
Definition lorentz.cpp:538
void SetInitialPosition(VisItDataCollection *E_dc, VisItDataCollection *B_dc, Vector &x_init)
Definition lorentz.cpp:505
void display_banner(ostream &os)
Definition lorentz.cpp:458
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()
Definition vector.hpp:47
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition vector.cpp:414
float real_t
Definition config.hpp:46
const char vishost[]
real_t p(const Vector &x, real_t t)
Helper struct to convert a C++ type to an MPI type.