12 #include "../../config/config.hpp"
23 using namespace miniapps;
25 namespace electromagnetics
28 TeslaSolver::TeslaSolver(
ParMesh & pmesh,
int order,
46 hDivHCurlMuInv_(NULL),
57 muInvCoef_(&muInvCoef),
66 MPI_Comm_size(pmesh_->
GetComm(), &num_procs_);
67 MPI_Comm_rank(pmesh_->
GetComm(), &myid_);
82 for (
int i=0; i<kbcs.
Size(); i++)
84 non_k_bdr_[kbcs[i]-1] = 0;
103 if ( j_src_ != NULL )
110 if ( m_src_ != NULL )
134 if ( jCoef_ || kbcs.
Size() > 0 )
145 if ( kbcs.
Size() > 0 )
150 SurfCur_ =
new SurfaceCurrent(*H1FESpace_, *HCurlFESpace_, *Grad_,
183 delete curlMuInvCurl_;
185 delete hDivMassMuInv_;
186 delete hDivHCurlMuInv_;
189 delete HCurlFESpace_;
192 map<string,socketstream*>::iterator mit;
193 for (mit=socks_.begin(); mit!=socks_.end(); mit++)
213 cout <<
"Number of H1 unknowns: " << size_h1 << endl;
214 cout <<
"Number of H(Curl) unknowns: " << size_nd << endl;
215 cout <<
"Number of H(Div) unknowns: " << size_rt << endl;
222 if (myid_ == 0) { cout <<
"Assembling ..." << flush; }
232 if ( hDivMassMuInv_ )
237 if ( hDivHCurlMuInv_ )
243 if (myid_ == 0) { cout <<
" done." << endl; }
249 if (myid_ == 0) { cout <<
"Updating ..." << endl; }
254 H1FESpace_->
Update(
false);
255 HCurlFESpace_->
Update(
false);
256 HDivFESpace_->
Update(
false);
262 if ( j_ ) { j_->
Update(); }
263 if ( k_ ) { k_->
Update(); }
264 if ( m_ ) { m_->
Update(); }
268 if ( hCurlMass_ ) { hCurlMass_->
Update(); }
269 if ( hDivMassMuInv_ ) { hDivMassMuInv_->
Update(); }
270 if ( hDivHCurlMuInv_ ) { hDivHCurlMuInv_->
Update(); }
274 if ( Grad_ ) { Grad_->
Update(); }
275 if ( DivFreeProj_ ) { DivFreeProj_->
Update(); }
276 if ( SurfCur_ ) { SurfCur_->
Update(); }
282 if (myid_ == 0) { cout <<
"Running solver ... " << endl; }
310 MassHCurl->
Mult(*J,*JD);
311 DivFreeProj_->
Mult(*JD, *RHS);
328 MassHDiv->
Mult(*M,*MD);
358 delete CurlMuInvCurl;
374 if (myid_ == 0) { cout <<
"Computing H ... " << flush; }
377 hDivHCurlMuInv_->
Mult(*b_, bd);
380 hDivHCurlMuInv_->
AddMult(*m_, bd, -1.0 * mu0_);
399 if (myid_ == 0) { cout <<
"done." << flush; }
406 if (myid_ == 0) { cout <<
" Solver done. " << endl; }
412 if (myid_ == 0) { cout <<
"Estimating Error ... " << flush; }
425 smooth_flux_fes, flux_fes, errors, norm_p);
427 if (myid_ == 0) { cout <<
"done." << endl; }
433 visit_dc_ = &visit_dc;
449 if (myid_ == 0) { cout <<
"Writing VisIt files ..." << flush; }
456 if (myid_ == 0) { cout <<
" done." << endl; }
463 if ( myid_ == 0 ) { cout <<
"Opening GLVis sockets." << endl; }
466 socks_[
"A"]->precision(8);
469 socks_[
"B"]->precision(8);
472 socks_[
"H"]->precision(8);
477 socks_[
"J"]->precision(8);
482 socks_[
"K"]->precision(8);
485 socks_[
"Psi"]->precision(8);
490 socks_[
"M"]->precision(8);
492 if ( myid_ == 0 ) { cout <<
"GLVis sockets open." << endl; }
498 if (myid_ == 0) { cout <<
"Sending data to GLVis ..." << flush; }
500 char vishost[] =
"localhost";
504 int Ww = 350, Wh = 350;
505 int offx = Ww+10, offy = Wh+45;
508 *a_,
"Vector Potential (A)", Wx, Wy, Ww, Wh);
512 *b_,
"Magnetic Flux Density (B)", Wx, Wy, Ww, Wh);
516 *h_,
"Magnetic Field (H)", Wx, Wy, Ww, Wh);
522 *j_,
"Current Density (J)", Wx, Wy, Ww, Wh);
530 *k_,
"Surface Current Density (K)", Wx, Wy, Ww, Wh);
535 "Surface Current Potential (Psi)", Wx, Wy, Ww, Wh);
541 *m_,
"Magnetization (M)", Wx, Wy, Ww, Wh);
544 if (myid_ == 0) { cout <<
" done." << endl; }
552 : H1FESpace_(&H1FESpace),
553 HCurlFESpace_(&HCurlFESpace),
566 S0_ = s0_->ParallelAssemble();
579 for (
int i=0; i<vbcs_->
Size(); i++)
581 ess_bdr_[(*vbcs_)[i]-1] = 1;
586 for (
int i=0; i<kbcs_->
Size(); i++)
588 non_k_bdr_[(*kbcs_)[i]-1] = 0;
596 for (
int i=0; i<vbcs_->
Size(); i++)
600 vbc_bdr_attr[(*vbcs_)[i]-1] = 1;
608 s0_->ParallelEliminateEssentialBC(ess_bdr_,
628 if (myid_ == 0) { cout <<
"Computing K ... " << flush; }
631 pcg_->
Mult(*RHS_, *PSI_);
634 Grad_->
Mult(*PSI_,*K_);
637 Vector vZero(3); vZero = 0.0;
641 if (myid_ == 0) { cout <<
"done." << endl; }
673 for (
int i=0; i<vbcs_->
Size(); i++)
677 vbc_bdr_attr[(*vbcs_)[i]-1] = 1;
694 #endif // MFEM_USE_MPI
int Size() const
Logical size of the array.
The Auxiliary-space Maxwell Solver in hypre.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
virtual void RegisterField(const char *field_name, GridFunction *gf)
Add a grid function to the collection and update the root file.
Subclass constant coefficient.
Integrator for (curl u, curl v) for Nedelec elements.
virtual void Update(bool want_transform=true)
HYPRE_Int GlobalTrueVSize()
HYPRE_Int MultTranspose(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A^t * x + beta * y.
virtual void Save()
Save the collection and a VisIt root file.
Abstract parallel finite element space.
void GetErrorEstimates(Vector &errors)
void ProjectCoefficient(Coefficient &coeff)
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A * x + beta * y.
void SetPrintLevel(int print_lvl)
ParGridFunction * GetPsi()
The BoomerAMG solver in hypre.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A * x + beta * y.
void VisualizeField(socketstream &sock, const char *vishost, int visport, ParGridFunction &gf, const char *title, int x, int y, int w, int h)
Jacobi preconditioner in hypre.
void SetPrintLevel(int print_level)
Data collection with VisIt I/O routines.
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.
SurfaceCurrent(ParFiniteElementSpace &H1FESpace, ParFiniteElementSpace &HCurlFESpace, ParDiscreteGradOperator &Grad, Array< int > &kbcs, Array< int > &vbcs, Vector &vbcv)
int SpaceDimension() const
Wrapper for hypre's parallel vector class.
Array< int > bdr_attributes
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)
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 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.
Integrator for (Q u, v) for VectorFiniteElements.
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
void ProjectBdrCoefficient(Coefficient &coeff, Array< int > &attr)
void ParallelProject(Vector &tv) const
Returns the vector restricted to the true dofs.