21using namespace common;
 
   23namespace electromagnetics
 
   80   MPI_Comm_size(pmesh_->
GetComm(), &num_procs_);
 
   81   MPI_Comm_rank(pmesh_->
GetComm(), &myid_);
 
   93   lossy_ = abcs.
Size() > 0 || sigma_ != NULL;
 
  105      if ( myid_ == 0 && logging_ > 0 )
 
  107         cout << 
"Creating Permittivity Coefficient" << endl;
 
  113   if ( muInv_ == NULL )
 
  119      if ( myid_ == 0 && logging_ > 0 )
 
  121         cout << 
"Creating Permeability Coefficient" << endl;
 
  127   if ( sigma_ != NULL )
 
  129      if ( myid_ == 0 && logging_ > 0 )
 
  131         cout << 
"Creating Conductivity Coefficient" << endl;
 
  137   if ( abcs.
Size() > 0 )
 
  139      if ( myid_ == 0 && logging_ > 0 )
 
  141         cout << 
"Creating Admittance Coefficient" << endl;
 
  149   if ( dbcs.
Size() > 0 )
 
  151      if ( myid_ == 0 && logging_ > 0 )
 
  153         cout << 
"Configuring Dirichlet BC" << endl;
 
  159      if ( dEdt_bc_ != NULL )
 
  171   if ( myid_ == 0 && logging_ > 0 )
 
  173      cout << 
"Creating H(Div) Mass Operator" << endl;
 
  178   if ( myid_ == 0 && logging_ > 0 )
 
  180      cout << 
"Creating Weak Curl Operator" << endl;
 
  193   if ( sigmaCoef_ || etaInvCoef_ )
 
  195      if ( myid_ == 0 && logging_ > 0 )
 
  197         cout << 
"Creating H(Curl) Loss Operator" << endl;
 
  202         if ( myid_ == 0 && logging_ > 0 )
 
  204            cout << 
"Adding domain integrator for conductive regions" << endl;
 
  211         if ( myid_ == 0 && logging_ > 0 )
 
  213            cout << 
"Adding boundary integrator for absorbing boundary" << endl;
 
  227   if ( myid_ == 0 && logging_ > 0 )
 
  229      cout << 
"Creating discrete curl operator" << endl;
 
  255      if ( myid_ == 0 && logging_ > 0 )
 
  257         cout << 
"Creating Current Source" << endl;
 
 
  297   delete WeakCurlMuInv_;
 
  299   delete hDivMassMuInv_;
 
  301   delete weakCurlMuInv_;
 
  303   delete HCurlFESpace_;
 
  306   map<int, ParBilinearForm*>::iterator mit1;
 
  307   for (mit1=a1_.begin(); mit1!=a1_.end(); mit1++)
 
  311      delete diagScale_[i];
 
  316   map<int, Coefficient*>::iterator mit2;
 
  317   for (mit2=dtCoef_.begin(); mit2!=dtCoef_.end(); mit2++)
 
  321   for (mit2=dtSigmaCoef_.begin(); mit2!=dtSigmaCoef_.end(); mit2++)
 
  325   for (mit2=dtEtaInvCoef_.begin(); mit2!=dtEtaInvCoef_.end(); mit2++)
 
  330   map<string, socketstream*>::iterator mit3;
 
  331   for (mit3=socks_.begin(); mit3!=socks_.end(); mit3++)
 
 
  350      cout << 
"Number of H(Curl) unknowns: " << size_nd << endl;
 
  351      cout << 
"Number of H(Div)  unknowns: " << size_rt << endl << flush;
 
 
  358   eCoef_ = &EFieldCoef;
 
 
  366   bCoef_ = &BFieldCoef;
 
 
  374   implicitSolve(0.0, B, dEdt);
 
 
  380   implicitSolve(dt, B, dEdt);
 
 
  384MaxwellSolver::setupSolver(
const int idt, 
const real_t dt)
 const 
  386   if ( pcg_.find(idt) == pcg_.end() )
 
  388      if ( myid_ == 0 && logging_ > 0 )
 
  390         cout << 
