MFEM  v4.0
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 "volta_solver.hpp"
13 
14 #ifdef MFEM_USE_MPI
15 
16 using namespace std;
17 namespace mfem
18 {
19 using namespace miniapps;
20 
21 namespace electromagnetics
22 {
23 
24 VoltaSolver::VoltaSolver(ParMesh & pmesh, int order,
25  Array<int> & dbcs, Vector & dbcv,
26  Array<int> & nbcs, Vector & nbcv,
27  Coefficient & epsCoef,
28  double (*phi_bc )(const Vector&),
29  double (*rho_src)(const Vector&),
30  void (*p_src )(const Vector&, Vector&),
31  Vector & point_charges)
32  : myid_(0),
33  num_procs_(1),
34  order_(order),
35  pmesh_(&pmesh),
36  dbcs_(&dbcs),
37  dbcv_(&dbcv),
38  nbcs_(&nbcs),
39  nbcv_(&nbcv),
40  visit_dc_(NULL),
41  H1FESpace_(NULL),
42  HCurlFESpace_(NULL),
43  HDivFESpace_(NULL),
44  divEpsGrad_(NULL),
45  h1Mass_(NULL),
46  h1SurfMass_(NULL),
47  hDivMass_(NULL),
48  hCurlHDivEps_(NULL),
49  hCurlHDiv_(NULL),
50  weakDiv_(NULL),
51  rhod_(NULL),
52  grad_(NULL),
53  phi_(NULL),
54  rho_(NULL),
55  sigma_(NULL),
56  e_(NULL),
57  d_(NULL),
58  p_(NULL),
59  epsCoef_(&epsCoef),
60  phiBCCoef_(NULL),
61  rhoCoef_(NULL),
62  pCoef_(NULL),
63  phi_bc_(phi_bc),
64  rho_src_(rho_src),
65  p_src_(p_src),
66  point_charge_params_(point_charges),
67  point_charges_(0)
68 {
69  // Initialize MPI variables
70  MPI_Comm_size(pmesh_->GetComm(), &num_procs_);
71  MPI_Comm_rank(pmesh_->GetComm(), &myid_);
72 
73  // Define compatible parallel finite element spaces on the parallel
74  // mesh. Here we use arbitrary order H1, Nedelec, and Raviart-Thomas finite
75  // elements.
76  H1FESpace_ = new H1_ParFESpace(pmesh_,order,pmesh_->Dimension());
77  HCurlFESpace_ = new ND_ParFESpace(pmesh_,order,pmesh_->Dimension());
78  HDivFESpace_ = new RT_ParFESpace(pmesh_,order,pmesh_->Dimension());
79 
80  // Select surface attributes for Dirichlet BCs
81  ess_bdr_.SetSize(pmesh.bdr_attributes.Max());
82  ess_bdr_ = 0; // Deselect all outer surfaces
83  for (int i=0; i<dbcs_->Size(); i++)
84  {
85  ess_bdr_[(*dbcs_)[i]-1] = 1;
86  }
87 
88  // Setup various coefficients
89 
90  // Potential on outer surface
91  if ( phi_bc_ != NULL )
92  {
93  phiBCCoef_ = new FunctionCoefficient(*phi_bc_);
94  }
95 
96  // Volume Charge Density
97  if ( rho_src_ != NULL )
98  {
99  rhoCoef_ = new FunctionCoefficient(rho_src_);
100  }
101 
102  // Polarization
103  if ( p_src_ != NULL )
104  {
105  pCoef_ = new VectorFunctionCoefficient(pmesh_->SpaceDimension(),
106  p_src_);
107  }
108 
109  // Bilinear Forms
110  divEpsGrad_ = new ParBilinearForm(H1FESpace_);
111  divEpsGrad_->AddDomainIntegrator(new DiffusionIntegrator(*epsCoef_));
112 
113  hDivMass_ = new ParBilinearForm(HDivFESpace_);
115 
116  hCurlHDivEps_ = new ParMixedBilinearForm(HCurlFESpace_,HDivFESpace_);
117  hCurlHDivEps_->AddDomainIntegrator(new VectorFEMassIntegrator(*epsCoef_));
118 
119  rhod_ = new ParLinearForm(H1FESpace_);
120 
121  // Discrete Grad operator
122  grad_ = new ParDiscreteGradOperator(H1FESpace_, HCurlFESpace_);
123 
124  // Build grid functions
125  phi_ = new ParGridFunction(H1FESpace_);
126  d_ = new ParGridFunction(HDivFESpace_);
127  e_ = new ParGridFunction(HCurlFESpace_);
128 
129  if ( point_charge_params_.Size() > 0 )
130  {
131  int dim = pmesh_->Dimension();
132  int npts = point_charge_params_.Size() / (dim + 1);
133  point_charges_.resize(npts);
134 
135  Vector cent(dim);
136  for (int i=0; i<npts; i++)
137  {
138  for (int d=0; d<dim; d++)
139  {
140  cent[d] = point_charge_params_[(dim + 1) * i + d];
141  }
142  double s = point_charge_params_[(dim + 1) * i + dim];
143 
144  point_charges_[i] = new DeltaCoefficient();
145  point_charges_[i]->SetScale(s);
146  point_charges_[i]->SetDeltaCenter(cent);
147 
148  rhod_->AddDomainIntegrator(new DomainLFIntegrator(*point_charges_[i]));
149  }
150  }
151 
152  if ( rho_src_ )
153  {
154  rho_ = new ParGridFunction(H1FESpace_);
155 
156  h1Mass_ = new ParBilinearForm(H1FESpace_);
157  h1Mass_->AddDomainIntegrator(new MassIntegrator);
158  }
159 
160  if ( p_src_ )
161  {
162  p_ = new ParGridFunction(HCurlFESpace_);
163 
164  hCurlHDiv_ = new ParMixedBilinearForm(HCurlFESpace_, HDivFESpace_);
166 
167  weakDiv_ = new ParMixedBilinearForm(HCurlFESpace_, H1FESpace_);
169 
170  }
171 
172  if ( nbcs_->Size() > 0 )
173  {
174  sigma_ = new ParGridFunction(H1FESpace_);
175 
176  h1SurfMass_ = new ParBilinearForm(H1FESpace_);
177  h1SurfMass_->AddBoundaryIntegrator(new MassIntegrator);
178  }
179 }
180 
182 {
183  delete phiBCCoef_;
184  delete rhoCoef_;
185  delete pCoef_;
186 
187  delete phi_;
188  delete rho_;
189  delete rhod_;
190  delete sigma_;
191  delete d_;
192  delete e_;
193  delete p_;
194 
195  delete grad_;
196 
197  delete divEpsGrad_;
198  delete h1Mass_;
199  delete h1SurfMass_;
200  delete hDivMass_;
201  delete hCurlHDivEps_;
202  delete hCurlHDiv_;
203  delete weakDiv_;
204 
205  delete H1FESpace_;
206  delete HCurlFESpace_;
207  delete HDivFESpace_;
208 
209  for (unsigned int i=0; i<point_charges_.size(); i++)
210  {
211  delete point_charges_[i];
212  }
213 
214  map<string,socketstream*>::iterator mit;
215  for (mit=socks_.begin(); mit!=socks_.end(); mit++)
216  {
217  delete mit->second;
218  }
219 }
220 
221 HYPRE_Int
223 {
224  return H1FESpace_->GlobalTrueVSize();
225 }
226 
227 void
229 {
230  HYPRE_Int size_h1 = H1FESpace_->GlobalTrueVSize();
231  HYPRE_Int size_nd = HCurlFESpace_->GlobalTrueVSize();
232  HYPRE_Int size_rt = HDivFESpace_->GlobalTrueVSize();
233  if (myid_ == 0)
234  {
235  cout << "Number of H1 unknowns: " << size_h1 << endl;
236  cout << "Number of H(Curl) unknowns: " << size_nd << endl;
237  cout << "Number of H(Div) unknowns: " << size_rt << endl;
238  }
239 }
240 
242 {
243  if (myid_ == 0) { cout << "Assembling ... " << flush; }
244 
245  divEpsGrad_->Assemble();
246  divEpsGrad_->Finalize();
247 
248  hDivMass_->Assemble();
249  hDivMass_->Finalize();
250 
251  hCurlHDivEps_->Assemble();
252  hCurlHDivEps_->Finalize();
253 
254  *rhod_ = 0.0;
255  rhod_->Assemble();
256 
257  grad_->Assemble();
258  grad_->Finalize();
259 
260  if ( h1Mass_ )
261  {
262  h1Mass_->Assemble();
263  h1Mass_->Finalize();
264  }
265  if ( h1SurfMass_ )
266  {
267  h1SurfMass_->Assemble();
268  h1SurfMass_->Finalize();
269  }
270  if ( hCurlHDiv_ )
271  {
272  hCurlHDiv_->Assemble();
273  hCurlHDiv_->Finalize();
274  }
275  if ( weakDiv_ )
276  {
277  weakDiv_->Assemble();
278  weakDiv_->Finalize();
279  }
280 
281  if (myid_ == 0) { cout << "done." << endl << flush; }
282 }
283 
284 void
286 {
287  if (myid_ == 0) { cout << "Updating ..." << endl; }
288 
289  // Inform the spaces that the mesh has changed
290  // Note: we don't need to interpolate any GridFunctions on the new mesh
291  // so we pass 'false' to skip creation of any transformation matrices.
292  H1FESpace_->Update(false);
293  HCurlFESpace_->Update(false);
294  HDivFESpace_->Update(false);
295 
296  // Inform the grid functions that the space has changed.
297  phi_->Update();
298  rhod_->Update();
299  d_->Update();
300  e_->Update();
301  if ( rho_ ) { rho_->Update(); }
302  if ( sigma_ ) { sigma_->Update(); }
303  if ( p_ ) { p_->Update(); }
304 
305  // Inform the bilinear forms that the space has changed.
306  divEpsGrad_->Update();
307  hDivMass_->Update();
308  hCurlHDivEps_->Update();
309 
310  if ( h1Mass_ ) { h1Mass_->Update(); }
311  if ( h1SurfMass_ ) { h1SurfMass_->Update(); }
312  if ( hCurlHDiv_ ) { hCurlHDiv_->Update(); }
313  if ( weakDiv_ ) { weakDiv_->Update(); }
314 
315  // Inform the other objects that the space has changed.
316  grad_->Update();
317 }
318 
319 void
321 {
322  if (myid_ == 0) { cout << "Running solver ... " << endl; }
323 
324  // Initialize the electric potential with its boundary conditions
325  *phi_ = 0.0;
326 
327  if ( dbcs_->Size() > 0 )
328  {
329  if ( phiBCCoef_ )
330  {
331  // Apply gradient boundary condition
332  phi_->ProjectBdrCoefficient(*phiBCCoef_, ess_bdr_);
333  }
334  else
335  {
336  // Apply piecewise constant boundary condition
337  Array<int> dbc_bdr_attr(pmesh_->bdr_attributes.Max());
338  for (int i=0; i<dbcs_->Size(); i++)
339  {
340  ConstantCoefficient voltage((*dbcv_)[i]);
341  dbc_bdr_attr = 0;
342  dbc_bdr_attr[(*dbcs_)[i]-1] = 1;
343  phi_->ProjectBdrCoefficient(voltage, dbc_bdr_attr);
344  }
345  }
346  }
347 
348  // Initialize the volumetric charge density
349  if ( rho_ )
350  {
351  rho_->ProjectCoefficient(*rhoCoef_);
352  h1Mass_->AddMult(*rho_, *rhod_);
353  }
354 
355  // Initialize the Polarization
356  if ( p_ )
357  {
358  p_->ProjectCoefficient(*pCoef_);
359  weakDiv_->AddMult(*p_, *rhod_);
360  }
361 
362  // Initialize the surface charge density
363  if ( sigma_ )
364  {
365  *sigma_ = 0.0;
366 
367  Array<int> nbc_bdr_attr(pmesh_->bdr_attributes.Max());
368  for (int i=0; i<nbcs_->Size(); i++)
369  {
370  ConstantCoefficient sigma_coef((*nbcv_)[i]);
371  nbc_bdr_attr = 0;
372  nbc_bdr_attr[(*nbcs_)[i]-1] = 1;
373  sigma_->ProjectBdrCoefficient(sigma_coef, nbc_bdr_attr);
374  }
375  h1SurfMass_->AddMult(*sigma_, *rhod_);
376  }
377 
378  // Determine the essential BC degrees of freedom
379  if ( dbcs_->Size() > 0 )
380  {
381  // From user supplied boundary attributes
382  H1FESpace_->GetEssentialTrueDofs(ess_bdr_, ess_bdr_tdofs_);
383  }
384  else
385  {
386  // Use the first DoF on processor zero by default
387  if ( myid_ == 0 )
388  {
389  ess_bdr_tdofs_.SetSize(1);
390  ess_bdr_tdofs_[0] = 0;
391  }
392  }
393 
394  // Apply essential BC and form linear system
395  HypreParMatrix DivEpsGrad;
396  HypreParVector Phi(H1FESpace_);
397  HypreParVector RHS(H1FESpace_);
398 
399  divEpsGrad_->FormLinearSystem(ess_bdr_tdofs_, *phi_, *rhod_, DivEpsGrad,
400  Phi, RHS);
401 
402  // Define and apply a parallel PCG solver for AX=B with the AMG
403  // preconditioner from hypre.
404  HypreBoomerAMG amg(DivEpsGrad);
405  HyprePCG pcg(DivEpsGrad);
406  pcg.SetTol(1e-12);
407  pcg.SetMaxIter(500);
408  pcg.SetPrintLevel(2);
409  pcg.SetPreconditioner(amg);
410  pcg.Mult(RHS, Phi);
411 
412  // Extract the parallel grid function corresponding to the finite
413  // element approximation Phi. This is the local solution on each
414  // processor.
415  divEpsGrad_->RecoverFEMSolution(Phi, *rhod_, *phi_);
416 
417  // Compute the negative Gradient of the solution vector. This is
418  // the magnetic field corresponding to the scalar potential
419  // represented by phi.
420  grad_->Mult(*phi_, *e_); *e_ *= -1.0;
421 
422  // Compute electric displacement (D) from E and P (if present)
423  if (myid_ == 0) { cout << "Computing D ..." << flush; }
424 
425  ParGridFunction ed(HDivFESpace_);
426  hCurlHDivEps_->Mult(*e_, ed);
427  if ( p_ )
428  {
429  hCurlHDiv_->AddMult(*p_, ed, -1.0);
430  }
431 
432  HypreParMatrix MassHDiv;
433  Vector ED, D;
434 
435  Array<int> dbc_dofs_d;
436  hDivMass_->FormLinearSystem(dbc_dofs_d, *d_, ed, MassHDiv, D, ED);
437 
438  HyprePCG pcgM(MassHDiv);
439  pcgM.SetTol(1e-12);
440  pcgM.SetMaxIter(500);
441  pcgM.SetPrintLevel(0);
442  HypreDiagScale diagM;
443  pcgM.SetPreconditioner(diagM);
444  pcgM.Mult(ED, D);
445 
446  hDivMass_->RecoverFEMSolution(D, ed, *d_);
447 
448  if (myid_ == 0) { cout << "done." << flush; }
449 
450  if (myid_ == 0) { cout << "Solver done. " << endl; }
451 }
452 
453 void
455 {
456  if (myid_ == 0) { cout << "Estimating Error ... " << flush; }
457 
458  // Space for the discontinuous (original) flux
459  DiffusionIntegrator flux_integrator(*epsCoef_);
460  L2_FECollection flux_fec(order_, pmesh_->Dimension());
461  // ND_FECollection flux_fec(order_, pmesh_->Dimension());
462  ParFiniteElementSpace flux_fes(pmesh_, &flux_fec, pmesh_->SpaceDimension());
463 
464  // Space for the smoothed (conforming) flux
465  double norm_p = 1;
466  RT_FECollection smooth_flux_fec(order_-1, pmesh_->Dimension());
467  ParFiniteElementSpace smooth_flux_fes(pmesh_, &smooth_flux_fec);
468 
469  L2ZZErrorEstimator(flux_integrator, *phi_,
470  smooth_flux_fes, flux_fes, errors, norm_p);
471 
472  if (myid_ == 0) { cout << "done." << endl; }
473 }
474 
475 void
477 {
478  visit_dc_ = &visit_dc;
479 
480  visit_dc.RegisterField("Phi", phi_);
481  visit_dc.RegisterField("D", d_);
482  visit_dc.RegisterField("E", e_);
483  if ( rho_ ) { visit_dc.RegisterField("Rho", rho_); }
484  if ( p_ ) { visit_dc.RegisterField("P", p_); }
485  if ( sigma_ ) { visit_dc.RegisterField("Sigma", sigma_); }
486 }
487 
488 void
490 {
491  if ( visit_dc_ )
492  {
493  if (myid_ == 0) { cout << "Writing VisIt files ..." << flush; }
494 
495  HYPRE_Int prob_size = this->GetProblemSize();
496  visit_dc_->SetCycle(it);
497  visit_dc_->SetTime(prob_size);
498  visit_dc_->Save();
499 
500  if (myid_ == 0) { cout << " done." << endl; }
501  }
502 }
503 
504 void
506 {
507  if ( myid_ == 0 ) { cout << "Opening GLVis sockets." << endl; }
508 
509  socks_["Phi"] = new socketstream;
510  socks_["Phi"]->precision(8);
511 
512  socks_["D"] = new socketstream;
513  socks_["D"]->precision(8);
514 
515  socks_["E"] = new socketstream;
516  socks_["E"]->precision(8);
517 
518  if ( rho_)
519  {
520  socks_["Rho"] = new socketstream;
521  socks_["Rho"]->precision(8);
522  }
523  if ( p_)
524  {
525  socks_["P"] = new socketstream;
526  socks_["P"]->precision(8);
527  }
528  if ( sigma_)
529  {
530  socks_["Sigma"] = new socketstream;
531  socks_["Sigma"]->precision(8);
532  }
533 }
534 
535 void
537 {
538  if (myid_ == 0) { cout << "Sending data to GLVis ..." << flush; }
539 
540  char vishost[] = "localhost";
541  int visport = 19916;
542 
543  int Wx = 0, Wy = 0; // window position
544  int Ww = 350, Wh = 350; // window size
545  int offx = Ww+10, offy = Wh+45; // window offsets
546 
547  VisualizeField(*socks_["Phi"], vishost, visport,
548  *phi_, "Electric Potential (Phi)", Wx, Wy, Ww, Wh);
549  Wx += offx;
550 
551  VisualizeField(*socks_["D"], vishost, visport,
552  *d_, "Electric Displacement (D)", Wx, Wy, Ww, Wh);
553  Wx += offx;
554 
555  VisualizeField(*socks_["E"], vishost, visport,
556  *e_, "Electric Field (E)", Wx, Wy, Ww, Wh);
557 
558  Wx = 0; Wy += offy; // next line
559 
560  if ( rho_ )
561  {
562  VisualizeField(*socks_["Rho"], vishost, visport,
563  *rho_, "Charge Density (Rho)", Wx, Wy, Ww, Wh);
564  Wx += offx;
565  }
566  if ( p_ )
567  {
568  VisualizeField(*socks_["P"], vishost, visport,
569  *p_, "Electric Polarization (P)", Wx, Wy, Ww, Wh);
570  Wx += offx;
571  }
572  if ( sigma_ )
573  {
574  VisualizeField(*socks_["Sigma"], vishost, visport,
575  *sigma_, "Surface Charge Density (Sigma)", Wx, Wy, Ww, Wh);
576  // Wx += offx; // not used
577  }
578  if (myid_ == 0) { cout << " done." << endl; }
579 }
580 
581 } // namespace electromagnetics
582 
583 } // namespace mfem
584 
585 #endif // MFEM_USE_MPI
void SetTol(double tol)
Definition: hypre.cpp:2182
int Size() const
Logical size of the array.
Definition: array.hpp:118
Class for domain integration L(v) := (f, v)
Definition: lininteg.hpp:93
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
Definition: pfespace.cpp:737
virtual void AddMult(const Vector &x, Vector &y, const double a=1.0) const
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
Subclass constant coefficient.
Definition: coefficient.hpp:67
virtual void FormLinearSystem(const Array< int > &ess_tdof_list, Vector &x, Vector &b, OperatorHandle &A, Vector &X, Vector &B, int copy_interior=0)
Form the linear system A X = B, corresponding to this bilinear form and the linear form b(...
virtual void AddMult(const Vector &x, Vector &y, const double a=1.0) const
int offx
virtual void Update(bool want_transform=true)
Definition: pfespace.cpp:2754
void Assemble()
Assembles the linear form i.e. sums over all domain/bdr integrators.
Definition: linearform.cpp:79
int Wx
Delta function coefficient.
int Size() const
Returns the size of the vector.
Definition: vector.hpp:150
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)
virtual void ProjectCoefficient(Coefficient &coeff)
Definition: pgridfunc.cpp:292
virtual void Finalize(int skip_zeros=1)
Finalizes the matrix initialization.
void SetPrintLevel(int print_lvl)
Definition: hypre.cpp:2197
void Update(ParFiniteElementSpace *pf=NULL)
Update the object according to the given new FE space *pf.
Definition: plinearform.cpp:21
virtual void Update(FiniteElementSpace *nfes=NULL)
void GetErrorEstimates(Vector &errors)
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
Adds a domain integrator. Assumes ownership of bfi.
The BoomerAMG solver in hypre.
Definition: hypre.hpp:873
Class for parallel linear form.
Definition: plinearform.hpp:26
int dim
Definition: ex3.cpp:48
virtual void Update()
Transform by the Space UpdateMatrix (e.g., on Mesh change).
Definition: pgridfunc.cpp:80
Jacobi preconditioner in hypre.
Definition: hypre.hpp:807
Data collection with VisIt I/O routines.
T Max() const
Find the maximal element in the array, using the comparison operator &lt; for class T.
Definition: array.cpp:68
void Assemble(int skip_zeros=1)
HYPRE_Int GlobalTrueVSize() const
Definition: pfespace.hpp:251
void Assemble(int skip_zeros=1)
Assemble the local matrix.
int Dimension() const
Definition: mesh.hpp:713
void SetTime(double t)
Set physical time (for time-dependent simulations)
void SetMaxIter(int max_iter)
Definition: hypre.cpp:2187
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Definition: fe_coll.hpp:180
int SpaceDimension() const
Definition: mesh.hpp:714
Wrapper for hypre&#39;s parallel vector class.
Definition: hypre.hpp:73
void AddDomainIntegrator(LinearFormIntegrator *lfi)
Adds new Domain Integrator. Assumes ownership of lfi.
Definition: linearform.cpp:39
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition: mesh.hpp:179
MPI_Comm GetComm() const
Definition: pmesh.hpp:223
PCG solver in hypre.
Definition: hypre.hpp:706
void ProjectBdrCoefficient(Coefficient *coeff[], VectorCoefficient *vcoeff, Array< int > &attr)
Definition: pgridfunc.cpp:400
Base class Coefficient that may optionally depend on time.
Definition: coefficient.hpp:31
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:618
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)
Definition: pgridfunc.cpp:709
virtual void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x)
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection and update the root file.
Class for parallel bilinear form using different test and trial FE spaces.
int Wh
virtual void Finalize(int skip_zeros=1)
Finalizes the matrix initialization.
void AddBoundaryIntegrator(BilinearFormIntegrator *bfi)
Adds new Boundary Integrator. Assumes ownership of bfi.
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
Definition: hypre.cpp:2202
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
Adds new Domain Integrator. Assumes ownership of bfi.
Class for parallel bilinear form.
class for C-function coefficient
Vector data type.
Definition: vector.hpp:48
int offy
int Wy
int Ww
Class for parallel grid function.
Definition: pgridfunc.hpp:32
Wrapper for hypre&#39;s ParCSR matrix class.
Definition: hypre.hpp:187
virtual void Assemble(int skip_zeros=1)
Construct the internal matrix representation of the discrete linear operator.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre&#39;s PCG.
Definition: hypre.cpp:2223
Class for parallel meshes.
Definition: pmesh.hpp:32
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Integrator for (Q u, v) for VectorFiniteElements.
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)
Definition: fem_extras.cpp:94
Arbitrary order &quot;L2-conforming&quot; discontinuous finite elements.
Definition: fe_coll.hpp:134