MFEM  v3.1
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
pfem_extras.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 "pfem_extras.hpp"
17 
18 using namespace std;
19 
20 namespace mfem
21 {
22 
23 namespace miniapps
24 {
25 
26 H1_ParFESpace::H1_ParFESpace(ParMesh *m,
27  const int p, const int space_dim, const int type,
28  int vdim, int order)
29  : ParFiniteElementSpace(m, new H1_FECollection(p,space_dim,type),vdim,order)
30 {
31  FEC_ = this->FiniteElementSpace::fec;
32 }
33 
35 {
36  delete FEC_;
37 }
38 
39 ND_ParFESpace::ND_ParFESpace(ParMesh *m, const int p, const int space_dim,
40  int vdim, int order)
41  : ParFiniteElementSpace(m, new ND_FECollection(p,space_dim),vdim,order)
42 {
43  FEC_ = this->FiniteElementSpace::fec;
44 }
45 
47 {
48  delete FEC_;
49 }
50 
51 RT_ParFESpace::RT_ParFESpace(ParMesh *m, const int p, const int space_dim,
52  int vdim, int order)
53  : ParFiniteElementSpace(m, new RT_FECollection(p-1,space_dim),vdim,order)
54 {
55  FEC_ = this->FiniteElementSpace::fec;
56 }
57 
59 {
60  delete FEC_;
61 }
62 
63 L2_ParFESpace::L2_ParFESpace(ParMesh *m, const int p, const int space_dim,
64  int vdim, int order)
65  : ParFiniteElementSpace(m, new L2_FECollection(p,space_dim),vdim,order)
66 {
67  FEC_ = this->FiniteElementSpace::fec;
68 }
69 
71 {
72  delete FEC_;
73 }
74 
76 {
77  delete pdlo_;
78  delete mat_;
79 }
80 
81 HYPRE_Int
83  double alpha, double beta)
84 {
85  if ( !mat_ ) { this->createMatrix(); }
86  return mat_->Mult( x, y, alpha, beta);
87 }
88 
89 HYPRE_Int
90 ParDiscreteInterpolationOperator::Mult(HYPRE_ParVector x, HYPRE_ParVector y,
91  double alpha, double beta)
92 {
93  if ( !mat_ ) { this->createMatrix(); }
94  return mat_->Mult( x, y, alpha, beta);
95 }
96 
97 HYPRE_Int
99  HypreParVector &y,
100  double alpha, double beta)
101 {
102  if ( !mat_ ) { this->createMatrix(); }
103  return mat_->MultTranspose( x, y, alpha, beta);
104 }
105 
106 void
108  double b, Vector &y) const
109 {
110  if ( !mat_ ) { this->createMatrix(); }
111  mat_->Mult( a, x, b, y);
112 }
113 
114 void
116  double b, Vector &y) const
117 {
118  if ( !mat_ ) { this->createMatrix(); }
119  mat_->MultTranspose( a, x, b, y);
120 }
121 
122 void
124 {
125  if ( !mat_ ) { this->createMatrix(); }
126  mat_->Mult( x, y);
127 }
128 
129 void
131  Vector &y) const
132 {
133  if ( !mat_ ) { this->createMatrix(); }
134  mat_->MultTranspose( x, y);
135 }
136 
137 void
139 {
140  pdlo_->Assemble();
141  pdlo_->Finalize();
142  delete mat_;
144 }
145 
146 void
148 {
149  pdlo_->Update();
150  this->createMatrix();
151 }
152 
155 {
156  if ( !mat_ ) { this->createMatrix(); }
157  HypreParMatrix * mat = mat_;
158  mat_ = NULL;
159  return mat;
160 }
161 
163  ParFiniteElementSpace *rfes)
164 {
165  pdlo_ = new ParDiscreteLinearOperator(dfes, rfes);
167  this->createMatrix();
168 }
169 
171  ParFiniteElementSpace *rfes)
172 {
173  pdlo_ = new ParDiscreteLinearOperator(dfes, rfes);
175  this->createMatrix();
176 }
177 
179  ParFiniteElementSpace *rfes)
180 {
181  pdlo_ = new ParDiscreteLinearOperator(dfes, rfes);
183  this->createMatrix();
184 }
185 
188  ParFiniteElementSpace & HCurlFESpace,
190  : H1FESpace_(&H1FESpace),
191  HCurlFESpace_(&HCurlFESpace),
192  Grad_(&Grad)
193 {
194  ess_bdr_.SetSize(H1FESpace.GetParMesh()->bdr_attributes.Max());
195  ess_bdr_ = 1;
196 
197  s0_ = new ParBilinearForm(&H1FESpace);
198  s0_->AddDomainIntegrator(new DiffusionIntegrator());
199  s0_->Assemble();
200  s0_->Finalize();
201  S0_ = s0_->ParallelAssemble();
202 
203  m1_ = new ParBilinearForm(&HCurlFESpace);
204  m1_->AddDomainIntegrator(new VectorFEMassIntegrator());
205  m1_->Assemble();
206  m1_->Finalize();
207  M1_ = m1_->ParallelAssemble();
208 
209  amg_ = new HypreBoomerAMG(*S0_);
210  amg_->SetPrintLevel(0);
211  pcg_ = new HyprePCG(*S0_);
212  pcg_->SetTol(1e-14);
213  pcg_->SetMaxIter(200);
214  pcg_->SetPrintLevel(0);
215  pcg_->SetPreconditioner(*amg_);
216 
217  xDiv_ = new HypreParVector(&H1FESpace);
218  yPot_ = new HypreParVector(&H1FESpace);
219  gradYPot_ = new HypreParVector(HCurlFESpace_);
220 }
221 
223 {
224  delete s0_;
225  delete m1_;
226  delete amg_;
227  delete pcg_;
228  delete S0_;
229  delete M1_;
230  delete xDiv_;
231  delete yPot_;
232  delete gradYPot_;
233 }
234 
235 void
237 {
238  *yPot_ = 0.0;
239  Grad_->MultTranspose(x,*xDiv_);
240  s0_->ParallelEliminateEssentialBC(ess_bdr_,*S0_,*yPot_,*xDiv_);
241  pcg_->Mult(*xDiv_,*yPot_);
242  Grad_->Mult(*yPot_,*gradYPot_);
243  M1_->Mult(*gradYPot_,y);
244 }
245 
246 void
248 {
249  delete S0_;
250  delete M1_;
251  delete gradYPot_;
252  delete yPot_;
253  delete xDiv_;
254  delete pcg_;
255  delete amg_;
256 
257  s0_->Update();
258  m1_->Update();
259 
260  s0_->Assemble();
261  s0_->Finalize();
262 
263  m1_->Assemble();
264  m1_->Finalize();
265 
266  S0_ = s0_->ParallelAssemble();
267  M1_ = m1_->ParallelAssemble();
268 
269  amg_ = new HypreBoomerAMG(*S0_);
270  amg_->SetPrintLevel(0);
271  pcg_ = new HyprePCG(*S0_);
272  pcg_->SetTol(1e-14);
273  pcg_->SetMaxIter(200);
274  pcg_->SetPrintLevel(0);
275  pcg_->SetPreconditioner(*amg_);
276 
277  xDiv_ = new HypreParVector(H1FESpace_);
278  yPot_ = new HypreParVector(H1FESpace_);
279  gradYPot_ = new HypreParVector(HCurlFESpace_);
280 }
281 
284  ParFiniteElementSpace & HCurlFESpace,
286  : IrrotationalProjector(H1FESpace,HCurlFESpace, Grad),
287  HCurlFESpace_(&HCurlFESpace),
288  xIrr_(NULL)
289 {
290  xIrr_ = new HypreParVector(&HCurlFESpace);
291 }
292 
294 {
295  delete xIrr_;
296 }
297 
298 void
300 {
301  this->IrrotationalProjector::Mult(x,*xIrr_);
302  y = x;
303  y -= *xIrr_;
304 }
305 
306 void
308 {
309  delete xIrr_;
310 
312 
313  xIrr_ = new HypreParVector(HCurlFESpace_);
314 }
315 
316 
317 void VisualizeField(socketstream &sock, const char *vishost, int visport,
318  ParGridFunction &gf, const char *title,
319  int x, int y, int w, int h)
320 {
321  ParMesh &pmesh = *gf.ParFESpace()->GetParMesh();
322  MPI_Comm comm = pmesh.GetComm();
323 
324  int num_procs, myid;
325  MPI_Comm_size(comm, &num_procs);
326  MPI_Comm_rank(comm, &myid);
327 
328  bool newly_opened = false;
329  int connection_failed;
330 
331  do
332  {
333  if (myid == 0)
334  {
335  if (!sock.is_open() || !sock)
336  {
337  sock.open(vishost, visport);
338  sock.precision(8);
339  newly_opened = true;
340  }
341  sock << "solution\n";
342  }
343 
344  pmesh.PrintAsOne(sock);
345  gf.SaveAsOne(sock);
346 
347  if (myid == 0 && newly_opened)
348  {
349  sock << "window_title '" << title << "'\n"
350  << "window_geometry "
351  << x << " " << y << " " << w << " " << h << "\n"
352  << "keys maaAc" << endl;
353  }
354 
355  if (myid == 0)
356  {
357  connection_failed = !sock && !newly_opened;
358  }
359  MPI_Bcast(&connection_failed, 1, MPI_INT, 0, comm);
360  }
361  while (connection_failed);
362 }
363 
364 } // namespace miniapps
365 
366 } // namespace mfem
367 
368 #endif
void SetTol(double tol)
Definition: hypre.cpp:1917
RT_ParFESpace(ParMesh *m, const int p, const int space_dim, int vdim=1, int order=Ordering::byNODES)
Definition: pfem_extras.cpp:51
void SaveAsOne(std::ostream &out=std::cout)
Merge the local grid functions.
Definition: pgridfunc.cpp:321
L2_ParFESpace(ParMesh *m, const int p, const int space_dim, int vdim=1, int order=Ordering::byNODES)
Definition: pfem_extras.cpp:63
HYPRE_Int MultTranspose(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A^t * x + beta * y.
Definition: hypre.cpp:963
IrrotationalProjector(ParFiniteElementSpace &H1FESpace, ParFiniteElementSpace &HCurlFESpace, ParDiscreteInterpolationOperator &Grad)
DivergenceFreeProjector(ParFiniteElementSpace &H1FESpace, ParFiniteElementSpace &HCurlFESpace, ParDiscreteInterpolationOperator &Grad)
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
Abstract parallel finite element space.
Definition: pfespace.hpp:28
virtual void Finalize(int skip_zeros=1)
Finalizes the matrix initialization.
ParFiniteElementSpace * ParFESpace()
Definition: pgridfunc.hpp:61
const FiniteElementCollection * fec
Definition: fespace.hpp:79
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
ND_ParFESpace(ParMesh *m, const int p, const int space_dim, int vdim=1, int order=Ordering::byNODES)
Definition: pfem_extras.cpp:39
void AddDomainInterpolator(DiscreteInterpolator *di)
HypreParMatrix * ParallelAssemble()
Returns the matrix assembled on the true dofs, i.e. P^t A P.
virtual void Update(FiniteElementSpace *nfes=NULL)
void PrintAsOne(std::ostream &out=std::cout)
Definition: pmesh.cpp:2976
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
ParDiscreteCurlOperator(ParFiniteElementSpace *dfes, ParFiniteElementSpace *rfes)
void VisualizeField(socketstream &sock, const char *vishost, int visport, ParGridFunction &gf, const char *title, int x, int y, int w, int h)
void SetPrintLevel(int print_level)
Definition: hypre.hpp:739
T Max() const
Definition: array.cpp:90
void Assemble(int skip_zeros=1)
Assemble the local matrix.
ParDiscreteGradOperator(ParFiniteElementSpace *dfes, ParFiniteElementSpace *rfes)
void SetMaxIter(int max_iter)
Definition: hypre.cpp:1922
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Definition: fe_coll.hpp:133
HypreParMatrix * ParallelAssemble() const
Returns the matrix &quot;assembled&quot; on the true dofs.
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
ParDiscreteDivOperator(ParFiniteElementSpace *dfes, ParFiniteElementSpace *rfes)
virtual void Finalize(int skip_zeros=1)
Finalizes the matrix initialization.
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
Definition: hypre.cpp:1937
void ParallelEliminateEssentialBC(const Array< int > &bdr_attr_is_ess, HypreParMatrix &A, const HypreParVector &X, HypreParVector &B) const
Class for parallel bilinear form.
int open(const char hostname[], int port)
Arbitrary order H(curl)-conforming Nedelec finite elements.
Definition: fe_coll.hpp:185
Vector data type.
Definition: vector.hpp:33
Arbitrary order H1-conforming (continuous) finite elements.
Definition: fe_coll.hpp:54
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 Vector &x, Vector &y) const
Operator application.
virtual void Assemble(int skip_zeros=1)
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
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
Arbitrary order &quot;L2-conforming&quot; discontinuous finite elements.
Definition: fe_coll.hpp:95