"Creating implicit operator for dt = " << dt << endl;
 
  394      a1_[idt]->AddDomainIntegrator(
 
  405            a1_[idt]->AddDomainIntegrator(
 
  410            dtEtaInvCoef_[idt] = 
new TransformedCoefficient(dtCoef_[idt],
 
  413            a1_[idt]->AddBoundaryIntegrator(
 
  414               new VectorFEMassIntegrator(dtEtaInvCoef_[idt]),
 
  415               const_cast<Array<int>&
>(abc_marker_));
 
  419      a1_[idt]->Assemble();
 
  420      a1_[idt]->Finalize();
 
  421      A1_[idt] = a1_[idt]->ParallelAssemble();
 
  423      diagScale_[idt] = 
new HypreDiagScale(*A1_[idt]);
 
  424      pcg_[idt] = 
new HyprePCG(*A1_[idt]);
 
  425      pcg_[idt]->SetTol(1.0e-12);
 
  426      pcg_[idt]->SetMaxIter(200);
 
  427      pcg_[idt]->SetPrintLevel(0);
 
  428      pcg_[idt]->SetPreconditioner(*diagScale_[idt]);
 
  433MaxwellSolver::implicitSolve(
real_t dt, 
const Vector &B, Vector &dEdt)
 const 
  435   int idt = hCurlLosses_ ? ((int)(dtScale_ * dt / dtMax_)) : 0;
 
  438   weakCurlMuInv_->
Mult(*b_, *rhs_);
 
  443      hCurlLosses_->
AddMult(*e_, *rhs_, -1.0);
 
  457                                          const_cast<Array<int>&
>(dbc_marker_));
 
  461   setupSolver(idt, dt);
 
  464   a1_[idt]->FormLinearSystem(dbc_dofs_, *dedt_, *rhs_, *A1_[idt], dEdt, *RHS_);
 
  467   pcg_[idt]->Mult(*RHS_, dEdt);
 
  470   a1_[idt]->RecoverFEMSolution(dEdt, *rhs_, *dedt_);
 
  494   int iter = 0, nstep = 20;
 
  495   real_t dt0 = 1.0, dt1 = 1.0, change = 1.0, ptol = 0.001;
 
  502   while ( iter < nstep && change > ptol )
 
  507      NegCurl_->
Mult(*v0,*u0);
 
  508      M2MuInv_->
Mult(*u0,*HD_);
 
  511      pcg_[0]->Mult(*RHS_,*v1);
 
  514      dt1 = 2.0/sqrt(lambda);
 
  515      change = fabs((dt1-dt0)/dt0);
 
  518      if ( myid_ == 0 && logging_ > 1 )
 
  520         cout << iter << 
":  " << dt0 << 
" " << change << endl;
 
 
  540   A1_[0]->Mult(*E_,*RHS_);
 
  541   M2MuInv_->
Mult(*B_,*HD_);
 
 
  551   visit_dc_ = &visit_dc;
 
 
  566      if ( myid_ == 0 && logging_ > 1 )
 
  567      { cout << 
"Writing VisIt files ..." << flush; }
 
  579      if ( myid_ == 0 && logging_ > 1 ) { cout << 
" " << endl << flush; }
 
 
  586   if ( myid_ == 0 && logging_ > 0 )
 
  587   { cout << 
"Opening GLVis sockets." << endl << flush; }
 
  590   socks_[
"E"]->precision(8);
 
  593   socks_[
"B"]->precision(8);
 
  598      socks_[
"J"]->precision(8);
 
  601   if ( myid_ == 0 && logging_ > 0 )
 
  602   { cout << 
"GLVis sockets open." << endl << flush; }
 
 
  608   if ( myid_ == 0 && logging_ > 1 )
 
  609   { cout << 
"Sending data to GLVis ..." << flush; }
 
  614   int Ww = 350, 
Wh = 350; 
 
  618                  *e_, 
"Electric Field (E)", 
Wx, 
Wy, 
Ww, 
Wh);
 
  622                  *b_, 
"Magnetic Flux Density (B)", 
Wx, 
Wy, 
Ww, 
Wh);
 
  633                     *j_, 
"Current Density (J)", 
Wx, 
Wy, 
Ww, 
Wh);
 
  635   if ( myid_ == 0 && logging_ > 1 ) { cout << 
" " << flush; }
 
 
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
int Size() const
Return the logical size of the array.
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)
virtual void Assemble(int skip_zeros=1)
Construct the internal matrix representation of the discrete linear operator.
A general function coefficient.
HYPRE_Int MultTranspose(HypreParVector &x, HypreParVector &y, real_t alpha=1.0, real_t beta=0.0) const
Computes y = alpha * A^t * x + beta * y.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, real_t alpha=1.0, real_t beta=0.0) const
Computes y = alpha * A * x + beta * y.
Wrapper for hypre's parallel vector class.
HYPRE_Int Randomize(HYPRE_Int seed)
Set random values.
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 width
Dimension of the input / number of columns in the matrix.
int height
Dimension of the output / number of rows in the matrix.
HypreParMatrix * ParallelAssemble() const
Returns the matrix "assembled" on the true dofs.
void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const override
HYPRE_BigInt GlobalTrueVSize() const
Class for parallel grid function.
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
void ParallelProject(Vector &tv) const
Returns the vector restricted to the true dofs.
void Distribute(const Vector *tv)
void ProjectBdrCoefficientTangent(VectorCoefficient &vcoeff, const Array< int > &bdr_attr) override
Project the tangential components of the given VectorCoefficient on the boundary. Only boundary attri...
Class for parallel meshes.
@ EXPLICIT
This type assumes F(u,k,t) = k.
@ IMPLICIT
This is the most general type, no assumptions on F and G.
Type type
Describes the form of the TimeDependentOperator, see the documentation of Type.
Base class for vector Coefficients that optionally depend on time and space.
virtual void SetTime(real_t t)
Set the time for time dependent coefficients.
Vector coefficient that is constant in space and time.
for VectorFiniteElements (Nedelec, Raviart-Thomas)
A general vector function coefficient.
Data collection with VisIt I/O routines.
void Save() override
Save the collection and a VisIt root file.
void RegisterField(const std::string &field_name, GridFunction *gf) override
Add a grid function to the collection and update the root file.
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k)
Solve for the unknown k, at the current time t, the following equation: F(u + gamma k,...
HYPRE_BigInt GetProblemSize()
real_t GetMaximumTimeStep() const
void WriteVisItFields(int it=0)
void SetInitialEField(VectorCoefficient &EFieldCoef)
void RegisterVisItFields(VisItDataCollection &visit_dc)
MaxwellSolver(ParMesh &pmesh, int sOrder, real_t(*eps)(const Vector &), real_t(*muInv)(const Vector &), real_t(*sigma)(const Vector &), void(*j_src)(const Vector &, real_t, Vector &), Array< int > &abcs, Array< int > &dbcs, void(*dEdt_bc)(const Vector &, real_t, Vector &))
void SetInitialBField(VectorCoefficient &BFieldCoef)
void DisplayToGLVis(int visport=19916)
void Mult(const Vector &B, Vector &dEdt) const
Operator application: y=A(x).
real_t sigma(const Vector &x)
real_t muInv(const Vector &x)
void j_src(const Vector &x, real_t t, Vector &j)
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 prodFunc(real_t a, real_t b)
real_t InnerProduct(HypreParVector *x, HypreParVector *y)