MFEM  v3.1
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
volta_solver.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 #include "../../config/config.hpp"
13 
14 #ifdef MFEM_USE_MPI
15 
16 #include "volta_solver.hpp"
17 
18 using namespace std;
19 namespace mfem
20 {
21 using namespace miniapps;
22 
23 namespace electromagnetics
24 {
25 
26 VoltaSolver::VoltaSolver(ParMesh & pmesh, int order,
27  Array<int> & dbcs, Vector & dbcv,
28  Array<int> & nbcs, Vector & nbcv,
29  double (*eps )(const Vector&),
30  double (*phi_bc )(const Vector&),
31  double (*rho_src)(const Vector&),
32  void (*p_src )(const Vector&, Vector&))
33  : myid_(0),
34  num_procs_(1),
35  order_(order),
36  pmesh_(&pmesh),
37  dbcs_(&dbcs),
38  dbcv_(&dbcv),
39  nbcs_(&nbcs),
40  nbcv_(&nbcv),
41  visit_dc_(NULL),
42  H1FESpace_(NULL),
43  HCurlFESpace_(NULL),
44  HDivFESpace_(NULL),
45  divEpsGrad_(NULL),
46  h1Mass_(NULL),
47  h1SurfMass_(NULL),
48  hCurlMass_(NULL),
49  hDivMass_(NULL),
50  hCurlHDivEps_(NULL),
51  hCurlHDiv_(NULL),
52  Grad_(NULL),
53  phi_(NULL),
54  rho_(NULL),
55  sigma_(NULL),
56  e_(NULL),
57  d_(NULL),
58  p_(NULL),
59  epsCoef_(NULL),
60  phiBCCoef_(NULL),
61  rhoCoef_(NULL),
62  pCoef_(NULL),
63  eps_(eps),
64  phi_bc_(phi_bc),
65  rho_src_(rho_src),
66  p_src_(p_src)
67 {
68  // Initialize MPI variables
69  MPI_Comm_size(pmesh_->GetComm(), &num_procs_);
70  MPI_Comm_rank(pmesh_->GetComm(), &myid_);
71 
72  // Define compatible parallel finite element spaces on the parallel
73  // mesh. Here we use arbitrary order H1, Nedelec, and Raviart-Thomas finite
74  // elements.
75  H1FESpace_ = new H1_ParFESpace(pmesh_,order,pmesh_->Dimension());
76  HCurlFESpace_ = new ND_ParFESpace(pmesh_,order,pmesh_->Dimension());
77  HDivFESpace_ = new RT_ParFESpace(pmesh_,order,pmesh_->Dimension());
78 
79  // Select surface attributes for Dirichlet BCs
80  ess_bdr_.SetSize(pmesh.bdr_attributes.Max());
81  ess_bdr_ = 0; // Deselect all outer surfaces
82  for (int i=0; i<dbcs_->Size(); i++)
83  {
84  ess_bdr_[(*dbcs_)[i]-1] = 1;
85  }
86 
87  // Setup various coefficients
88 
89  // Potential on outer surface
90  if ( phi_bc_ != NULL )
91  {
92  phiBCCoef_ = new FunctionCoefficient(*phi_bc_);
93  }
94 
95  // Permittivity Coefficient
96  if ( eps_ == NULL )
97  {
98  epsCoef_ = new ConstantCoefficient(epsilon0_);
99  }
100  else
101  {
102  epsCoef_ = new FunctionCoefficient(eps_);
103  }
104 
105  // Volume Charge Density
106  if ( rho_src_ != NULL )
107  {
108  rhoCoef_ = new FunctionCoefficient(rho_src_);
109  }
110 
111  // Polarization
112  if ( p_src_ != NULL )
113  {
114  pCoef_ = new VectorFunctionCoefficient(pmesh_->SpaceDimension(),
115  p_src_);
116  }
117 
118  // Bilinear Forms
119  divEpsGrad_ = new ParBilinearForm(H1FESpace_);
120  divEpsGrad_->AddDomainIntegrator(new DiffusionIntegrator(*epsCoef_));
121 
122  hDivMass_ = new ParBilinearForm(HDivFESpace_);
124 
125  hCurlHDivEps_ = new ParMixedBilinearForm(HCurlFESpace_,HDivFESpace_);
126  hCurlHDivEps_->AddDomainIntegrator(new VectorFEMassIntegrator(*epsCoef_));
127 
128  // Assemble Matrices
129  divEpsGrad_->Assemble();
130  divEpsGrad_->Finalize();
131 
132  hDivMass_->Assemble();
133  hDivMass_->Finalize();
134 
135  hCurlHDivEps_->Assemble();
136  hCurlHDivEps_->Finalize();
137 
138  // Discrete Grad operator
139  Grad_ = new ParDiscreteGradOperator(H1FESpace_, HCurlFESpace_);
140 
141  // Build grid functions
142  phi_ = new ParGridFunction(H1FESpace_);
143  d_ = new ParGridFunction(HDivFESpace_);
144  e_ = new ParGridFunction(HCurlFESpace_);
145 
146  if ( rho_src_ )
147  {
148  rho_ = new ParGridFunction(H1FESpace_);
149 
150  h1Mass_ = new ParBilinearForm(H1FESpace_);
151  h1Mass_->AddDomainIntegrator(new MassIntegrator);
152  h1Mass_->Assemble();
153  h1Mass_->Finalize();
154  }
155 
156  if ( p_src_ )
157  {
158  p_ = new ParGridFunction(HCurlFESpace_);
159 
160  hCurlMass_ = new ParBilinearForm(HCurlFESpace_);
162  hCurlMass_->Assemble();
163  hCurlMass_->Finalize();
164 
165  hCurlHDiv_ = new ParMixedBilinearForm(HCurlFESpace_, HDivFESpace_);
167  hCurlHDiv_->Assemble();
168  hCurlHDiv_->Finalize();
169  }
170 
171  if ( nbcs_->Size() > 0 )
172  {
173  sigma_ = new ParGridFunction(H1FESpace_);
174 
175  h1SurfMass_ = new ParBilinearForm(H1FESpace_);
176  h1SurfMass_->AddBoundaryIntegrator(new MassIntegrator);
177  h1SurfMass_->Assemble();
178  h1SurfMass_->Finalize();
179  }
180 }
181 
183 {
184  delete epsCoef_;
185  delete phiBCCoef_;
186  delete rhoCoef_;
187  delete pCoef_;
188 
189  delete phi_;
190  delete rho_;
191  delete sigma_;
192  delete d_;
193  delete e_;
194  delete p_;
195 
196  delete Grad_;
197 
198  delete divEpsGrad_;
199  delete h1Mass_;
200  delete h1SurfMass_;
201  delete hCurlMass_;
202  delete hDivMass_;
203  delete hCurlHDivEps_;
204  delete hCurlHDiv_;
205 
206  delete H1FESpace_;
207  delete HCurlFESpace_;
208 
209  map<string,socketstream*>::iterator mit;
210  for (mit=socks_.begin(); mit!=socks_.end(); mit++)
211  {
212  delete mit->second;
213  }
214 }
215 
216 HYPRE_Int
218 {
219  return H1FESpace_->GlobalTrueVSize();
220 }
221 
222 void
224 {
225  HYPRE_Int size_h1 = H1FESpace_->GlobalTrueVSize();
226  HYPRE_Int size_nd = HCurlFESpace_->GlobalTrueVSize();
227  HYPRE_Int size_rt = HDivFESpace_->GlobalTrueVSize();
228  if (myid_ == 0)
229  {
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;
233  }
234 }
235 
236 void
238 {
239  if (myid_ == 0) { cout << " Assembly ... " << flush; }
240 
241  // Inform the spaces that the mesh has changed
242  H1FESpace_->Update();
243  HCurlFESpace_->Update();
244  HDivFESpace_->Update();
245 
246  // Inform the grid functions that the space has changed.
247  phi_->Update();
248  d_->Update();
249  e_->Update();
250  if ( rho_ ) { rho_->Update(); }
251  if ( sigma_ ) { sigma_->Update(); }
252  if ( p_ ) { p_->Update(); }
253 
254  // Inform the bilinear forms that the space has changed.
255  divEpsGrad_->Update();
256  divEpsGrad_->Assemble();
257  divEpsGrad_->Finalize();
258 
259  hDivMass_->Update();
260  hDivMass_->Assemble();
261  hDivMass_->Finalize();
262 
263  hCurlHDivEps_->Update();
264  hCurlHDivEps_->Assemble();
265  hCurlHDivEps_->Finalize();
266 
267  if ( h1Mass_ )
268  {
269  h1Mass_->Update();
270  h1Mass_->Assemble();
271  h1Mass_->Finalize();
272  }
273 
274  if ( h1SurfMass_ )
275  {
276  h1SurfMass_->Update();
277  h1SurfMass_->Assemble();
278  h1SurfMass_->Finalize();
279  }
280 
281  if ( hCurlMass_ )
282  {
283  hCurlMass_->Update();
284  hCurlMass_->Assemble();
285  hCurlMass_->Finalize();
286  }
287 
288  if ( hCurlHDiv_ )
289  {
290  hCurlHDiv_->Update();
291  hCurlHDiv_->Assemble();
292  hCurlHDiv_->Finalize();
293  }
294 
295  // Inform the other objects that the space has changed.
296  Grad_->Update();
297 
298  if (myid_ == 0) { cout << "done." << flush; }
299 }
300 
301 void
303 {
304  if (myid_ == 0) { cout << "Running solver ... " << endl << flush; }
305 
306  // Initialize the electric potential with its boundary conditions
307  *phi_ = 0.0;
308 
309  if ( dbcs_->Size() > 0 )
310  {
311  if ( phiBCCoef_ )
312  {
313  // Apply gradient boundary condition
314  phi_->ProjectBdrCoefficient(*phiBCCoef_, ess_bdr_);
315  }
316  else
317  {
318  // Apply piecewise constant boundary condition
319  Array<int> dbc_bdr_attr(pmesh_->bdr_attributes.Max());
320  for (int i=0; i<dbcs_->Size(); i++)
321  {
322  ConstantCoefficient voltage((*dbcv_)[i]);
323  dbc_bdr_attr = 0;
324  dbc_bdr_attr[(*dbcs_)[i]-1] = 1;
325  phi_->ProjectBdrCoefficient(voltage, dbc_bdr_attr);
326  }
327  }
328  }
329 
330  // Initialize the RHS vector
331  HypreParVector *RHS = new HypreParVector(H1FESpace_);
332  *RHS = 0.0;
333 
334  // Initialize the volumetric charge density
335  if ( rho_ )
336  {
337  rho_->ProjectCoefficient(*rhoCoef_);
338 
339  HypreParMatrix *MassH1 = h1Mass_->ParallelAssemble();
340  HypreParVector *Rho = rho_->ParallelProject();
341 
342  MassH1->Mult(*Rho,*RHS);
343 
344  delete MassH1;
345  delete Rho;
346  }
347 
348  // Initialize the Polarization
349  HypreParVector *P = NULL;
350  if ( p_ )
351  {
352  p_->ProjectCoefficient(*pCoef_);
353  P = p_->ParallelProject();
354 
355  HypreParMatrix *MassHCurl = hCurlMass_->ParallelAssemble();
356  HypreParVector *PD = new HypreParVector(HCurlFESpace_);
357 
358  MassHCurl->Mult(*P,*PD);
359  Grad_->MultTranspose(*PD,*RHS,-1.0,1.0);
360 
361  delete MassHCurl;
362  delete PD;
363 
364  }
365 
366  // Initialize the surface charge density
367  if ( sigma_ )
368  {
369  *sigma_ = 0.0;
370 
371  Array<int> nbc_bdr_attr(pmesh_->bdr_attributes.Max());
372  for (int i=0; i<nbcs_->Size(); i++)
373  {
374  ConstantCoefficient sigma_coef((*nbcv_)[i]);
375  nbc_bdr_attr = 0;
376  nbc_bdr_attr[(*nbcs_)[i]-1] = 1;
377  sigma_->ProjectBdrCoefficient(sigma_coef, nbc_bdr_attr);
378  }
379 
380  HypreParMatrix *MassS = h1SurfMass_->ParallelAssemble();
381  HypreParVector *Sigma = sigma_->ParallelProject();
382 
383  MassS->Mult(*Sigma,*RHS,1.0,1.0);
384 
385  delete MassS;
386  delete Sigma;
387  }
388 
389  // Apply Dirichlet BCs to matrix and right hand side
390  HypreParMatrix *DivEpsGrad = divEpsGrad_->ParallelAssemble();
391  HypreParVector *Phi = phi_->ParallelProject();
392 
393  // Apply the boundary conditions to the assembled matrix and vectors
394  if ( dbcs_->Size() > 0 )
395  {
396  // According to the selected surfaces
397  divEpsGrad_->ParallelEliminateEssentialBC(ess_bdr_,
398  *DivEpsGrad,
399  *Phi, *RHS);
400  }
401  else
402  {
403  // No surfaces were labeled as Dirichlet so eliminate one DoF
404  Array<int> dof_list(0);
405  if ( myid_ == 0 )
406  {
407  dof_list.SetSize(1);
408  dof_list[0] = 0;
409  }
410  DivEpsGrad->EliminateRowsCols(dof_list, *Phi, *RHS);
411  }
412 
413  // Define and apply a parallel PCG solver for AX=B with the AMG
414  // preconditioner from hypre.
415  HypreSolver *amg = new HypreBoomerAMG(*DivEpsGrad);
416  HyprePCG *pcg = new HyprePCG(*DivEpsGrad);
417  pcg->SetTol(1e-12);
418  pcg->SetMaxIter(500);
419  pcg->SetPrintLevel(2);
420  pcg->SetPreconditioner(*amg);
421  pcg->Mult(*RHS, *Phi);
422 
423  delete amg;
424  delete pcg;
425  delete DivEpsGrad;
426  delete RHS;
427 
428  // Extract the parallel grid function corresponding to the finite
429  // element approximation Phi. This is the local solution on each
430  // processor.
431  *phi_ = *Phi;
432 
433  // Compute the negative Gradient of the solution vector. This is
434  // the magnetic field corresponding to the scalar potential
435  // represented by phi.
436  HypreParVector *E = new HypreParVector(HCurlFESpace_);
437  Grad_->Mult(*Phi,*E,-1.0);
438  *e_ = *E;
439 
440  delete Phi;
441 
442  // Compute electric displacement (D) from E and P
443  if (myid_ == 0) { cout << "Computing D ... " << flush; }
444 
445  HypreParMatrix *HCurlHDivEps = hCurlHDivEps_->ParallelAssemble();
446  HypreParVector *ED = new HypreParVector(HDivFESpace_);
447  HypreParVector *D = new HypreParVector(HDivFESpace_);
448 
449  HCurlHDivEps->Mult(*E,*ED);
450 
451  if ( P )
452  {
453  HypreParMatrix *HCurlHDiv = hCurlHDiv_->ParallelAssemble();
454  HCurlHDiv->Mult(*P,*ED,-1.0,1.0);
455  delete HCurlHDiv;
456  }
457 
458  HypreParMatrix * MassHDiv = hDivMass_->ParallelAssemble();
459 
460  HyprePCG * pcgM = new HyprePCG(*MassHDiv);
461  pcgM->SetTol(1e-12);
462  pcgM->SetMaxIter(500);
463  pcgM->SetPrintLevel(0);
464  HypreDiagScale *diagM = new HypreDiagScale;
465  pcgM->SetPreconditioner(*diagM);
466  pcgM->Mult(*ED,*D);
467 
468  *d_ = *D;
469 
470  if (myid_ == 0) { cout << "done." << flush; }
471 
472  delete diagM;
473  delete pcgM;
474  delete HCurlHDivEps;
475  delete MassHDiv;
476  delete E;
477  delete ED;
478  delete D;
479  delete P;
480 
481  if (myid_ == 0) { cout << " Solver done. " << flush; }
482 }
483 
484 void
486 {
487  if (myid_ == 0) { cout << "Estimating Error ... " << flush; }
488 
489  // Space for the discontinuous (original) flux
490  DiffusionIntegrator flux_integrator(*epsCoef_);
491  L2_FECollection flux_fec(order_, pmesh_->Dimension());
492  // ND_FECollection flux_fec(order_, pmesh_->Dimension());
493  ParFiniteElementSpace flux_fes(pmesh_, &flux_fec, pmesh_->SpaceDimension());
494 
495  // Space for the smoothed (conforming) flux
496  double norm_p = 1;
497  RT_FECollection smooth_flux_fec(order_-1, pmesh_->Dimension());
498  ParFiniteElementSpace smooth_flux_fes(pmesh_, &smooth_flux_fec);
499 
500  L2ZZErrorEstimator(flux_integrator, *phi_,
501  smooth_flux_fes, flux_fes, errors, norm_p);
502 
503  if (myid_ == 0) { cout << "done." << flush; }
504 }
505 
506 void
508 {
509  visit_dc_ = &visit_dc;
510 
511  visit_dc.RegisterField("Phi", phi_);
512  visit_dc.RegisterField("D", d_);
513  visit_dc.RegisterField("E", e_);
514  if ( rho_ ) { visit_dc.RegisterField("Rho", rho_); }
515  if ( p_ ) { visit_dc.RegisterField("P", p_); }
516  if ( sigma_ ) { visit_dc.RegisterField("Sigma", sigma_); }
517 }
518 
519 void
521 {
522  if ( visit_dc_ )
523  {
524  if (myid_ == 0) { cout << "Writing VisIt files ..." << flush; }
525 
526  HYPRE_Int prob_size = this->GetProblemSize();
527  visit_dc_->SetCycle(it);
528  visit_dc_->SetTime(prob_size);
529  visit_dc_->Save();
530 
531  if (myid_ == 0) { cout << " " << flush; }
532  }
533 }
534 
535 void
537 {
538  if ( myid_ == 0 ) { cout << "Opening GLVis sockets." << endl << flush; }
539 
540  socks_["Phi"] = new socketstream;
541  socks_["Phi"]->precision(8);
542 
543  socks_["D"] = new socketstream;
544  socks_["D"]->precision(8);
545 
546  socks_["E"] = new socketstream;
547  socks_["E"]->precision(8);
548 
549  if ( rho_)
550  {
551  socks_["Rho"] = new socketstream;
552  socks_["Rho"]->precision(8);
553  }
554  if ( p_)
555  {
556  socks_["P"] = new socketstream;
557  socks_["P"]->precision(8);
558  }
559  if ( sigma_)
560  {
561  socks_["Sigma"] = new socketstream;
562  socks_["Sigma"]->precision(8);
563  }
564  if ( myid_ == 0 ) { cout << "GLVis sockets open." << endl << flush; }
565 }
566 
567 void
569 {
570  if (myid_ == 0) { cout << "Sending data to GLVis ..." << flush; }
571 
572  char vishost[] = "localhost";
573  int visport = 19916;
574 
575  int Wx = 0, Wy = 0; // window position
576  int Ww = 350, Wh = 350; // window size
577  int offx = Ww+10, offy = Wh+45; // window offsets
578 
579  VisualizeField(*socks_["Phi"], vishost, visport,
580  *phi_, "Electric Potential (Phi)", Wx, Wy, Ww, Wh);
581  Wx += offx;
582 
583  VisualizeField(*socks_["D"], vishost, visport,
584  *d_, "Electric Displacement (D)", Wx, Wy, Ww, Wh);
585  Wx += offx;
586 
587  VisualizeField(*socks_["E"], vishost, visport,
588  *e_, "Electric Field (E)", Wx, Wy, Ww, Wh);
589 
590  Wx = 0; Wy += offy; // next line
591 
592  if ( rho_ )
593  {
594  VisualizeField(*socks_["Rho"], vishost, visport,
595  *rho_, "Charge Density (Rho)", Wx, Wy, Ww, Wh);
596  Wx += offx;
597  }
598  if ( p_ )
599  {
600  VisualizeField(*socks_["P"], vishost, visport,
601  *p_, "Electric Polarization (P)", Wx, Wy, Ww, Wh);
602  Wx += offx;
603  }
604  if ( sigma_ )
605  {
606  VisualizeField(*socks_["Sigma"], vishost, visport,
607  *sigma_, "Surface Charge Density (Sigma)", Wx, Wy, Ww, Wh);
608  Wx += offx;
609  }
610  if (myid_ == 0) { cout << " " << flush; }
611 }
612 
613 } // namespace electromagnetics
614 
615 } // namespace mfem
616 
617 #endif // MFEM_USE_MPI
void SetTol(double tol)
Definition: hypre.cpp:1917
int Size() const
Logical size of the array.
Definition: array.hpp:109
void EliminateRowsCols(const Array< int > &rows_cols, const HypreParVector &X, HypreParVector &B)
Definition: hypre.cpp:1213
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.
Definition: coefficient.hpp:57
HYPRE_Int MultTranspose(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A^t * x + beta * y.
Definition: pfem_extras.cpp:98
virtual void Save()
Save the collection and a VisIt root file.
Abstract parallel finite element space.
Definition: pfespace.hpp:28
void RegisterVisItFields(VisItDataCollection &visit_dc)
void ProjectCoefficient(Coefficient &coeff)
Definition: pgridfunc.cpp:241
virtual void Finalize(int skip_zeros=1)
Finalizes the matrix initialization.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A * x + beta * y.
Definition: hypre.cpp:903
void SetPrintLevel(int print_lvl)
Definition: hypre.cpp:1932
HypreParMatrix * ParallelAssemble()
Returns the matrix assembled on the true dofs, i.e. P^t A P.
virtual void Update(FiniteElementSpace *nfes=NULL)
void GetErrorEstimates(Vector &errors)
HypreParMatrix * ParallelAssemble()
Returns the matrix assembled on the true dofs, i.e. P^t A P.
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
The BoomerAMG solver in hypre.
Definition: hypre.hpp:698
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A * x + beta * y.
Definition: pfem_extras.cpp:82
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.
Definition: hypre.hpp:659
Data collection with VisIt I/O routines.
void L2ZZErrorEstimator(BilinearFormIntegrator &flux_integrator, ParGridFunction &x, ParFiniteElementSpace &smooth_flux_fes, ParFiniteElementSpace &flux_fes, Vector &errors, int norm_p, double solver_tol, int solver_max_it)
Definition: pgridfunc.cpp:535
T Max() const
Definition: array.cpp:90
void Assemble(int skip_zeros=1)
void Assemble(int skip_zeros=1)
Assemble the local matrix.
int Dimension() const
Definition: mesh.hpp:475
void SetTime(double t)
Set physical time (for time-dependent simulations)
void SetMaxIter(int max_iter)
Definition: hypre.cpp:1922
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Definition: fe_coll.hpp:133
int SpaceDimension() const
Definition: mesh.hpp:476
Wrapper for hypre&#39;s parallel vector class.
Definition: hypre.hpp:58
Array< int > bdr_attributes
Definition: mesh.hpp:140
MPI_Comm GetComm() const
Definition: pmesh.hpp:86
PCG solver in hypre.
Definition: hypre.hpp:558
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:323
Class for parallel bilinear form.
virtual void Finalize(int skip_zeros=1)
Finalizes the matrix initialization.
void AddBoundaryIntegrator(BilinearFormIntegrator *bfi)
Adds new Boundary Integrator.
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
Definition: hypre.cpp:1937
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
Adds new Domain Integrator.
void ParallelEliminateEssentialBC(const Array< int > &bdr_attr_is_ess, HypreParMatrix &A, const HypreParVector &X, HypreParVector &B) const
Class for parallel bilinear form.
Abstract class for hypre&#39;s solvers and preconditioners.
Definition: hypre.hpp:522
class for C-function coefficient
Vector data type.
Definition: vector.hpp:33
Class for parallel grid function.
Definition: pgridfunc.hpp:31
Wrapper for hypre&#39;s ParCSR matrix class.
Definition: hypre.hpp:143
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre&#39;s PCG.
Definition: hypre.cpp:1958
Class for parallel meshes.
Definition: pmesh.hpp:28
Integrator for (Q u, v) for VectorFiniteElements.
Definition: bilininteg.hpp:458
void ProjectBdrCoefficient(Coefficient &coeff, Array< int > &attr)
Definition: gridfunc.hpp:170
void ParallelProject(Vector &tv) const
Returns the vector restricted to the true dofs.
Definition: pgridfunc.cpp:120
Arbitrary order &quot;L2-conforming&quot; discontinuous finite elements.
Definition: fe_coll.hpp:95