20using namespace common;
22namespace electromagnetics
70 rho_src_func_(rho_src),
72 point_charge_params_(point_charges),
76 MPI_Comm_size(pmesh_->
GetComm(), &num_procs_);
77 MPI_Comm_rank(pmesh_->
GetComm(), &myid_);
93 if ( phi_bc_func_ != NULL )
99 if ( rho_src_func_ != NULL )
105 if ( p_src_func_ != NULL )
139 if ( point_charge_params_.
Size() > 0 )
142 int npts = point_charge_params_.
Size() / (
dim + 1);
143 point_charges_.resize(npts);
146 for (
int i=0; i<npts; i++)
148 for (
int d=0; d<
dim; d++)
150 cent[d] = point_charge_params_[(
dim + 1) * i + d];
155 point_charges_[i]->SetScale(
s);
156 point_charges_[i]->SetDeltaCenter(cent);
181 if ( nbcs_->
Size() > 0 )
214 delete hCurlHDivEps_;
219 delete HCurlFESpace_;
223 for (
unsigned int i=0; i<point_charges_.size(); i++)
225 delete point_charges_[i];
228 map<string,socketstream*>::iterator mit;
229 for (mit=socks_.begin(); mit!=socks_.end(); mit++)
250 cout <<
"Number of H1 unknowns: " << size_h1 << endl;
251 cout <<
"Number of H(Curl) unknowns: " << size_nd << endl;
252 cout <<
"Number of H(Div) unknowns: " << size_rt << endl;
253 cout <<
"Number of L2 unknowns: " << size_l2 << endl;
259 if (myid_ == 0) { cout <<
"Assembling ... " << flush; }
303 if (myid_ == 0) { cout <<
"done." << endl << flush; }
309 if (myid_ == 0) { cout <<
"Updating ..." << endl; }
314 H1FESpace_->
Update(
false);
315 HCurlFESpace_->
Update(
false);
316 HDivFESpace_->
Update(
false);
317 L2FESpace_->
Update(
false);
327 if ( rho_src_ ) { rho_src_->
Update(); }
328 if ( sigma_src_ ) { sigma_src_->
Update(); }
329 if ( p_src_ ) { p_src_->
Update(); }
336 if ( h1Mass_ ) { h1Mass_->
Update(); }
337 if ( h1SurfMass_ ) { h1SurfMass_->
Update(); }
338 if ( hCurlHDiv_ ) { hCurlHDiv_->
Update(); }
339 if ( weakDiv_ ) { weakDiv_->
Update(); }
349 if (myid_ == 0) { cout <<
"Running solver ... " << endl; }
354 if ( dbcs_->
Size() > 0 )
365 for (
int i=0; i<dbcs_->
Size(); i++)
369 if ((*dbcs_)[i] <= dbc_bdr_attr.
Size())
371 dbc_bdr_attr[(*dbcs_)[i]-1] = 1;
382 h1Mass_->
AddMult(*rho_src_, *rhod_);
389 weakDiv_->
AddMult(*p_src_, *rhod_);
398 for (
int i=0; i<nbcs_->
Size(); i++)
402 if ((*nbcs_)[i] <= nbc_bdr_attr.
Size())
404 nbc_bdr_attr[(*nbcs_)[i]-1] = 1;
408 h1SurfMass_->
AddMult(*sigma_src_, *rhod_);
412 if ( dbcs_->
Size() > 0 )
423 ess_bdr_tdofs_[0] = 0;
453 grad_->
Mult(*phi_, *e_); *e_ *= -1.0;
456 if (myid_ == 0) { cout <<
"Computing D ..." << flush; }
459 hCurlHDivEps_->
Mult(*e_, ed);
462 hCurlHDiv_->
AddMult(*p_src_, ed, -1.0);
482 div_->
Mult(*d_, *rho_);
484 if (myid_ == 0) { cout <<
"done." << flush; }
488 real_t charge_rho = (*l2_vol_int_)(*rho_);
491 real_t charge_D = (*rt_surf_int_)(*d_);
495 cout << endl <<
"Total charge: \n"
496 <<
" Volume integral of charge density: " << charge_rho
497 <<
"\n Surface integral of dielectric flux: " << charge_D
502 if (myid_ == 0) { cout <<
"Solver done. " << endl; }
508 if (myid_ == 0) { cout <<
"Estimating Error ... " << flush; }
522 smooth_flux_fes, flux_fes, errors, norm_p);
524 if (myid_ == 0) { cout <<
"done." << endl; }
530 visit_dc_ = &visit_dc;
536 if ( rho_src_ ) { visit_dc.
RegisterField(
"Rho Source", rho_src_); }
537 if ( p_src_ ) { visit_dc.
RegisterField(
"P Source", p_src_); }
538 if ( sigma_src_ ) { visit_dc.
RegisterField(
"Sigma Source", sigma_src_); }
546 if (myid_ == 0) { cout <<
"Writing VisIt files ..." << flush; }
553 if (myid_ == 0) { cout <<
" done." << endl; }
560 if ( myid_ == 0 ) { cout <<
"Opening GLVis sockets." << endl; }
563 socks_[
"Phi"]->precision(8);
566 socks_[
"D"]->precision(8);
569 socks_[
"E"]->precision(8);
572 socks_[
"Rho"]->precision(8);
577 socks_[
"RhoSrc"]->precision(8);
582 socks_[
"PSrc"]->precision(8);
587 socks_[
"SigmaSrc"]->precision(8);
594 if (myid_ == 0) { cout <<
"Sending data to GLVis ..." << flush; }
600 int Ww = 350,
Wh = 350;
604 *phi_,
"Electric Potential (Phi)",
Wx,
Wy,
Ww,
Wh);
608 *e_,
"Electric Field (E)",
Wx,
Wy,
Ww,
Wh);
612 *d_,
"Electric Displacement (D)",
Wx,
Wy,
Ww,
Wh);
616 *rho_,
"Charge Density",
Wx,
Wy,
Ww,
Wh);
622 *rho_src_,
"Charge Density Source (Rho)",
Wx,
Wy,
Ww,
Wh);
628 *p_src_,
"Electric Polarization Source (P)",
635 *sigma_src_,
"Surface Charge Density Source (Sigma)",
639 if (myid_ == 0) { cout <<
" done." << endl; }
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
A coefficient that is constant across space and time.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetTime(real_t t)
Set physical time (for time-dependent simulations)
Delta function coefficient optionally multiplied by a weight coefficient and a scaled time dependent ...
virtual void Assemble(int skip_zeros=1)
Construct the internal matrix representation of the discrete linear operator.
Class for domain integration .
A general function coefficient.
The BoomerAMG solver in hypre.
Jacobi preconditioner in hypre.
void SetPrintLevel(int print_lvl)
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's PCG.
void SetMaxIter(int max_iter)
Wrapper for hypre's ParCSR matrix class.
Wrapper for hypre's parallel vector class.
Arbitrary order "L2-conforming" discontinuous finite elements.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
int Dimension() const
Dimension of the reference space used within the elements.
int SpaceDimension() const
Dimension of the physical space containing the mesh.
Abstract parallel finite element space.
void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const override
HYPRE_BigInt GlobalTrueVSize() const
void Update(bool want_transform=true) override
Class for parallel grid function.
void ProjectBdrCoefficient(Coefficient *coeff[], VectorCoefficient *vcoeff, const Array< int > &attr)
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
void Update() override
Transform by the Space UpdateMatrix (e.g., on Mesh change).
Class for parallel meshes.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
A general vector function coefficient.
int Size() const
Returns the size of the vector.
Data collection with VisIt I/O routines.
virtual void Save() override
Save the collection and a VisIt root file.
virtual void RegisterField(const std::string &field_name, GridFunction *gf) override
Add a grid function to the collection and update the root file.
void RegisterVisItFields(VisItDataCollection &visit_dc)
VoltaSolver(ParMesh &pmesh, int order, Array< int > &dbcs, Vector &dbcv, Array< int > &nbcs, Vector &nbcv, Coefficient &epsCoef, real_t(*phi_bc)(const Vector &), real_t(*rho_src)(const Vector &), void(*p_src)(const Vector &, Vector &), Vector &point_charges)
void WriteVisItFields(int it=0)
void GetErrorEstimates(Vector &errors)
HYPRE_BigInt GetProblemSize()
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)
void AttrToMarker(int max_attr, const Array< int > &attrs, Array< int > &marker)
Convert a set of attribute numbers to a marker array.
real_t L2ZZErrorEstimator(BilinearFormIntegrator &flux_integrator, const ParGridFunction &x, ParFiniteElementSpace &smooth_flux_fes, ParFiniteElementSpace &flux_fes, Vector &errors, int norm_p, real_t solver_tol, int solver_max_it)