MFEM  v4.6.0
Finite element discretization library
staticcond.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #include "staticcond.hpp"
13 
14 namespace mfem
15 {
16 
18  : fes(fespace)
19 {
20  tr_fec = fespace->FEColl()->GetTraceCollection();
21  int vdim = fes->GetVDim();
22  int ordering = fes->GetOrdering();
23 #ifndef MFEM_USE_MPI
24  tr_fes = new FiniteElementSpace(fes->GetMesh(), tr_fec, vdim, ordering);
25 #else
26  pfes = dynamic_cast<ParFiniteElementSpace*>(fes);
27  if (!pfes)
28  {
29  tr_fes = new FiniteElementSpace(fes->GetMesh(), tr_fec, vdim, ordering);
30  tr_pfes = NULL;
31  }
32  else
33  {
34  tr_pfes = new ParFiniteElementSpace(pfes->GetParMesh(), tr_fec, vdim,
35  ordering);
36  tr_fes = tr_pfes;
37  }
40 #endif
41  S = S_e = NULL;
42  symm = false;
43 
44  Array<int> vdofs;
45  const int NE = fes->GetNE();
46  elem_pdof.MakeI(NE);
47  for (int i = 0; i < NE; i++)
48  {
49  const int npd = vdim*fes->GetNumElementInteriorDofs(i);
50  elem_pdof.AddColumnsInRow(i, npd);
51  }
52  elem_pdof.MakeJ();
53  for (int i = 0; i < NE; i++)
54  {
55  fes->GetElementVDofs(i, vdofs);
56  const int nsd = vdofs.Size()/vdim;
57  const int nspd = fes->GetNumElementInteriorDofs(i);
58  const int *dofs = vdofs.GetData();
59  for (int vd = 0; vd < vdim; vd++)
60  {
61 #ifdef MFEM_DEBUG
62  for (int j = 0; j < nspd; j++)
63  {
64  MFEM_ASSERT(dofs[nsd-nspd+j] >= 0, "");
65  }
66 #endif
67  elem_pdof.AddConnections(i, dofs+nsd-nspd, nspd);
68  dofs += nsd;
69  }
70  }
71  elem_pdof.ShiftUpI();
72  // Set the number of private dofs.
73  npdofs = elem_pdof.Size_of_connections();
74  MFEM_ASSERT(fes->GetVSize() == tr_fes->GetVSize() + npdofs,
75  "incompatible volume and trace FE spaces");
76  // Initialize the map rdof_edof.
77  rdof_edof.SetSize(tr_fes->GetVSize());
78  Array<int> rvdofs;
79  for (int i = 0; i < NE; i++)
80  {
81  fes->GetElementVDofs(i, vdofs);
82  tr_fes->GetElementVDofs(i, rvdofs);
83  const int nsd = vdofs.Size()/vdim;
84  const int nsrd = rvdofs.Size()/vdim;
85  for (int vd = 0; vd < vdim; vd++)
86  {
87  for (int j = 0; j < nsrd; j++)
88  {
89  int rvdof = rvdofs[j+nsrd*vd];
90  int vdof = vdofs[j+nsd*vd];
91  if (rvdof < 0)
92  {
93  rvdof = -1-rvdof;
94  vdof = -1-vdof;
95  }
96  MFEM_ASSERT(vdof >= 0, "incompatible volume and trace FE spaces");
97  rdof_edof[rvdof] = vdof;
98  }
99  }
100  }
101 }
102 
104 {
105 #ifdef MFEM_USE_MPI
106  // pS, pS_e are automatically destroyed
107 #endif
108  delete S_e;
109  delete S;
110  A_data.Delete();
111  A_ipiv.Delete();
112  delete tr_fes;
113  delete tr_fec;
114 }
115 
117 {
118  if (!Parallel())
119  {
120  return (tr_fes->GetTrueVSize() < fes->GetTrueVSize());
121  }
122  else
123  {
124 #ifdef MFEM_USE_MPI
125  return (tr_pfes->GlobalTrueVSize() < pfes->GlobalTrueVSize());
126 #else
127  return false; // avoid compiler warning
128 #endif
129  }
130 }
131 
132 void StaticCondensation::Init(bool symmetric, bool block_diagonal)
133 {
134  const int NE = fes->GetNE();
135  // symm = symmetric; // TODO: handle the symmetric case
136  A_offsets.SetSize(NE+1);
137  A_ipiv_offsets.SetSize(NE+1);
138  A_offsets[0] = A_ipiv_offsets[0] = 0;
139  Array<int> rvdofs;
140  for (int i = 0; i < NE; i++)
141  {
142  tr_fes->GetElementVDofs(i, rvdofs);
143  const int ned = rvdofs.Size();
144  const int npd = elem_pdof.RowSize(i);
145  A_offsets[i+1] = A_offsets[i] + npd*(npd + (symm ? 1 : 2)*ned);
146  A_ipiv_offsets[i+1] = A_ipiv_offsets[i] + npd;
147  }
148  A_data = Memory<double>(A_offsets[NE]);
149  A_ipiv = Memory<int>(A_ipiv_offsets[NE]);
150  const int nedofs = tr_fes->GetVSize();
151  if (fes->GetVDim() == 1)
152  {
153  // The sparsity pattern of S is given by the map rdof->elem->rdof
154  Table rdof_rdof;
155  {
156  Table elem_rdof, rdof_elem;
157  elem_rdof.MakeI(NE);
158  for (int i = 0; i < NE; i++)
159  {
160  tr_fes->GetElementVDofs(i, rvdofs);
161  elem_rdof.AddColumnsInRow(i, rvdofs.Size());
162  }
163  elem_rdof.MakeJ();
164  for (int i = 0; i < NE; i++)
165  {
166  tr_fes->GetElementVDofs(i, rvdofs);
168  elem_rdof.AddConnections(i, rvdofs.GetData(), rvdofs.Size());
169  }
170  elem_rdof.ShiftUpI();
171  Transpose(elem_rdof, rdof_elem, nedofs);
172  mfem::Mult(rdof_elem, elem_rdof, rdof_rdof);
173  }
174  S = new SparseMatrix(rdof_rdof.GetI(), rdof_rdof.GetJ(), NULL,
175  nedofs, nedofs, true, false, false);
176  rdof_rdof.LoseData();
177  }
178  else
179  {
180  // For a block diagonal vector bilinear form, the sparsity of
181  // rdof->elem->rdof is overkill, so we use dynamically allocated
182  // sparsity pattern.
183  S = new SparseMatrix(nedofs);
184  }
185 }
186 
188 {
189  Array<int> rvdofs;
190  tr_fes->GetElementVDofs(el, rvdofs);
191  const int vdim = fes->GetVDim();
192  const int nvpd = elem_pdof.RowSize(el);
193  const int nved = rvdofs.Size();
194  DenseMatrix A_pp(A_data + A_offsets[el], nvpd, nvpd);
195  DenseMatrix A_pe(A_pp.Data() + nvpd*nvpd, nvpd, nved);
196  DenseMatrix A_ep;
197  if (symm) { A_ep.SetSize(nved, nvpd); }
198  else { A_ep.UseExternalData(A_pe.Data() + nvpd*nved, nved, nvpd); }
199  DenseMatrix A_ee(nved, nved);
200 
201  const int npd = nvpd/vdim;
202  const int ned = nved/vdim;
203  const int nd = npd + ned;
204  // Copy the blocks from elmat to A_xx
205  for (int i = 0; i < vdim; i++)
206  {
207  for (int j = 0; j < vdim; j++)
208  {
209  A_pp.CopyMN(elmat, npd, npd, i*nd+ned, j*nd+ned, i*npd, j*npd);
210  A_pe.CopyMN(elmat, npd, ned, i*nd+ned, j*nd, i*npd, j*ned);
211  A_ep.CopyMN(elmat, ned, npd, i*nd, j*nd+ned, i*ned, j*npd);
212  A_ee.CopyMN(elmat, ned, ned, i*nd, j*nd, i*ned, j*ned);
213  }
214  }
215  // Compute the Schur complement
216  LUFactors lu(A_pp.Data(), A_ipiv + A_ipiv_offsets[el]);
217  lu.Factor(nvpd);
218  lu.BlockFactor(nvpd, nved, A_pe.Data(), A_ep.Data(), A_ee.Data());
219 
220  // Assemble the Schur complement
221  const int skip_zeros = 0;
222  S->AddSubMatrix(rvdofs, rvdofs, A_ee, skip_zeros);
223 }
224 
226 {
227  Array<int> rvdofs;
228  tr_fes->GetBdrElementVDofs(el, rvdofs);
229  const int skip_zeros = 0;
230  S->AddSubMatrix(rvdofs, rvdofs, elmat, skip_zeros);
231 }
232 
234 {
235  const int skip_zeros = 0;
236  if (!Parallel())
237  {
238  S->Finalize(skip_zeros);
239  if (S_e) { S_e->Finalize(skip_zeros); }
240  const SparseMatrix *cP = tr_fes->GetConformingProlongation();
241  if (cP)
242  {
243  if (S->Height() != cP->Width())
244  {
245  SparseMatrix *cS = mfem::RAP(*cP, *S, *cP);
246  delete S;
247  S = cS;
248  }
249  if (S_e && S_e->Height() != cP->Width())
250  {
251  SparseMatrix *cS_e = mfem::RAP(*cP, *S_e, *cP);
252  delete S_e;
253  S = cS_e;
254  }
255  }
256  }
257  else // parallel
258  {
259 #ifdef MFEM_USE_MPI
260  if (!S) { return; } // already finalized
261  S->Finalize(skip_zeros);
262  if (S_e) { S_e->Finalize(skip_zeros); }
263  OperatorHandle dS(pS.Type()), pP(pS.Type());
264  dS.MakeSquareBlockDiag(tr_pfes->GetComm(), tr_pfes->GlobalVSize(),
265  tr_pfes->GetDofOffsets(), S);
266  // TODO - construct Dof_TrueDof_Matrix directly in the pS format
267  pP.ConvertFrom(tr_pfes->Dof_TrueDof_Matrix());
268  pS.MakePtAP(dS, pP);
269  dS.Clear();
270  delete S;
271  S = NULL;
272  if (S_e)
273  {
274  OperatorHandle dS_e(pS_e.Type());
275  dS_e.MakeSquareBlockDiag(tr_pfes->GetComm(), tr_pfes->GlobalVSize(),
276  tr_pfes->GetDofOffsets(), S_e);
277  pS_e.MakePtAP(dS_e, pP);
278  dS_e.Clear();
279  delete S_e;
280  S_e = NULL;
281  }
282 #endif
283  }
284 }
285 
287  const Array<int> &ess_rtdof_list_, Matrix::DiagonalPolicy dpolicy)
288 {
289  if (!Parallel() || S) // not parallel or not finalized
290  {
291  if (S_e == NULL)
292  {
293  S_e = new SparseMatrix(S->Height());
294  }
295  for (int i = 0; i < ess_rtdof_list_.Size(); i++)
296  {
297  S->EliminateRowCol(ess_rtdof_list_[i], *S_e, dpolicy);
298  }
299  }
300  else // parallel and finalized
301  {
302 #ifdef MFEM_USE_MPI
303  MFEM_ASSERT(pS_e.Ptr() == NULL, "essential b.c. already eliminated");
304  pS_e.EliminateRowsCols(pS, ess_rtdof_list_);
305 #endif
306  }
307 }
308 
309 void StaticCondensation::ReduceRHS(const Vector &b, Vector &sc_b) const
310 {
311  // sc_b = b_e - A_ep A_pp_inv b_p
312 
313  MFEM_ASSERT(b.Size() == fes->GetVSize(), "'b' has incorrect size");
314 
315  const int NE = fes->GetNE();
316  const int nedofs = tr_fes->GetVSize();
317  const SparseMatrix *tr_cP = NULL;
318  Vector b_r;
319  if (!Parallel() && !(tr_cP = tr_fes->GetConformingProlongation()))
320  {
321  sc_b.SetSize(nedofs);
322  b_r.SetDataAndSize(sc_b.GetData(), sc_b.Size());
323  }
324  else
325  {
326  b_r.SetSize(nedofs);
327  }
328  for (int i = 0; i < nedofs; i++)
329  {
330  b_r(i) = b(rdof_edof[i]);
331  }
332 
333  DenseMatrix U_pe, L_ep;
334  Vector b_p, b_ep;
335  Array<int> rvdofs;
336  for (int i = 0; i < NE; i++)
337  {
338  tr_fes->GetElementVDofs(i, rvdofs);
339  const int ned = rvdofs.Size();
340  const int *rd = rvdofs.GetData();
341  const int npd = elem_pdof.RowSize(i);
342  const int *pd = elem_pdof.GetRow(i);
343  b_p.SetSize(npd);
344  b_ep.SetSize(ned);
345  for (int j = 0; j < npd; j++)
346  {
347  b_p(j) = b(pd[j]);
348  }
349 
350  LUFactors lu(const_cast<double*>((const double*)A_data) + A_offsets[i],
351  const_cast<int*>((const int*)A_ipiv) + A_ipiv_offsets[i]);
352  lu.LSolve(npd, 1, b_p.GetData());
353 
354  if (symm)
355  {
356  // TODO: handle the symmetric case correctly.
357  U_pe.UseExternalData(lu.data + npd*npd, npd, ned);
358  U_pe.MultTranspose(b_p, b_ep);
359  }
360  else
361  {
362  L_ep.UseExternalData(lu.data + npd*(npd+ned), ned, npd);
363  L_ep.Mult(b_p, b_ep);
364  }
365  for (int j = 0; j < ned; j++)
366  {
367  if (rd[j] >= 0) { b_r(rd[j]) -= b_ep(j); }
368  else { b_r(-1-rd[j]) += b_ep(j); }
369  }
370  }
371  if (!Parallel())
372  {
373  if (tr_cP)
374  {
375  sc_b.SetSize(tr_cP->Width());
376  tr_cP->MultTranspose(b_r, sc_b);
377  }
378  }
379  else
380  {
381 #ifdef MFEM_USE_MPI
382  const Operator *tr_P = tr_pfes->GetProlongationMatrix();
383  sc_b.SetSize(tr_P->Width());
384  tr_P->MultTranspose(b_r, sc_b);
385 #endif
386  }
387 }
388 
389 void StaticCondensation::ReduceSolution(const Vector &sol, Vector &sc_sol) const
390 {
391  MFEM_ASSERT(sol.Size() == fes->GetVSize(), "'sol' has incorrect size");
392 
393  const int nedofs = tr_fes->GetVSize();
394  const SparseMatrix *tr_R = tr_fes->GetRestrictionMatrix();
395  Vector sol_r;
396  if (!tr_R)
397  {
398  sc_sol.SetSize(nedofs);
399  sol_r.SetDataAndSize(sc_sol.GetData(), sc_sol.Size());
400  }
401  else
402  {
403  sol_r.SetSize(nedofs);
404  }
405  for (int i = 0; i < nedofs; i++)
406  {
407  sol_r(i) = sol(rdof_edof[i]);
408  }
409  if (tr_R)
410  {
411  sc_sol.SetSize(tr_R->Height());
412  tr_R->Mult(sol_r, sc_sol);
413  }
414 }
415 
417  Vector &B, int copy_interior) const
418 {
419  ReduceRHS(b, B);
420  ReduceSolution(x, X);
421  if (!Parallel())
422  {
423  S_e->AddMult(X, B, -1.);
424  S->PartMult(ess_rtdof_list, X, B);
425  }
426  else
427  {
428 #ifdef MFEM_USE_MPI
429  MFEM_ASSERT(pS.Type() == pS_e.Type(), "type id mismatch");
430  pS.EliminateBC(pS_e, ess_rtdof_list, X, B);
431 #endif
432  }
433  if (!copy_interior)
434  {
435  X.SetSubVectorComplement(ess_rtdof_list, 0.0);
436  }
437 }
438 
440  const Array<int> &ess_tdof_marker, Array<int> &ess_rtdof_marker) const
441 {
442  const int nedofs = tr_fes->GetVSize();
443  const SparseMatrix *R = fes->GetRestrictionMatrix();
444  Array<int> ess_dof_marker;
445  if (!R)
446  {
447  ess_dof_marker.MakeRef(ess_tdof_marker);
448  }
449  else
450  {
451  ess_dof_marker.SetSize(fes->GetVSize());
452  R->BooleanMultTranspose(ess_tdof_marker, ess_dof_marker);
453  }
454  const SparseMatrix *tr_R = tr_fes->GetRestrictionMatrix();
455  Array<int> ess_rdof_marker;
456  if (!tr_R)
457  {
458  ess_rtdof_marker.SetSize(nedofs);
459  ess_rdof_marker.MakeRef(ess_rtdof_marker);
460  }
461  else
462  {
463  ess_rdof_marker.SetSize(nedofs);
464  }
465  for (int i = 0; i < nedofs; i++)
466  {
467  ess_rdof_marker[i] = ess_dof_marker[rdof_edof[i]];
468  }
469  if (tr_R)
470  {
471  ess_rtdof_marker.SetSize(tr_R->Height());
472  tr_R->BooleanMult(ess_rdof_marker, ess_rtdof_marker);
473  }
474 }
475 
477  const Vector &b, const Vector &sc_sol, Vector &sol) const
478 {
479  // sol_e = sc_sol
480  // sol_p = A_pp_inv (b_p - A_pe sc_sol)
481 
482  MFEM_ASSERT(b.Size() == fes->GetVSize(), "'b' has incorrect size");
483 
484  const int nedofs = tr_fes->GetVSize();
485  Vector sol_r;
486  if (!Parallel())
487  {
488  const SparseMatrix *tr_cP = tr_fes->GetConformingProlongation();
489  if (!tr_cP)
490  {
491  sol_r.SetDataAndSize(sc_sol.GetData(), sc_sol.Size());
492  }
493  else
494  {
495  sol_r.SetSize(nedofs);
496  tr_cP->Mult(sc_sol, sol_r);
497  }
498  }
499  else
500  {
501 #ifdef MFEM_USE_MPI
502  sol_r.SetSize(nedofs);
503  tr_pfes->GetProlongationMatrix()->Mult(sc_sol, sol_r);
504 #endif
505  }
506  sol.SetSize(nedofs+npdofs);
507  for (int i = 0; i < nedofs; i++)
508  {
509  sol(rdof_edof[i]) = sol_r(i);
510  }
511  const int NE = fes->GetNE();
512  Vector b_p, s_e;
513  Array<int> rvdofs;
514  for (int i = 0; i < NE; i++)
515  {
516  tr_fes->GetElementVDofs(i, rvdofs);
517  const int ned = rvdofs.Size();
518  const int npd = elem_pdof.RowSize(i);
519  const int *pd = elem_pdof.GetRow(i);
520  b_p.SetSize(npd);
521 
522  for (int j = 0; j < npd; j++)
523  {
524  b_p(j) = b(pd[j]);
525  }
526  sol_r.GetSubVector(rvdofs, s_e);
527 
528  LUFactors lu(const_cast<double*>((const double*)A_data) + A_offsets[i],
529  const_cast<int*>((const int*)A_ipiv) + A_ipiv_offsets[i]);
530  lu.LSolve(npd, 1, b_p.GetData());
531  lu.BlockBackSolve(npd, ned, 1, lu.data + npd*npd, s_e.GetData(),
532  b_p.GetData());
533 
534  for (int j = 0; j < npd; j++)
535  {
536  sol(pd[j]) = b_p(j);
537  }
538  }
539 }
540 
541 }
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Definition: operator.hpp:93
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
Definition: sparsemat.cpp:733
int * GetJ()
Definition: table.hpp:114
virtual const Operator * GetProlongationMatrix() const
The returned Operator is owned by the FiniteElementSpace.
Definition: pfespace.cpp:1152
~StaticCondensation()
Destroy a StaticCondensation object.
Definition: staticcond.cpp:103
void AddColumnsInRow(int r, int ncol)
Definition: table.hpp:78
void ComputeSolution(const Vector &b, const Vector &sc_sol, Vector &sol) const
Definition: staticcond.cpp:476
void MakeI(int nrows)
Next 7 methods are used together with the default constructor.
Definition: table.cpp:81
virtual void Finalize(int skip_zeros=1)
Finalize the matrix initialization, switching the storage format from LIL to CSR. ...
Definition: sparsemat.hpp:546
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:517
void Delete()
Delete the owned pointers and reset the Memory object.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:475
Pointer to an Operator of a specified type.
Definition: handle.hpp:33
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:72
T * GetData()
Returns the data.
Definition: array.hpp:115
int Size() const
Returns the size of the vector.
Definition: vector.hpp:197
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
double * Data() const
Returns the matrix data array.
Definition: densemat.hpp:111
bool ReducesTrueVSize() const
Definition: staticcond.cpp:116
void EliminateReducedTrueDofs(const Array< int > &ess_rtdof_list, Matrix::DiagonalPolicy dpolicy)
Eliminate the given reduced true dofs from the Schur complement matrix S.
Definition: staticcond.cpp:286
void LoseData()
Call this if data has been stolen.
Definition: table.hpp:180
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
virtual void AddMult(const Vector &x, Vector &y, const double a=1.0) const
y += A * x (default) or y += a * A * x
Definition: sparsemat.cpp:740
Abstract parallel finite element space.
Definition: pfespace.hpp:28
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
Definition: vector.cpp:579
StaticCondensation(FiniteElementSpace *fespace)
Construct a StaticCondensation object.
Definition: staticcond.cpp:17
int RowSize(int i) const
Definition: table.hpp:108
void AddConnections(int r, const int *c, int nc)
Definition: table.cpp:104
void EliminateBC(const OperatorHandle &A_e, const Array< int > &ess_dof_list, const Vector &X, Vector &B) const
Eliminate essential dofs from the solution X into the r.h.s. B.
Definition: handle.cpp:340
void ReduceRHS(const Vector &b, Vector &sc_b) const
Definition: staticcond.cpp:309
Data type sparse matrix.
Definition: sparsemat.hpp:50
const FiniteElementCollection * FEColl() const
Definition: fespace.hpp:723
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
Definition: densemat.cpp:214
double b
Definition: lissajous.cpp:42
virtual const SparseMatrix * GetRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Definition: fespace.hpp:616
void EliminateRowsCols(OperatorHandle &A, const Array< int > &ess_dof_list)
Reset the OperatorHandle to be the eliminated part of A after elimination of the essential dofs ess_d...
Definition: handle.cpp:252
virtual FiniteElementCollection * GetTraceCollection() const
Definition: fe_coll.cpp:110
const SparseMatrix * GetConformingProlongation() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Definition: fespace.cpp:1268
void ConvertMarkerToReducedTrueDofs(const Array< int > &ess_tdof_marker, Array< int > &ess_rtdof_marker) const
Definition: staticcond.cpp:439
double * data
Definition: densemat.hpp:622
void LSolve(int m, int n, double *X) const
Definition: densemat.cpp:3359
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
Definition: densemat.cpp:3232
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
Definition: table.cpp:187
void Mult(const double *x, double *y) const
Matrix vector multiplication.
Definition: densemat.cpp:172
int GetNE() const
Returns number of elements in the mesh.
Definition: fespace.hpp:736
HYPRE_BigInt GlobalTrueVSize() const
Definition: pfespace.hpp:281
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
Definition: sparsemat.cpp:2722
void SetSubVectorComplement(const Array< int > &dofs, const double val)
Set all vector entries NOT in the dofs Array to the given val.
Definition: vector.cpp:740
double * GetData() const
Return a pointer to the beginning of the Vector data.
Definition: vector.hpp:206
int GetVDim() const
Returns vector dimension.
Definition: fespace.hpp:702
void ReduceSystem(Vector &x, Vector &b, Vector &X, Vector &B, int copy_interior=0) const
Set the reduced solution X and r.h.s B vectors from the full linear system solution x and r...
Definition: staticcond.cpp:416
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for the i&#39;th element. The returned indices are offsets into an ...
Definition: fespace.cpp:281
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Definition: fespace.hpp:712
virtual void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
Definition: sparsemat.cpp:908
Mesh * GetMesh() const
Returns the mesh.
Definition: fespace.hpp:555
void MakeSquareBlockDiag(MPI_Comm comm, HYPRE_BigInt glob_size, HYPRE_BigInt *row_starts, SparseMatrix *diag)
Reset the OperatorHandle to hold a parallel square block-diagonal matrix using the currently set type...
Definition: handle.cpp:60
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition: fespace.hpp:219
HYPRE_BigInt GlobalVSize() const
Definition: pfespace.hpp:279
int GetNumElementInteriorDofs(int i) const
Returns the number of degrees of freedom associated with the interior of the specified element...
Definition: fespace.cpp:3124
void Finalize()
Finalize the construction of the Schur complement matrix.
Definition: staticcond.cpp:233
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition: array.hpp:687
void EliminateRowCol(int rc, const double sol, Vector &rhs, DiagonalPolicy dpolicy=DIAG_ONE)
Eliminate row rc and column rc and modify the rhs using sol.
Definition: sparsemat.cpp:1854
void ReduceSolution(const Vector &sol, Vector &sc_sol) const
Definition: staticcond.cpp:389
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
Definition: table.cpp:413
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:66
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Definition: vector.hpp:154
void AssembleBdrMatrix(int el, const DenseMatrix &elmat)
Definition: staticcond.cpp:225
void ShiftUpI()
Definition: table.cpp:115
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
Definition: sparsemat.cpp:1026
HYPRE_BigInt * GetDofOffsets() const
Definition: pfespace.hpp:277
Operator::Type Type() const
Get the currently set operator type id.
Definition: handle.hpp:99
void AssembleMatrix(int el, const DenseMatrix &elmat)
Definition: staticcond.cpp:187
Ordering::Type GetOrdering() const
Return the ordering method.
Definition: fespace.hpp:721
DofTransformation * GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for i&#39;th boundary element. The returned indices are offsets int...
Definition: fespace.cpp:297
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
Definition: operator.hpp:47
void MakeJ()
Definition: table.cpp:91
virtual bool Factor(int m, double TOL=0.0)
Compute the LU factorization of the current matrix.
Definition: densemat.cpp:3249
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
Definition: fespace.hpp:709
Operator * Ptr() const
Access the underlying Operator pointer.
Definition: handle.hpp:87
int Size_of_connections() const
Definition: table.hpp:98
int Size() const
Return the logical size of the array.
Definition: array.hpp:141
MPI_Comm GetComm() const
Definition: pfespace.hpp:269
void MakeRef(T *, int)
Make this Array a reference to a pointer.
Definition: array.hpp:872
Vector data type.
Definition: vector.hpp:58
void BlockBackSolve(int m, int n, int r, const double *U12, const double *X2, double *Y1) const
Definition: densemat.cpp:3584
ID for class HypreParMatrix.
Definition: operator.hpp:287
int * GetI()
Definition: table.hpp:113
void CopyMN(const DenseMatrix &A, int m, int n, int Aro, int Aco)
Copy the m x n submatrix of A at row/col offsets Aro/Aco to *this.
Definition: densemat.cpp:1591
HypreParMatrix * Dof_TrueDof_Matrix() const
The true dof-to-dof interpolation matrix.
Definition: pfespace.hpp:317
void UseExternalData(double *d, int h, int w)
Change the data array and the size of the DenseMatrix.
Definition: densemat.hpp:80
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:105
Abstract operator.
Definition: operator.hpp:24
void Init(bool symmetric, bool block_diagonal)
Definition: staticcond.cpp:132
void MakePtAP(OperatorHandle &A, OperatorHandle &P)
Reset the OperatorHandle to hold the product P^t A P.
Definition: handle.cpp:123
static void AdjustVDofs(Array< int > &vdofs)
Remove the orientation information encoded into an array of dofs Some basis function types have a rel...
Definition: fespace.cpp:267
void SetType(Operator::Type tid)
Invoke Clear() and set a new type id.
Definition: handle.hpp:132
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
Definition: sparsemat.cpp:982
void BooleanMultTranspose(const Array< int > &x, Array< int > &y) const
y = At * x, treating all entries as booleans (zero=false, nonzero=true).
Definition: sparsemat.cpp:1056