MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
staticcond.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, 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
14namespace 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
132void 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<real_t>(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
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<real_t*>((const real_t*)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
389void 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<real_t*>((const real_t*)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}
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:697
int Size() const
Return the logical size of the array.
Definition array.hpp:144
void MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
Definition array.hpp:882
T * GetData()
Returns the data.
Definition array.hpp:118
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication.
Definition densemat.cpp:220
void MultTranspose(const real_t *x, real_t *y) const
Multiply a vector with the transpose matrix.
Definition densemat.cpp:262
real_t * Data() const
Returns the matrix data array.
Definition densemat.hpp:111
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition densemat.hpp:105
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.
void UseExternalData(real_t *d, int h, int w)
Change the data array and the size of the DenseMatrix.
Definition densemat.hpp:80
real_t * data
Definition densemat.hpp:629
virtual FiniteElementCollection * GetTraceCollection() const
Definition fe_coll.cpp:120
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:220
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Definition fespace.hpp:716
int GetNumElementInteriorDofs(int i) const
Returns the number of degrees of freedom associated with the interior of the specified element.
Definition fespace.cpp:3119
virtual const SparseMatrix * GetRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Definition fespace.hpp:620
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:265
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for the i'th element. The returned indices are offsets into an ...
Definition fespace.cpp:287
Ordering::Type GetOrdering() const
Return the ordering method.
Definition fespace.hpp:725
int GetNE() const
Returns number of elements in the mesh.
Definition fespace.hpp:740
const SparseMatrix * GetConformingProlongation() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Definition fespace.cpp:1302
const FiniteElementCollection * FEColl() const
Definition fespace.hpp:727
Mesh * GetMesh() const
Returns the mesh.
Definition fespace.hpp:559
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
Definition fespace.hpp:713
int GetVDim() const
Returns vector dimension.
Definition fespace.hpp:706
DofTransformation * GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for i'th boundary element. The returned indices are offsets int...
Definition fespace.cpp:303
void LSolve(int m, int n, real_t *X) const
virtual bool Factor(int m, real_t TOL=0.0)
Compute the LU factorization of the current matrix.
void BlockFactor(int m, int n, real_t *A12, real_t *A21, real_t *A22) const
void BlockBackSolve(int m, int n, int r, const real_t *U12, const real_t *X2, real_t *Y1) const
Class used by MFEM to store pointers to host and/or device memory.
void Delete()
Delete the owned pointers and reset the Memory object.
Pointer to an Operator of a specified type.
Definition handle.hpp:34
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
void ConvertFrom(OperatorHandle &A)
Convert the given OperatorHandle A to the currently set type id.
Definition handle.cpp:200
void SetType(Operator::Type tid)
Invoke Clear() and set a new type id.
Definition handle.hpp:132
void MakePtAP(OperatorHandle &A, OperatorHandle &P)
Reset the OperatorHandle to hold the product P^t A P.
Definition handle.cpp:123
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
Operator * Ptr() const
Access the underlying Operator pointer.
Definition handle.hpp:87
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged.
Definition handle.hpp:124
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
Operator::Type Type() const
Get the currently set operator type id.
Definition handle.hpp:99
Abstract operator.
Definition operator.hpp:25
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:66
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
Definition operator.hpp:48
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition operator.hpp:72
@ Hypre_ParCSR
ID for class HypreParMatrix.
Definition operator.hpp:287
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
Abstract parallel finite element space.
Definition pfespace.hpp:29
MPI_Comm GetComm() const
Definition pfespace.hpp:273
HYPRE_BigInt GlobalVSize() const
Definition pfespace.hpp:283
HYPRE_BigInt GlobalTrueVSize() const
Definition pfespace.hpp:285
HYPRE_BigInt * GetDofOffsets() const
Definition pfespace.hpp:281
const Operator * GetProlongationMatrix() const override
The returned Operator is owned by the FiniteElementSpace.
HypreParMatrix * Dof_TrueDof_Matrix() const
The true dof-to-dof interpolation matrix.
Definition pfespace.hpp:327
ParMesh * GetParMesh() const
Definition pfespace.hpp:277
Data type sparse matrix.
Definition sparsemat.hpp:51
virtual void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
void EliminateRowCol(int rc, const real_t sol, Vector &rhs, DiagonalPolicy dpolicy=DIAG_ONE)
Eliminate row rc and column rc and modify the rhs using sol.
void BooleanMultTranspose(const Array< int > &x, Array< int > &y) const
y = At * x, treating all entries as booleans (zero=false, nonzero=true).
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
virtual void Finalize(int skip_zeros=1)
Finalize the matrix initialization, switching the storage format from LIL to CSR.
virtual void AddMult(const Vector &x, Vector &y, const real_t a=1.0) const
y += A * x (default) or y += a * A * x
void AssembleMatrix(int el, const DenseMatrix &elmat)
StaticCondensation(FiniteElementSpace *fespace)
Construct a StaticCondensation object.
void AssembleBdrMatrix(int el, const DenseMatrix &elmat)
void Finalize()
Finalize the construction of the Schur complement matrix.
void ConvertMarkerToReducedTrueDofs(const Array< int > &ess_tdof_marker, Array< int > &ess_rtdof_marker) const
void EliminateReducedTrueDofs(const Array< int > &ess_rtdof_list, Matrix::DiagonalPolicy dpolicy)
Eliminate the given reduced true dofs from the Schur complement matrix S.
bool ReducesTrueVSize() const
void Init(bool symmetric, bool block_diagonal)
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....
void ComputeSolution(const Vector &b, const Vector &sc_sol, Vector &sol) const
void ReduceRHS(const Vector &b, Vector &sc_b) const
~StaticCondensation()
Destroy a StaticCondensation object.
void ReduceSolution(const Vector &sol, Vector &sc_sol) const
void LoseData()
Call this if data has been stolen.
Definition table.hpp:180
int * GetJ()
Definition table.hpp:114
void AddConnections(int r, const int *c, int nc)
Definition table.cpp:104
int RowSize(int i) const
Definition table.hpp:108
void ShiftUpI()
Definition table.cpp:115
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
Definition table.cpp:187
void MakeI(int nrows)
Next 7 methods are used together with the default constructor.
Definition table.cpp:81
int Size_of_connections() const
Definition table.hpp:98
void AddColumnsInRow(int r, int ncol)
Definition table.hpp:78
void MakeJ()
Definition table.cpp:91
int * GetI()
Definition table.hpp:113
Vector data type.
Definition vector.hpp:80
void SetDataAndSize(real_t *d, int s)
Set the Vector data and size.
Definition vector.hpp:175
int Size() const
Returns the size of the vector.
Definition vector.hpp:218
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:538
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
Definition vector.hpp:227
void SetSubVectorComplement(const Array< int > &dofs, const real_t val)
Set all vector entries NOT in the dofs Array to the given val.
Definition vector.cpp:739
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
Definition vector.cpp:578
real_t b
Definition lissajous.cpp:42
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition table.cpp:476
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
Definition table.cpp:414
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
float real_t
Definition config.hpp:43