21 using namespace miniapps;
23 namespace electromagnetics
26 TeslaSolver::TeslaSolver(
ParMesh & pmesh,
int order,
43 hDivHCurlMuInv_(NULL),
58 muInvCoef_(&muInvCoef),
67 MPI_Comm_size(pmesh_->
GetComm(), &num_procs_);
68 MPI_Comm_rank(pmesh_->
GetComm(), &myid_);
79 int geom = H1FESpace_->GetFE(0)->GetGeomType();
88 for (
int i=0; i<kbcs.
Size(); i++)
90 non_k_bdr_[kbcs[i]-1] = 0;
109 if ( j_src_ != NULL )
116 if ( m_src_ != NULL )
147 if ( jCoef_ || kbcs.
Size() > 0 )
156 irOrder, NULL, NULL, grad_);
159 if ( kbcs.
Size() > 0 )
200 delete curlMuInvCurl_;
202 delete hDivHCurlMuInv_;
203 delete weakCurlMuInv_;
206 delete HCurlFESpace_;
209 map<string,socketstream*>::iterator mit;
210 for (mit=socks_.begin(); mit!=socks_.end(); mit++)
230 cout <<
"Number of H1 unknowns: " << size_h1 << endl;
231 cout <<
"Number of H(Curl) unknowns: " << size_nd << endl;
232 cout <<
"Number of H(Div) unknowns: " << size_rt << endl;
239 if (myid_ == 0) { cout <<
"Assembling ..." << flush; }
258 if ( weakCurlMuInv_ )
264 if (myid_ == 0) { cout <<
" done." << endl; }
270 if (myid_ == 0) { cout <<
"Updating ..." << endl; }
275 H1FESpace_->
Update(
false);
276 HCurlFESpace_->
Update(
false);
277 HDivFESpace_->
Update(
false);
287 if ( jr_ ) { jr_->
Update(); }
288 if ( j_ ) { j_->
Update(); }
289 if ( k_ ) { k_->
Update(); }
290 if ( m_ ) { m_->
Update(); }
295 hDivHCurlMuInv_->
Update();
296 if ( weakCurlMuInv_ ) { weakCurlMuInv_->
Update(); }
300 if ( grad_ ) { grad_->
Update(); }
301 if ( DivFreeProj_ ) { DivFreeProj_->
Update(); }
302 if ( SurfCur_ ) { SurfCur_->
Update(); }
308 if (myid_ == 0) { cout <<
"Running solver ... " << endl; }
332 DivFreeProj_->
Mult(*jr_, *j_);
335 hCurlMass_->
AddMult(*j_, *jd_);
342 weakCurlMuInv_->
AddMult(*m_, *jd_, mu0_);
356 HypreAMS ams(CurlMuInvCurl, HCurlFESpace_);
374 curl_->
Mult(*a_, *b_);
377 if (myid_ == 0) { cout <<
"Computing H ... " << flush; }
379 hDivHCurlMuInv_->
Mult(*b_, *bd_);
382 hDivHCurlMuInv_->
AddMult(*m_, *bd_, -1.0 * mu0_);
401 if (myid_ == 0) { cout <<
"done." << flush; }
403 if (myid_ == 0) { cout <<
" Solver done. " << endl; }
409 if (myid_ == 0) { cout <<
"Estimating Error ... " << flush; }
422 smooth_flux_fes, flux_fes, errors, norm_p);
424 if (myid_ == 0) { cout <<
"done." << endl; }
430 visit_dc_ = &visit_dc;
446 if (myid_ == 0) { cout <<
"Writing VisIt files ..." << flush; }
453 if (myid_ == 0) { cout <<
" done." << endl; }
460 if ( myid_ == 0 ) { cout <<
"Opening GLVis sockets." << endl; }
463 socks_[
"A"]->precision(8);
466 socks_[
"B"]->precision(8);
469 socks_[
"H"]->precision(8);
474 socks_[
"J"]->precision(8);
479 socks_[
"K"]->precision(8);
482 socks_[
"Psi"]->precision(8);
487 socks_[
"M"]->precision(8);
489 if ( myid_ == 0 ) { cout <<
"GLVis sockets open." << endl; }
495 if (myid_ == 0) { cout <<
"Sending data to GLVis ..." << flush; }
497 char vishost[] =
"localhost";
501 int Ww = 350, Wh = 350;
502 int offx = Ww+10, offy = Wh+45;
505 *a_,
"Vector Potential (A)", Wx, Wy, Ww, Wh);
509 *b_,
"Magnetic Flux Density (B)", Wx, Wy, Ww, Wh);
513 *h_,
"Magnetic Field (H)", Wx, Wy, Ww, Wh);
519 *j_,
"Current Density (J)", Wx, Wy, Ww, Wh);
527 *k_,
"Surface Current Density (K)", Wx, Wy, Ww, Wh);
532 "Surface Current Potential (Psi)", Wx, Wy, Ww, Wh);
538 *m_,
"Magnetization (M)", Wx, Wy, Ww, Wh);
541 if (myid_ == 0) { cout <<
" done." << endl; }
548 : H1FESpace_(&H1FESpace),
568 for (
int i=0; i<vbcs_->
Size(); i++)
570 ess_bdr_[(*vbcs_)[i]-1] = 1;
576 for (
int i=0; i<kbcs_->
Size(); i++)
578 non_k_bdr_[(*kbcs_)[i]-1] = 0;
619 if (myid_ == 0) { cout <<
"Computing K ... " << flush; }
625 for (
int i=0; i<vbcs_->
Size(); i++)
629 vbc_bdr_attr[(*vbcs_)[i]-1] = 1;
638 pcg_->
Mult(RHS_, Psi_);
644 grad_->
Mult(*psi_, k);
647 Vector vZero(3); vZero = 0.0;
651 if (myid_ == 0) { cout <<
"done." << endl; }
657 delete pcg_; pcg_ = NULL;
658 delete amg_; amg_ = NULL;
675 #endif // MFEM_USE_MPI
int Size() const
Logical size of the array.
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
Class for an integration rule - an Array of IntegrationPoint.
The Auxiliary-space Maxwell Solver in hypre.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Subclass constant coefficient.
Integrator for (curl u, curl v) for Nedelec elements.
virtual void Update(bool want_transform=true)
virtual void Save()
Save the collection and a VisIt root file.
Abstract parallel finite element space.
void GetErrorEstimates(Vector &errors)
virtual void ProjectCoefficient(Coefficient &coeff)
void SetPrintLevel(int print_lvl)
ParGridFunction * GetPsi()
The BoomerAMG solver in hypre.
SurfaceCurrent(ParFiniteElementSpace &H1FESpace, ParDiscreteGradOperator &Grad, Array< int > &kbcs, Array< int > &vbcs, Vector &vbcv)
virtual void Update()
Transform by the Space UpdateMatrix (e.g., on Mesh change).
Jacobi preconditioner in hypre.
void SetPrintLevel(int print_level)
Data collection with VisIt I/O routines.
void VisualizeField(socketstream &sock, const char *vishost, int visport, GridFunction &gf, const char *title, int x, int y, int w, int h, bool vec)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
HYPRE_Int GlobalTrueVSize() const
HYPRE_Int GetProblemSize()
void SetTime(double t)
Set physical time (for time-dependent simulations)
void RegisterVisItFields(VisItDataCollection &visit_dc)
void SetMaxIter(int max_iter)
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
int SpaceDimension() const
Wrapper for hypre's parallel vector class.
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i'th element.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Base class Coefficient that may optionally depend on time.
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
double L2ZZErrorEstimator(BilinearFormIntegrator &flux_integrator, const ParGridFunction &x, ParFiniteElementSpace &smooth_flux_fes, ParFiniteElementSpace &flux_fes, Vector &errors, int norm_p, double solver_tol, int solver_max_it)
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection and update the root file.
void WriteVisItFields(int it=0)
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
void ProjectBdrCoefficientTangent(VectorCoefficient &vcoeff, Array< int > &bdr_attr)
void ComputeSurfaceCurrent(ParGridFunction &k)
Arbitrary order H(curl)-conforming Nedelec finite elements.
Class for parallel grid function.
Wrapper for hypre's ParCSR matrix class.
virtual void Assemble(int skip_zeros=1)
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's PCG.
Class for parallel meshes.
void SetSingularProblem()
Set this option when solving a curl-curl problem with zero mass term.
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Integrator for (Q u, v) for VectorFiniteElements.
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
void ProjectBdrCoefficient(Coefficient &coeff, Array< int > &attr)