68 using namespace mfem::electromagnetics;
74 static Vector pw_mu_inv_(0);
75 static Vector ms_params_(0);
81 static Vector cr_params_(0);
87 static Vector bm_params_(0);
91 static Vector ha_params_(0);
98 static Vector b_uniform_(0);
107 int main(
int argc,
char *argv[])
114 const char *mesh_file =
"../../data/ball-nurbs.mesh";
117 int serial_ref_levels = 0;
118 int parallel_ref_levels = 0;
119 bool visualization =
true;
128 args.
AddOption(&mesh_file,
"-m",
"--mesh",
129 "Mesh file to use.");
131 "Finite element order (polynomial degree).");
132 args.
AddOption(&serial_ref_levels,
"-rs",
"--serial-ref-levels",
133 "Number of serial refinement levels.");
134 args.
AddOption(¶llel_ref_levels,
"-rp",
"--parallel-ref-levels",
135 "Number of parallel refinement levels.");
136 args.
AddOption(&b_uniform_,
"-ubbc",
"--uniform-b-bc",
137 "Specify if the three components of the constant magnetic flux density");
138 args.
AddOption(&pw_mu_,
"-pwm",
"--piecewise-mu",
139 "Piecewise values of Permeability");
140 args.
AddOption(&ms_params_,
"-ms",
"--magnetic-shell-params",
141 "Center, Inner Radius, Outer Radius, and Permeability of Magnetic Shell");
142 args.
AddOption(&cr_params_,
"-cr",
"--current-ring-params",
143 "Axis End Points, Inner Radius, Outer Radius and Total Current of Annulus");
144 args.
AddOption(&bm_params_,
"-bm",
"--bar-magnet-params",
145 "Axis End Points, Radius, and Magnetic Field of Cylindrical Magnet");
146 args.
AddOption(&ha_params_,
"-ha",
"--halbach-array-params",
147 "Bounding Box Corners and Number of Segments");
148 args.
AddOption(&kbcs,
"-kbcs",
"--surface-current-bc",
149 "Surfaces for the Surface Current (K) Boundary Condition");
150 args.
AddOption(&vbcs,
"-vbcs",
"--voltage-bc-surf",
151 "Voltage Boundary Condition Surfaces (to drive K)");
152 args.
AddOption(&vbcv,
"-vbcv",
"--voltage-bc-vals",
153 "Voltage Boundary Condition Values (to drive K)");
154 args.
AddOption(&maxit,
"-maxit",
"--max-amr-iterations",
155 "Max number of iterations in the main AMR loop.");
156 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
157 "--no-visualization",
158 "Enable or disable GLVis visualization.");
159 args.
AddOption(&visit,
"-visit",
"--visit",
"-no-visit",
"--no-visit",
160 "Enable or disable VisIt visualization.");
178 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
182 cout <<
"Starting initialization." << endl;
189 if (serial_ref_levels > 0) { serial_ref_levels--; }
199 for (
int l = 0; l < serial_ref_levels; l++)
207 ParMesh pmesh(MPI_COMM_WORLD, *mesh);
211 int par_ref_levels = parallel_ref_levels;
212 for (
int l = 0; l < par_ref_levels; l++)
218 if ( ( vbcs.
Size() > 0 && kbcs.
Size() == 0 ) ||
219 ( kbcs.
Size() > 0 && vbcs.
Size() == 0 ) ||
224 cout <<
"The surface current (K) boundary condition requires "
225 <<
"surface current boundary condition surfaces (with -kbcs), "
226 <<
"voltage boundary condition surface (with -vbcs), "
227 <<
"and voltage boundary condition values (with -vbcv)."
237 TeslaSolver Tesla(pmesh, order, kbcs, vbcs, vbcv, *muInvCoef,
256 if (mpi.
Root()) { cout <<
"Initialization done." << endl; }
263 const int max_dofs = 10000000;
264 for (
int it = 1; it <= maxit; it++)
268 cout <<
"\nAMR Iteration " << it << endl;
297 cout <<
"AMR iteration " << it <<
" complete." << endl;
301 if (prob_size > max_dofs)
305 cout <<
"Reached maximum number of dofs, exiting..." << endl;
312 if (mpi.
Root() && (it % 10 == 0))
314 cout <<
"press (q)uit or (c)ontinue --> " << flush;
317 MPI_Bcast(&c, 1, MPI_CHAR, 0, MPI_COMM_WORLD);
328 double local_max_err = errors.Max();
329 double global_max_err;
330 MPI_Allreduce(&local_max_err, &global_max_err, 1,
331 MPI_DOUBLE, MPI_MAX, pmesh.
GetComm());
335 const double frac = 0.5;
336 double threshold = frac * global_max_err;
337 if (mpi.
Root()) { cout <<
"Refining ..." << endl; }
345 if (mpi.
Root()) { cout <<
"Rebalancing ..." << endl; }
359 os <<
" ___________ __ " << endl
360 <<
" \\__ ___/___ _____| | _____ " << endl
361 <<
" | |_/ __ \\ / ___/ | \\__ \\ " << endl
362 <<
" | |\\ ___/ \\___ \\| |__/ __ \\_ " << endl
363 <<
" |____| \\___ >____ >____(____ / " << endl
364 <<
" \\/ \\/ \\/ " << endl << flush;
374 if ( ms_params_.
Size() > 0 )
378 else if ( pw_mu_.
Size() > 0 )
381 for (
int i = 0; i < pw_mu_.
Size(); i++)
383 MFEM_ASSERT( pw_mu_[i] > 0.0,
"permeability values must be positive" );
384 pw_mu_inv_[i] = 1.0/pw_mu_[i];
403 for (
int i = 0; i < x.
Size(); i++)
405 r2 += (x(i) - ms_params_(i))*(x(i) - ms_params_(i));
408 if ( sqrt(r2) >= ms_params_(x.
Size()) &&
409 sqrt(r2) <= ms_params_(x.
Size()+1) )
411 return mu0_*ms_params_(x.
Size()+2);
420 MFEM_ASSERT(x.
Size() == 3,
"current_ring source requires 3D space.");
431 for (
int i=0; i<x.
Size(); i++)
433 xu[i] -= cr_params_[i];
434 a[i] = cr_params_[x.
Size()+i] - cr_params_[i];
444 double ra = cr_params_[2*x.
Size()+0];
445 double rb = cr_params_[2*x.
Size()+1];
461 if ( xa >= 0.0 && xa <= h*h && xp >= ra && xp <= rb )
463 ju(0) = a(1) * xu(2) - a(2) * xu(1);
464 ju(1) = a(2) * xu(0) - a(0) * xu(2);
465 ju(2) = a(0) * xu(1) - a(1) * xu(0);
468 j.
Add(cr_params_[2*x.
Size()+2]/(h*(rb-ra)),ju);
485 for (
int i=0; i<x.
Size(); i++)
487 xu[i] -= bm_params_[i];
488 a[i] = bm_params_[x.
Size()+i] - bm_params_[i];
498 double r = bm_params_[2*x.
Size()];
508 if ( xa >= 0.0 && xa <= h*h && xp <= r )
510 m.
Add(bm_params_[2*x.
Size()+1]/h,a);
523 if ( x[0] < ha_params_[0] || x[0] > ha_params_[3] ||
524 x[1] < ha_params_[1] || x[1] > ha_params_[4] ||
525 x[2] < ha_params_[2] || x[2] > ha_params_[5] )
530 int ai = (int)ha_params_[6];
531 int ri = (int)ha_params_[7];
532 int n = (int)ha_params_[8];
534 int i = (int)n * (x[ai] - ha_params_[ai]) /
535 (ha_params_[ai+3] - ha_params_[ai]);
537 m[(ri + 1 + (i % 2)) % 3] = pow(-1.0,i/2);
545 a(0) = b_uniform_(1) * x(2);
546 a(1) = b_uniform_(2) * x(0);
547 a(2) = b_uniform_(0) * x(1);
554 return -x(x.
Size()-1);
int Size() const
Logical size of the array.
Subclass constant coefficient.
double magnetic_shell(const Vector &)
void SetSize(int s)
Resize the vector if the new size is different.
double Norml2() const
Returns the l2 norm of the vector.
int Size() const
Returns the size of the vector.
void bar_magnet(const Vector &, Vector &)
int GetNE() const
Returns number of elements.
void GetErrorEstimates(Vector &errors)
int main(int argc, char *argv[])
double phi_m_bc_uniform(const Vector &x)
void Rebalance()
Load balance the mesh. NC meshes only.
bool Nonconforming() const
A simple convenience class that calls MPI_Init() at construction and MPI_Finalize() at destruction...
double magnetic_shell_inv(const Vector &x)
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
void current_ring(const Vector &, Vector &)
Data collection with VisIt I/O routines.
void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1)
bool Root() const
Return true if WorldRank() == 0.
HYPRE_Int GetProblemSize()
void PrintUsage(std::ostream &out) const
void RegisterVisItFields(VisItDataCollection &visit_dc)
Base class Coefficient that may optionally depend on time.
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)
bool RefineByError(const Array< double > &elem_error, double threshold, int nonconforming=-1, int nc_limit=0)
void a_bc_uniform(const Vector &, Vector &)
NURBSExtension * NURBSext
class for piecewise constant coefficient
Vector & Add(const double a, const Vector &Va)
(*this) += a * Va
void WriteVisItFields(int it=0)
Coefficient * SetupInvPermeabilityCoefficient()
void PrintOptions(std::ostream &out) const
void display_banner(ostream &os)
void EnsureNCMesh(bool triangles_nonconforming=false)
class for C-function coefficient
Class for parallel meshes.
void halbach_array(const Vector &, Vector &)