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; }
615 int Ww = 350,
Wh = 350;
619 *e_,
"Electric Field (E)",
Wx,
Wy,
Ww,
Wh);
623 *b_,
"Magnetic Flux Density (B)",
Wx,
Wy,
Ww,
Wh);
634 *j_,
"Current Density (J)",
Wx,
Wy,
Ww,
Wh);
636 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(x,k,t) = k, i.e. k = f(x,t) = G(x,t).
@ IMPLICIT
This is the most general type, no assumptions on F and G.
Type type
Describes the form of the TimeDependentOperator.
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.
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 ImplicitSolve(const real_t dt, const Vector &x, Vector &k)
Solve the equation: k = f(x + dt k, t), for the unknown k at the current time t.
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 Mult(const Vector &B, Vector &dEdt) const
Perform the action of the operator: y = k = f(x, t), where k solves the algebraic equation F(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)