64 using namespace mfem::electromagnetics;
67 static Vector ms_params_(0);
73 static Vector cr_params_(0);
79 static Vector bm_params_(0);
84 static Vector b_uniform_(0);
93 int main(
int argc,
char *argv[])
97 MPI_Init(&argc, &argv);
98 MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
99 MPI_Comm_rank(MPI_COMM_WORLD, &myid);
104 const char *mesh_file =
"butterfly_3d.mesh";
107 bool visualization =
true;
116 args.
AddOption(&mesh_file,
"-m",
"--mesh",
117 "Mesh file to use.");
119 "Finite element order (polynomial degree).");
120 args.
AddOption(&sr,
"-rs",
"--serial-ref-levels",
121 "Number of serial refinement levels.");
122 args.
AddOption(&pr,
"-rp",
"--parallel-ref-levels",
123 "Number of parallel refinement levels.");
124 args.
AddOption(&b_uniform_,
"-ubbc",
"--uniform-b-bc",
125 "Specify if the three components of the constant magnetic flux density");
126 args.
AddOption(&ms_params_,
"-ms",
"--magnetic-shell-params",
127 "Center, Inner Radius, Outer Radius, and Permeability of Magnetic Shell");
128 args.
AddOption(&cr_params_,
"-cr",
"--current-ring-params",
129 "Axis End Points, Inner Radius, Outer Radius and Total Current of Annulus");
130 args.
AddOption(&bm_params_,
"-bm",
"--bar-magnet-params",
131 "Axis End Points, Radius, and Magnetic Field of Cylindrical Magnet");
132 args.
AddOption(&kbcs,
"-kbcs",
"--surface-current-bc",
133 "Surfaces for the Surface Current (K) Boundary Condition");
134 args.
AddOption(&vbcs,
"-vbcs",
"--voltage-bc-surf",
135 "Voltage Boundary Condition Surfaces (to drive K)");
136 args.
AddOption(&vbcv,
"-vbcv",
"--voltage-bc-vals",
137 "Voltage Boundary Condition Values (to drive K)");
138 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
139 "--no-visualization",
140 "Enable or disable GLVis visualization.");
141 args.
AddOption(&visit,
"-visit",
"--visit",
"-no-visit",
"--no-visit",
142 "Enable or disable VisIt visualization.");
162 ifstream imesh(mesh_file);
167 cerr <<
"\nCan not open mesh file: " << mesh_file <<
'\n' << endl;
172 mesh =
new Mesh(imesh, 1, 1);
178 if (myid == 0) { cout <<
"Starting initialization." << endl; }
181 if (mesh->
NURBSext && ref_levels < 2)
185 for (
int l = 0; l < ref_levels; l++)
202 ParMesh pmesh(MPI_COMM_WORLD, *mesh);
206 int par_ref_levels = pr;
207 for (
int l = 0; l < par_ref_levels; l++)
213 if ( ( vbcs.
Size() > 0 && kbcs.
Size() == 0 ) ||
214 ( kbcs.
Size() > 0 && vbcs.
Size() == 0 ) ||
219 cout <<
"The surface current (K) boundary condition requires "
220 <<
"surface current boundary condition surfaces (with -kbcs), "
221 <<
"voltage boundary condition surface (with -vbcs), "
222 <<
"and voltage boundary condition values (with -vbcv)."
249 if (myid == 0) { cout <<
"Initialization done." << endl; }
256 const int max_dofs = 10000000;
257 for (
int it = 1; it <= 100; it++)
261 cout <<
"\nAMR Iteration " << it << endl;
284 if (myid == 0 && (visit || visualization)) { cout <<
"done." << endl; }
288 cout <<
"AMR iteration " << it <<
" complete." << endl;
292 if (prob_size > max_dofs)
296 cout <<
"Reached maximum number of dofs, exiting..." << endl;
303 if (myid == 0 && (it % 10 == 0))
305 cout <<
"press (q)uit or (c)ontinue --> " << flush;
308 MPI_Bcast(&c, 1, MPI_CHAR, 0, MPI_COMM_WORLD);
319 double local_max_err = errors.Max();
320 double global_max_err;
321 MPI_Allreduce(&local_max_err, &global_max_err, 1,
322 MPI_DOUBLE, MPI_MAX, pmesh.
GetComm());
327 const double frac = 0.5;
328 double threshold = frac * global_max_err;
329 for (
int i = 0; i < errors.Size(); i++)
331 if (errors[i] >= threshold) { ref_list.
Append(i); }
337 if (myid == 0) { cout <<
" Refinement ..." << flush; }
352 os <<
" ___________ __ " << endl
353 <<
" \\__ ___/___ _____| | _____ " << endl
354 <<
" | |_/ __ \\ / ___/ | \\__ \\ " << endl
355 <<
" | |\\ ___/ \\___ \\| |__/ __ \\_ " << endl
356 <<
" |____| \\___ >____ >____(____ / " << endl
357 <<
" \\/ \\/ \\/ " << endl << flush;
367 for (
int i=0; i<x.
Size(); i++)
369 r2 += (x(i)-ms_params_(i))*(x(i)-ms_params_(i));
372 if ( sqrt(r2) >= ms_params_(x.
Size()) &&
373 sqrt(r2) <= ms_params_(x.
Size()+1) )
375 return mu0_*ms_params_(x.
Size()+2);
384 MFEM_ASSERT(x.
Size() == 3,
"current_ring source requires 3D space.");
395 for (
int i=0; i<x.
Size(); i++)
397 xu[i] -= cr_params_[i];
398 a[i] = cr_params_[x.
Size()+i] - cr_params_[i];
408 double ra = cr_params_[2*x.
Size()+0];
409 double rb = cr_params_[2*x.
Size()+1];
425 if ( xa >= 0.0 && xa <= h*h && xp >= ra && xp <= rb )
427 ju(0) = a(1) * xu(2) - a(2) * xu(1);
428 ju(1) = a(2) * xu(0) - a(0) * xu(2);
429 ju(2) = a(0) * xu(1) - a(1) * xu(0);
432 j.
Add(cr_params_[2*x.
Size()+2]/(h*(rb-ra)),ju);
449 for (
int i=0; i<x.
Size(); i++)
451 xu[i] -= bm_params_[i];
452 a[i] = bm_params_[x.
Size()+i] - bm_params_[i];
462 double r = bm_params_[2*x.
Size()];
472 if ( xa >= 0.0 && xa <= h*h && xp <= r )
474 m.
Add(bm_params_[2*x.
Size()+1]/h,a);
483 a(0) = b_uniform_(1) * x(2);
484 a(1) = b_uniform_(2) * x(0);
485 a(2) = b_uniform_(0) * x(1);
492 return -x(x.
Size()-1);
int Size() const
Logical size of the array.
double magnetic_shell(const Vector &)
double muInv(const Vector &x)
void SetSize(int s)
Resizes 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)
double phi_m_bc_uniform(const Vector &x)
int Append(const T &el)
Append element to array, resize if necessary.
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)
HYPRE_Int GetProblemSize()
void PrintUsage(std::ostream &out) const
void RegisterVisItFields(VisItDataCollection &visit_dc)
int main(int argc, char *argv[])
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)
void a_bc_uniform(const Vector &, Vector &)
NURBSExtension * NURBSext
Vector & Add(const double a, const Vector &Va)
(*this) += a * Va
void WriteVisItFields(int it=0)
void PrintOptions(std::ostream &out) const
void display_banner(ostream &os)
void GeneralRefinement(const Array< Refinement > &refinements, int nonconforming=-1, int nc_limit=0)
Class for parallel meshes.