MFEM  v3.2
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
tesla_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 "tesla_solver.hpp"
17 
18 using namespace std;
19 
20 namespace mfem
21 {
22 
23 using namespace miniapps;
24 
25 namespace electromagnetics
26 {
27 
28 TeslaSolver::TeslaSolver(ParMesh & pmesh, int order,
29  Array<int> & kbcs,
30  Array<int> & vbcs, Vector & vbcv,
31  Coefficient & muInvCoef,
32  void (*a_bc )(const Vector&, Vector&),
33  void (*j_src)(const Vector&, Vector&),
34  void (*m_src)(const Vector&, Vector&))
35  : myid_(0),
36  num_procs_(1),
37  order_(order),
38  pmesh_(&pmesh),
39  visit_dc_(NULL),
40  H1FESpace_(NULL),
41  HCurlFESpace_(NULL),
42  HDivFESpace_(NULL),
43  curlMuInvCurl_(NULL),
44  hCurlMass_(NULL),
45  hDivMassMuInv_(NULL),
46  hDivHCurlMuInv_(NULL),
47  Grad_(NULL),
48  Curl_(NULL),
49  a_(NULL),
50  b_(NULL),
51  h_(NULL),
52  j_(NULL),
53  k_(NULL),
54  m_(NULL),
55  DivFreeProj_(NULL),
56  SurfCur_(NULL),
57  muInvCoef_(&muInvCoef),
58  aBCCoef_(NULL),
59  jCoef_(NULL),
60  mCoef_(NULL),
61  a_bc_(a_bc),
62  j_src_(j_src),
63  m_src_(m_src)
64 {
65  // Initialize MPI variables
66  MPI_Comm_size(pmesh_->GetComm(), &num_procs_);
67  MPI_Comm_rank(pmesh_->GetComm(), &myid_);
68 
69  // Define compatible parallel finite element spaces on the parallel
70  // mesh. Here we use arbitrary order H1, Nedelec, and Raviart-Thomas finite
71  // elements.
72  H1FESpace_ = new H1_ParFESpace(pmesh_,order,pmesh_->Dimension());
73  HCurlFESpace_ = new ND_ParFESpace(pmesh_,order,pmesh_->Dimension());
74  HDivFESpace_ = new RT_ParFESpace(pmesh_,order,pmesh_->Dimension());
75 
76  // Select surface attributes for Dirichlet BCs
77  ess_bdr_.SetSize(pmesh.bdr_attributes.Max());
78  non_k_bdr_.SetSize(pmesh.bdr_attributes.Max());
79  ess_bdr_ = 1; // All outer surfaces
80  non_k_bdr_ = 1; // Surfaces without applied surface currents
81 
82  for (int i=0; i<kbcs.Size(); i++)
83  {
84  non_k_bdr_[kbcs[i]-1] = 0;
85  }
86 
87  // Setup various coefficients
88 
89  // Vector Potential on the outer surface
90  if ( a_bc_ == NULL )
91  {
92  Vector Zero(3);
93  Zero = 0.0;
94  aBCCoef_ = new VectorConstantCoefficient(Zero);
95  }
96  else
97  {
98  aBCCoef_ = new VectorFunctionCoefficient(pmesh_->SpaceDimension(),
99  *a_bc_);
100  }
101 
102  // Volume Current Density
103  if ( j_src_ != NULL )
104  {
105  jCoef_ = new VectorFunctionCoefficient(pmesh_->SpaceDimension(),
106  j_src_);
107  }
108 
109  // Magnetization
110  if ( m_src_ != NULL )
111  {
112  mCoef_ = new VectorFunctionCoefficient(pmesh_->SpaceDimension(),
113  m_src_);
114  }
115 
116  // Bilinear Forms
117  curlMuInvCurl_ = new ParBilinearForm(HCurlFESpace_);
118  curlMuInvCurl_->AddDomainIntegrator(new CurlCurlIntegrator(*muInvCoef_));
119 
120  hCurlMass_ = new ParBilinearForm(HCurlFESpace_);
122 
123  hDivHCurlMuInv_ = new ParMixedBilinearForm(HDivFESpace_, HCurlFESpace_);
124  hDivHCurlMuInv_->AddDomainIntegrator(new VectorFEMassIntegrator(*muInvCoef_));
125 
126  // Discrete Curl operator
127  Curl_ = new ParDiscreteCurlOperator(HCurlFESpace_, HDivFESpace_);
128 
129  // Build grid functions
130  a_ = new ParGridFunction(HCurlFESpace_);
131  b_ = new ParGridFunction(HDivFESpace_);
132  h_ = new ParGridFunction(HCurlFESpace_);
133 
134  if ( jCoef_ || kbcs.Size() > 0 )
135  {
136  Grad_ = new ParDiscreteGradOperator(H1FESpace_, HCurlFESpace_);
137  }
138  if ( jCoef_ )
139  {
140  j_ = new ParGridFunction(HCurlFESpace_);
141  DivFreeProj_ = new DivergenceFreeProjector(*H1FESpace_, *HCurlFESpace_,
142  *Grad_);
143  }
144 
145  if ( kbcs.Size() > 0 )
146  {
147  k_ = new ParGridFunction(HCurlFESpace_);
148 
149  // Object to solve the subproblem of computing surface currents
150  SurfCur_ = new SurfaceCurrent(*H1FESpace_, *HCurlFESpace_, *Grad_,
151  kbcs, vbcs, vbcv);
152  }
153 
154  if ( mCoef_ )
155  {
156  m_ = new ParGridFunction(HDivFESpace_);
157 
158  hDivMassMuInv_ = new ParBilinearForm(HDivFESpace_);
159  hDivMassMuInv_->AddDomainIntegrator(
160  new VectorFEMassIntegrator(*muInvCoef_));
161  }
162 }
163 
165 {
166  delete jCoef_;
167  delete mCoef_;
168  delete aBCCoef_;
169 
170  delete DivFreeProj_;
171  delete SurfCur_;
172 
173  delete a_;
174  delete b_;
175  delete h_;
176  delete j_;
177  delete k_;
178  delete m_;
179 
180  delete Grad_;
181  delete Curl_;
182 
183  delete curlMuInvCurl_;
184  delete hCurlMass_;
185  delete hDivMassMuInv_;
186  delete hDivHCurlMuInv_;
187 
188  delete H1FESpace_;
189  delete HCurlFESpace_;
190  delete HDivFESpace_;
191 
192  map<string,socketstream*>::iterator mit;
193  for (mit=socks_.begin(); mit!=socks_.end(); mit++)
194  {
195  delete mit->second;
196  }
197 }
198 
199 HYPRE_Int
201 {
202  return HCurlFESpace_->GlobalTrueVSize();
203 }
204 
205 void
207 {
208  HYPRE_Int size_h1 = H1FESpace_->GlobalTrueVSize();
209  HYPRE_Int size_nd = HCurlFESpace_->GlobalTrueVSize();
210  HYPRE_Int size_rt = HDivFESpace_->GlobalTrueVSize();
211  if (myid_ == 0)
212  {
213  cout << "Number of H1 unknowns: " << size_h1 << endl;
214  cout << "Number of H(Curl) unknowns: " << size_nd << endl;
215  cout << "Number of H(Div) unknowns: " << size_rt << endl;
216  }
217 }
218 
219 void
221 {
222  if (myid_ == 0) { cout << "Assembling ..." << flush; }
223 
224  curlMuInvCurl_->Assemble();
225  curlMuInvCurl_->Finalize();
226 
227  if ( hCurlMass_ )
228  {
229  hCurlMass_->Assemble();
230  hCurlMass_->Finalize();
231  }
232  if ( hDivMassMuInv_ )
233  {
234  hDivMassMuInv_->Assemble();
235  hDivMassMuInv_->Finalize();
236  }
237  if ( hDivHCurlMuInv_ )
238  {
239  hDivHCurlMuInv_->Assemble();
240  hDivHCurlMuInv_->Finalize();
241  }
242 
243  if (myid_ == 0) { cout << " done." << endl; }
244 }
245 
246 void
248 {
249  if (myid_ == 0) { cout << "Updating ..." << endl; }
250 
251  // Inform the spaces that the mesh has changed
252  // Note: we don't need to interpolate any GridFunctions on the new mesh
253  // so we pass 'false' to skip creation of any transformation matrices.
254  H1FESpace_->Update(false);
255  HCurlFESpace_->Update(false);
256  HDivFESpace_->Update(false);
257 
258  // Inform the grid functions that the space has changed.
259  a_->Update();
260  h_->Update();
261  b_->Update();
262  if ( j_ ) { j_->Update(); }
263  if ( k_ ) { k_->Update(); }
264  if ( m_ ) { m_->Update(); }
265 
266  // Inform the bilinear forms that the space has changed.
267  curlMuInvCurl_->Update();
268  if ( hCurlMass_ ) { hCurlMass_->Update(); }
269  if ( hDivMassMuInv_ ) { hDivMassMuInv_->Update(); }
270  if ( hDivHCurlMuInv_ ) { hDivHCurlMuInv_->Update(); }
271 
272  // Inform the other objects that the space has changed.
273  Curl_->Update();
274  if ( Grad_ ) { Grad_->Update(); }
275  if ( DivFreeProj_ ) { DivFreeProj_->Update(); }
276  if ( SurfCur_ ) { SurfCur_->Update(); }
277 }
278 
279 void
281 {
282  if (myid_ == 0) { cout << "Running solver ... " << endl; }
283 
284  // Initialize the magnetic vector potential with its boundary conditions
285  *a_ = 0.0;
286 
287  // Apply surface currents if available
288  if ( k_ )
289  {
290  SurfCur_->ComputeSurfaceCurrent(*k_);
291  *a_ = *k_;
292  }
293 
294  // Apply uniform B boundary condition on remaining surfaces
295  a_->ProjectBdrCoefficientTangent(*aBCCoef_, non_k_bdr_);
296 
297  // Initialize the RHS vector
298  HypreParVector *RHS = new HypreParVector(HCurlFESpace_);
299  *RHS = 0.0;
300 
301  // Initialize the volumetric current density
302  if ( j_ )
303  {
304  j_->ProjectCoefficient(*jCoef_);
305 
306  HypreParMatrix *MassHCurl = hCurlMass_->ParallelAssemble();
307  HypreParVector *J = j_->ParallelProject();
308  HypreParVector *JD = new HypreParVector(HCurlFESpace_);
309 
310  MassHCurl->Mult(*J,*JD);
311  DivFreeProj_->Mult(*JD, *RHS);
312 
313  delete MassHCurl;
314  delete J;
315  delete JD;
316  }
317 
318  // Initialize the Magnetization
319  HypreParVector *M = NULL;
320  if ( m_ )
321  {
322  m_->ProjectCoefficient(*mCoef_);
323  M = m_->ParallelProject();
324 
325  HypreParMatrix *MassHDiv = hDivMassMuInv_->ParallelAssemble();
326  HypreParVector *MD = new HypreParVector(HDivFESpace_);
327 
328  MassHDiv->Mult(*M,*MD);
329  Curl_->MultTranspose(*MD,*RHS,mu0_,1.0);
330 
331  delete MassHDiv;
332  delete MD;
333  }
334 
335  // Apply Dirichlet BCs to matrix and right hand side
336  HypreParMatrix *CurlMuInvCurl = curlMuInvCurl_->ParallelAssemble();
337  HypreParVector *A = a_->ParallelProject();
338 
339  // Apply the boundary conditions to the assembled matrix and vectors
340  curlMuInvCurl_->ParallelEliminateEssentialBC(ess_bdr_,
341  *CurlMuInvCurl,
342  *A, *RHS);
343 
344  // Define and apply a parallel PCG solver for AX=B with the AMS
345  // preconditioner from hypre.
346  HypreAMS *ams = new HypreAMS(*CurlMuInvCurl, HCurlFESpace_);
347  ams->SetSingularProblem();
348 
349  HyprePCG *pcg = new HyprePCG(*CurlMuInvCurl);
350  pcg->SetTol(1e-12);
351  pcg->SetMaxIter(500);
352  pcg->SetPrintLevel(2);
353  pcg->SetPreconditioner(*ams);
354  pcg->Mult(*RHS, *A);
355 
356  delete ams;
357  delete pcg;
358  delete CurlMuInvCurl;
359  delete RHS;
360 
361  // Extract the parallel grid function corresponding to the finite
362  // element approximation Phi. This is the local solution on each
363  // processor.
364  *a_ = *A;
365 
366  // Compute the negative Gradient of the solution vector. This is
367  // the magnetic field corresponding to the scalar potential
368  // represented by phi.
369  HypreParVector *B = new HypreParVector(HDivFESpace_);
370  Curl_->Mult(*A,*B);
371  *b_ = *B;
372 
373  // Compute magnetic field (H) from B and M
374  if (myid_ == 0) { cout << "Computing H ... " << flush; }
375 
376  ParGridFunction bd(HCurlFESpace_);
377  hDivHCurlMuInv_->Mult(*b_, bd);
378  if ( m_ )
379  {
380  hDivHCurlMuInv_->AddMult(*m_, bd, -1.0 * mu0_);
381  }
382 
383  HypreParMatrix MassHCurl;
384  Vector BD, H;
385 
386  Array<int> dbc_dofs_h;
387  hCurlMass_->FormLinearSystem(dbc_dofs_h, *h_, bd, MassHCurl, H, BD);
388 
389  HyprePCG * pcgM = new HyprePCG(MassHCurl);
390  pcgM->SetTol(1e-12);
391  pcgM->SetMaxIter(500);
392  pcgM->SetPrintLevel(0);
393  HypreDiagScale diagM;
394  pcgM->SetPreconditioner(diagM);
395  pcgM->Mult(BD,H);
396 
397  hCurlMass_->RecoverFEMSolution(H, bd, *h_);
398 
399  if (myid_ == 0) { cout << "done." << flush; }
400 
401  delete pcgM;
402  delete A;
403  delete B;
404  delete M;
405 
406  if (myid_ == 0) { cout << " Solver done. " << endl; }
407 }
408 
409 void
411 {
412  if (myid_ == 0) { cout << "Estimating Error ... " << flush; }
413 
414  // Space for the discontinuous (original) flux
415  CurlCurlIntegrator flux_integrator(*muInvCoef_);
416  RT_FECollection flux_fec(order_-1, pmesh_->SpaceDimension());
417  ParFiniteElementSpace flux_fes(pmesh_, &flux_fec);
418 
419  // Space for the smoothed (conforming) flux
420  double norm_p = 1;
421  ND_FECollection smooth_flux_fec(order_, pmesh_->Dimension());
422  ParFiniteElementSpace smooth_flux_fes(pmesh_, &smooth_flux_fec);
423 
424  L2ZZErrorEstimator(flux_integrator, *a_,
425  smooth_flux_fes, flux_fes, errors, norm_p);
426 
427  if (myid_ == 0) { cout << "done." << endl; }
428 }
429 
430 void
432 {
433  visit_dc_ = &visit_dc;
434 
435  visit_dc.RegisterField("A", a_);
436  visit_dc.RegisterField("B", b_);
437  visit_dc.RegisterField("H", h_);
438  if ( j_ ) { visit_dc.RegisterField("J", j_); }
439  if ( k_ ) { visit_dc.RegisterField("K", k_); }
440  if ( m_ ) { visit_dc.RegisterField("M", m_); }
441  if ( SurfCur_ ) { visit_dc.RegisterField("Psi", SurfCur_->GetPsi()); }
442 }
443 
444 void
446 {
447  if ( visit_dc_ )
448  {
449  if (myid_ == 0) { cout << "Writing VisIt files ..." << flush; }
450 
451  HYPRE_Int prob_size = this->GetProblemSize();
452  visit_dc_->SetCycle(it);
453  visit_dc_->SetTime(prob_size);
454  visit_dc_->Save();
455 
456  if (myid_ == 0) { cout << " done." << endl; }
457  }
458 }
459 
460 void
462 {
463  if ( myid_ == 0 ) { cout << "Opening GLVis sockets." << endl; }
464 
465  socks_["A"] = new socketstream;
466  socks_["A"]->precision(8);
467 
468  socks_["B"] = new socketstream;
469  socks_["B"]->precision(8);
470 
471  socks_["H"] = new socketstream;
472  socks_["H"]->precision(8);
473 
474  if ( j_ )
475  {
476  socks_["J"] = new socketstream;
477  socks_["J"]->precision(8);
478  }
479  if ( k_ )
480  {
481  socks_["K"] = new socketstream;
482  socks_["K"]->precision(8);
483 
484  socks_["Psi"] = new socketstream;
485  socks_["Psi"]->precision(8);
486  }
487  if ( m_ )
488  {
489  socks_["M"] = new socketstream;
490  socks_["M"]->precision(8);
491  }
492  if ( myid_ == 0 ) { cout << "GLVis sockets open." << endl; }
493 }
494 
495 void
497 {
498  if (myid_ == 0) { cout << "Sending data to GLVis ..." << flush; }
499 
500  char vishost[] = "localhost";
501  int visport = 19916;
502 
503  int Wx = 0, Wy = 0; // window position
504  int Ww = 350, Wh = 350; // window size
505  int offx = Ww+10, offy = Wh+45; // window offsets
506 
507  VisualizeField(*socks_["A"], vishost, visport,
508  *a_, "Vector Potential (A)", Wx, Wy, Ww, Wh);
509  Wx += offx;
510 
511  VisualizeField(*socks_["B"], vishost, visport,
512  *b_, "Magnetic Flux Density (B)", Wx, Wy, Ww, Wh);
513  Wx += offx;
514 
515  VisualizeField(*socks_["H"], vishost, visport,
516  *h_, "Magnetic Field (H)", Wx, Wy, Ww, Wh);
517  Wx += offx;
518 
519  if ( j_ )
520  {
521  VisualizeField(*socks_["J"], vishost, visport,
522  *j_, "Current Density (J)", Wx, Wy, Ww, Wh);
523  }
524 
525  Wx = 0; Wy += offy; // next line
526 
527  if ( k_ )
528  {
529  VisualizeField(*socks_["K"], vishost, visport,
530  *k_, "Surface Current Density (K)", Wx, Wy, Ww, Wh);
531  Wx += offx;
532 
533  VisualizeField(*socks_["Psi"], vishost, visport,
534  *SurfCur_->GetPsi(),
535  "Surface Current Potential (Psi)", Wx, Wy, Ww, Wh);
536  Wx += offx;
537  }
538  if ( m_ )
539  {
540  VisualizeField(*socks_["M"], vishost, visport,
541  *m_, "Magnetization (M)", Wx, Wy, Ww, Wh);
542  Wx += offx;
543  }
544  if (myid_ == 0) { cout << " done." << endl; }
545 }
546 
548  ParFiniteElementSpace & HCurlFESpace,
550  Array<int> & kbcs,
551  Array<int> & vbcs, Vector & vbcv)
552  : H1FESpace_(&H1FESpace),
553  HCurlFESpace_(&HCurlFESpace),
554  Grad_(&Grad),
555  kbcs_(&kbcs),
556  vbcs_(&vbcs),
557  vbcv_(&vbcv)
558 {
559  // Initialize MPI variables
560  MPI_Comm_rank(H1FESpace_->GetParMesh()->GetComm(), &myid_);
561 
562  s0_ = new ParBilinearForm(H1FESpace_);
563  s0_->AddBoundaryIntegrator(new DiffusionIntegrator);
564  s0_->Assemble();
565  s0_->Finalize();
566  S0_ = s0_->ParallelAssemble();
567 
568  amg_ = new HypreBoomerAMG(*S0_);
569  amg_->SetPrintLevel(0);
570 
571  pcg_ = new HyprePCG(*S0_);
572  pcg_->SetTol(1e-12);
573  pcg_->SetMaxIter(200);
574  pcg_->SetPrintLevel(0);
575  pcg_->SetPreconditioner(*amg_);
576 
577  ess_bdr_.SetSize(H1FESpace_->GetParMesh()->bdr_attributes.Max());
578  ess_bdr_ = 0;
579  for (int i=0; i<vbcs_->Size(); i++)
580  {
581  ess_bdr_[(*vbcs_)[i]-1] = 1;
582  }
583 
584  non_k_bdr_.SetSize(H1FESpace_->GetParMesh()->bdr_attributes.Max());
585  non_k_bdr_ = 1;
586  for (int i=0; i<kbcs_->Size(); i++)
587  {
588  non_k_bdr_[(*kbcs_)[i]-1] = 0;
589  }
590 
591  psi_ = new ParGridFunction(H1FESpace_);
592  *psi_ = 0.0;
593 
594  // Apply piecewise constant voltage boundary condition
595  Array<int> vbc_bdr_attr(H1FESpace_->GetParMesh()->bdr_attributes.Max());
596  for (int i=0; i<vbcs_->Size(); i++)
597  {
598  ConstantCoefficient voltage((*vbcv_)[i]);
599  vbc_bdr_attr = 0;
600  vbc_bdr_attr[(*vbcs_)[i]-1] = 1;
601  psi_->ProjectBdrCoefficient(voltage, vbc_bdr_attr);
602  }
603 
604  PSI_ = psi_->ParallelProject();
605  RHS_ = new HypreParVector(H1FESpace_);
606  K_ = new HypreParVector(HCurlFESpace_);
607 
608  s0_->ParallelEliminateEssentialBC(ess_bdr_,
609  *S0_,
610  *PSI_, *RHS_);
611 }
612 
614 {
615  delete pcg_;
616  delete amg_;
617  delete S0_;
618  delete PSI_;
619  delete RHS_;
620  delete K_;
621  delete s0_;
622  delete psi_;
623 }
624 
625 void
627 {
628  if (myid_ == 0) { cout << "Computing K ... " << flush; }
629 
630  k = 0.0;
631  pcg_->Mult(*RHS_, *PSI_);
632  *psi_ = *PSI_;
633 
634  Grad_->Mult(*PSI_,*K_);
635  k = *K_;
636 
637  Vector vZero(3); vZero = 0.0;
638  VectorConstantCoefficient Zero(vZero);
639  k.ProjectBdrCoefficientTangent(Zero,non_k_bdr_);
640 
641  if (myid_ == 0) { cout << "done." << endl; }
642 }
643 
644 void
646 {
647  delete pcg_;
648  delete amg_;
649  delete S0_;
650  delete PSI_;
651  delete RHS_;
652  delete K_;
653 
654  psi_->Update();
655  *psi_ = 0.0;
656 
657  s0_->Update();
658  s0_->Assemble();
659  s0_->Finalize();
660  S0_ = s0_->ParallelAssemble();
661 
662  amg_ = new HypreBoomerAMG(*S0_);
663  amg_->SetPrintLevel(0);
664 
665  pcg_ = new HyprePCG(*S0_);
666  pcg_->SetTol(1e-12);
667  pcg_->SetMaxIter(200);
668  pcg_->SetPrintLevel(0);
669  pcg_->SetPreconditioner(*amg_);
670 
671  // Apply piecewise constant voltage boundary condition
672  Array<int> vbc_bdr_attr(H1FESpace_->GetParMesh()->bdr_attributes.Max());
673  for (int i=0; i<vbcs_->Size(); i++)
674  {
675  ConstantCoefficient voltage((*vbcv_)[i]);
676  vbc_bdr_attr = 0;
677  vbc_bdr_attr[(*vbcs_)[i]-1] = 1;
678  psi_->ProjectBdrCoefficient(voltage, vbc_bdr_attr);
679  }
680 
681  PSI_ = psi_->ParallelProject();
682  RHS_ = new HypreParVector(H1FESpace_);
683  K_ = new HypreParVector(HCurlFESpace_);
684 
685  s0_->ParallelEliminateEssentialBC(ess_bdr_,
686  *S0_,
687  *PSI_, *RHS_);
688 }
689 
690 } // namespace electromagnetics
691 
692 } // namespace mfem
693 
694 #endif // MFEM_USE_MPI
void SetTol(double tol)
Definition: hypre.cpp:1964
int Size() const
Logical size of the array.
Definition: array.hpp:109
The Auxiliary-space Maxwell Solver in hypre.
Definition: hypre.hpp:768
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)
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
Integrator for (curl u, curl v) for Nedelec elements.
Definition: bilininteg.hpp:408
virtual void Update(bool want_transform=true)
Definition: pfespace.cpp:2155
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 GetErrorEstimates(Vector &errors)
void ProjectCoefficient(Coefficient &coeff)
Definition: pgridfunc.cpp:247
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:940
void SetPrintLevel(int print_lvl)
Definition: hypre.cpp:1979
HypreParMatrix * ParallelAssemble()
Returns the matrix assembled on the true dofs, i.e. P^t A P.
virtual void Update(FiniteElementSpace *nfes=NULL)
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
The BoomerAMG solver in hypre.
Definition: hypre.hpp:705
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:666
void SetPrintLevel(int print_level)
Definition: hypre.hpp:746
Data collection with VisIt I/O routines.
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:523
void SetTime(double t)
Set physical time (for time-dependent simulations)
void RegisterVisItFields(VisItDataCollection &visit_dc)
void SetMaxIter(int max_iter)
Definition: hypre.cpp:1969
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Definition: fe_coll.hpp:179
SurfaceCurrent(ParFiniteElementSpace &H1FESpace, ParFiniteElementSpace &HCurlFESpace, ParDiscreteGradOperator &Grad, Array< int > &kbcs, Array< int > &vbcs, Vector &vbcv)
int SpaceDimension() const
Definition: mesh.hpp:524
Wrapper for hypre&#39;s parallel vector class.
Definition: hypre.hpp:58
Array< int > bdr_attributes
Definition: mesh.hpp:141
MPI_Comm GetComm() const
Definition: pmesh.hpp:96
PCG solver in hypre.
Definition: hypre.hpp:565
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:331
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:542
void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x)
Class for parallel bilinear form.
virtual void Finalize(int skip_zeros=1)
Finalizes the matrix initialization.
void FormLinearSystem(Array< int > &ess_tdof_list, Vector &x, Vector &b, HypreParMatrix &A, Vector &X, Vector &B, int copy_interior=0)
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
Definition: hypre.cpp:1984
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
void ProjectBdrCoefficientTangent(VectorCoefficient &vcoeff, Array< int > &bdr_attr)
Definition: gridfunc.cpp:1478
Class for parallel bilinear form.
void ComputeSurfaceCurrent(ParGridFunction &k)
Arbitrary order H(curl)-conforming Nedelec finite elements.
Definition: fe_coll.hpp:231
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:150
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre&#39;s PCG.
Definition: hypre.cpp:2005
Class for parallel meshes.
Definition: pmesh.hpp:28
void SetSingularProblem()
Set this option when solving a curl-curl problem with zero mass term.
Definition: hypre.hpp:786
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
Integrator for (Q u, v) for VectorFiniteElements.
Definition: bilininteg.hpp:465
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
void ProjectBdrCoefficient(Coefficient &coeff, Array< int > &attr)
Definition: gridfunc.hpp:173
void ParallelProject(Vector &tv) const
Returns the vector restricted to the true dofs.
Definition: pgridfunc.cpp:126