MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
weakform.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, 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 "weakform.hpp"
13
14namespace mfem
15{
16
18{
19 trial_integs.SetSize(trial_fes.Size(), test_fecols.Size());
20 for (int i = 0; i < trial_integs.NumRows(); i++)
21 {
22 for (int j = 0; j < trial_integs.NumCols(); j++)
23 {
25 }
26 }
27
28 test_integs.SetSize(test_fecols.Size(), test_fecols.Size());
29 for (int i = 0; i < test_integs.NumRows(); i++)
30 {
31 for (int j = 0; j < test_integs.NumCols(); j++)
32 {
34 }
35 }
36
37 lfis.SetSize(test_fecols.Size());
38 for (int j = 0; j < lfis.Size(); j++)
39 {
41 }
42
43
45
46 mat = mat_e = NULL;
49 width = height;
50
51 initialized = true;
52 static_cond = nullptr;
53
55 {
56 Bmat.SetSize(mesh->GetNE());
57 fvec.SetSize(mesh->GetNE());
58 }
59}
60
62{
65 dof_offsets[0] = 0;
66 tdof_offsets[0] = 0;
67 for (int i =0; i<nblocks; i++)
68 {
69 dof_offsets[i+1] = trial_fes[i]->GetVSize();
70 tdof_offsets[i+1] = trial_fes[i]->GetTrueVSize();
71 }
74}
75
76// Allocate SparseMatrix and RHS
78{
79 if (static_cond) { return; }
80
82 mat->owns_blocks = 1;
83
84 for (int i = 0; i<mat->NumRowBlocks(); i++)
85 {
86 int h = dof_offsets[i+1] - dof_offsets[i];
87 for (int j = 0; j<mat->NumColBlocks(); j++)
88 {
89 int w = dof_offsets[j+1] - dof_offsets[j];
90 mat->SetBlock(i,j,new SparseMatrix(h, w));
91 }
92 }
94 *y = 0.;
95}
96
97void DPGWeakForm::Finalize(int skip_zeros)
98{
99 if (mat) { mat->Finalize(skip_zeros); }
100 if (mat_e) { mat_e->Finalize(skip_zeros); }
101 if (static_cond) { static_cond->Finalize(); }
102}
103
104/// Adds new Domain BF Integrator. Assumes ownership of @a bfi.
106 BilinearFormIntegrator *bfi, int n, int m)
107{
108 MFEM_VERIFY(n>=0 && n<trial_fes.Size(),
109 "DPGWeakFrom::AddTrialIntegrator: trial fespace index out of bounds");
110 MFEM_VERIFY(m>=0 && m<test_fecols.Size(),
111 "DPGWeakFrom::AddTrialIntegrator: test fecol index out of bounds");
112 trial_integs(n,m)->Append(bfi);
113}
114
115/// Adds new Domain BF Integrator. Assumes ownership of @a bfi.
117(BilinearFormIntegrator *bfi, int n, int m)
118{
119 MFEM_VERIFY(n>=0 && n<test_fecols.Size() && m>=0 && m<test_fecols.Size(),
120 "DPGWeakFrom::AdTestIntegrator: test fecol index out of bounds");
121 test_integs(n,m)->Append(bfi);
122}
123
124/// Adds new Domain LF Integrator. Assumes ownership of @a bfi.
126 LinearFormIntegrator *lfi, int n)
127{
128 MFEM_VERIFY(n>=0 && n<test_fecols.Size(),
129 "DPGWeakFrom::AddDomainLFIntegrator: test fecol index out of bounds");
130 lfis[n]->Append(lfi);
131}
132
134{
137 P->owns_blocks = 0;
138 R->owns_blocks = 0;
139 for (int i = 0; i<nblocks; i++)
140 {
141 const SparseMatrix *P_ = trial_fes[i]->GetConformingProlongation();
142 if (P_)
143 {
144 const SparseMatrix *R_ = trial_fes[i]->GetRestrictionMatrix();
145 P->SetBlock(i,i,const_cast<SparseMatrix*>(P_));
146 R->SetBlock(i,i,const_cast<SparseMatrix*>(R_));
147 }
148 }
149}
150
152{
153 Finalize(0);
154 if (!P) { BuildProlongation(); }
155
156 BlockMatrix * Pt = Transpose(*P);
157 BlockMatrix * PtA = mfem::Mult(*Pt, *mat);
158 mat->owns_blocks = 0;
159 for (int i = 0; i<nblocks; i++)
160 {
161 for (int j = 0; j<nblocks; j++)
162 {
163 SparseMatrix * tmp = &mat->GetBlock(i,j);
164 if (Pt->IsZeroBlock(i,i))
165 {
166 PtA->SetBlock(i,j,tmp);
167 }
168 else
169 {
170 delete tmp;
171 }
172 }
173 }
174 delete mat;
175 if (mat_e)
176 {
177 BlockMatrix *PtAe = mfem::Mult(*Pt, *mat_e);
178 mat_e->owns_blocks = 0;
179 for (int i = 0; i<nblocks; i++)
180 {
181 for (int j = 0; j<nblocks; j++)
182 {
183 SparseMatrix * tmp = &mat_e->GetBlock(i,j);
184 if (Pt->IsZeroBlock(i,i))
185 {
186 PtAe->SetBlock(i,j,tmp);
187 }
188 else
189 {
190 delete tmp;
191 }
192 }
193 }
194 delete mat_e;
195 mat_e = PtAe;
196 }
197 delete Pt;
198
199 mat = mfem::Mult(*PtA, *P);
200
201 PtA->owns_blocks = 0;
202 for (int i = 0; i<nblocks; i++)
203 {
204 for (int j = 0; j<nblocks; j++)
205 {
206 SparseMatrix * tmp = &PtA->GetBlock(j,i);
207 if (P->IsZeroBlock(i,i))
208 {
209 mat->SetBlock(j,i,tmp);
210 }
211 else
212 {
213 delete tmp;
214 }
215 }
216 }
217 delete PtA;
218
219 if (mat_e)
220 {
221 BlockMatrix *PtAeP = mfem::Mult(*mat_e, *P);
222 mat_e->owns_blocks = 0;
223 for (int i = 0; i<nblocks; i++)
224 {
225 for (int j = 0; j<nblocks; j++)
226 {
227 SparseMatrix * tmp = &mat_e->GetBlock(j,i);
228 if (P->IsZeroBlock(i,i))
229 {
230 PtAeP->SetBlock(j,i,tmp);
231 }
232 else
233 {
234 delete tmp;
235 }
236 }
237 }
238
239 delete mat_e;
240 mat_e = PtAeP;
241 }
242 height = mat->Height();
243 width = mat->Width();
244}
245
246/// Assembles the form i.e. sums over all domain integrators.
247void DPGWeakForm::Assemble(int skip_zeros)
248{
249 ElementTransformation *eltrans;
250 Array<int> faces, ori;
251
252 DofTransformation doftrans_i, doftrans_j;
253 if (mat == NULL)
254 {
255 AllocMat();
256 }
257
258 // loop through the elements
259 int dim = mesh->Dimension();
260 DenseMatrix B, Be, G, Ge, A;
261 Vector vec_e, vec, Gvec, b;
262 Array<int> vdofs;
263
264 // loop through elements
265 for (int iel = 0; iel < mesh -> GetNE(); iel++)
266 {
267 if (dim == 1)
268 {
269 mesh->GetElementVertices(iel, faces);
270 }
271 else if (dim == 2)
272 {
273 mesh->GetElementEdges(iel, faces, ori);
274 }
275 else if (dim == 3)
276 {
277 mesh->GetElementFaces(iel,faces,ori);
278 }
279 else
280 {
281 MFEM_ABORT("DPGWeakForm::Assemble: dim > 3 not supported");
282 }
283 int numfaces = faces.Size();
284
285 Array<int> test_offs(test_fecols.Size()+1); test_offs[0] = 0;
286 Array<int> trial_offs(trial_fes.Size()+1); trial_offs = 0;
287
288 eltrans = mesh->GetElementTransformation(iel);
289 for (int j = 0; j < test_fecols.Size(); j++)
290 {
291 int order = test_fecols[j]->GetOrder(); // assuming uniform order
292 test_offs[j+1] = test_fecols_vdims[j]*test_fecols[j]->GetFE(
293 eltrans->GetGeometryType(),
294 order)->GetDof();
295 }
296 for (int j = 0; j < trial_fes.Size(); j++)
297 {
298 if (IsTraceFes[j])
299 {
300 for (int ie = 0; ie<faces.Size(); ie++)
301 {
302 trial_offs[j+1] += trial_fes[j]->GetVDim()*trial_fes[j]->GetFaceElement(
303 faces[ie])->GetDof();
304 }
305 }
306 else
307 {
308 trial_offs[j+1] = trial_fes[j]->GetVDim() * trial_fes[j]->GetFE(
309 iel)->GetDof();
310 }
311 }
312 test_offs.PartialSum();
313 trial_offs.PartialSum();
314
315 G.SetSize(test_offs.Last()); G = 0.0;
316 vec.SetSize(test_offs.Last()); vec = 0.0;
317 B.SetSize(test_offs.Last(),trial_offs.Last()); B = 0.0;
318
319
320 for (int j = 0; j < test_fecols.Size(); j++)
321 {
322 int order_j = test_fecols[j]->GetOrder();
323
324 eltrans = mesh->GetElementTransformation(iel);
325 const FiniteElement & test_fe =
326 *test_fecols[j]->GetFE(eltrans->GetGeometryType(), order_j);
327
328 for (int k = 0; k < lfis[j]->Size(); k++)
329 {
330 (*lfis[j])[k]->AssembleRHSElementVect(test_fe,*eltrans,vec_e);
331 vec.AddSubVector(vec_e,test_offs[j]);
332 }
333
334 for (int i = 0; i < test_fecols.Size(); i++)
335 {
336 int order_i = test_fecols[i]->GetOrder();
337 eltrans = mesh->GetElementTransformation(iel);
338 const FiniteElement & test_fe_i =
339 *test_fecols[i]->GetFE(eltrans->GetGeometryType(), order_i);
340
341 for (int k = 0; k < test_integs(i,j)->Size(); k++)
342 {
343 if (i==j)
344 {
345 (*test_integs(i,j))[k]->AssembleElementMatrix(test_fe,*eltrans,Ge);
346 }
347 else
348 {
349 (*test_integs(i,j))[k]->AssembleElementMatrix2(test_fe_i,test_fe,*eltrans,
350 Ge);
351 }
352 G.AddSubMatrix(test_offs[j], test_offs[i], Ge);
353 }
354 }
355
356 for (int i = 0; i < trial_fes.Size(); i++)
357 {
358 if (IsTraceFes[i])
359 {
360 for (int k = 0; k < trial_integs(i,j)->Size(); k++)
361 {
362 int face_dof_offs = 0;
363 for (int ie = 0; ie < numfaces; ie++)
364 {
365 int iface = faces[ie];
367 const FiniteElement & tfe = *trial_fes[i]->GetFaceElement(iface);
368 (*trial_integs(i,j))[k]->AssembleTraceFaceMatrix(iel,tfe,test_fe,*ftr,Be);
369 B.AddSubMatrix(test_offs[j], trial_offs[i]+face_dof_offs, Be);
370 face_dof_offs+=Be.Width();
371 }
372 }
373 }
374 else
375 {
376 const FiniteElement & fe = *trial_fes[i]->GetFE(iel);
377 eltrans = mesh->GetElementTransformation(iel);
378 for (int k = 0; k < trial_integs(i,j)->Size(); k++)
379 {
380 (*trial_integs(i,j))[k]->AssembleElementMatrix2(fe,test_fe,*eltrans,Be);
381 B.AddSubMatrix(test_offs[j], trial_offs[i], Be);
382 }
383 }
384 }
385 }
386
387 // Form Normal Equations B^T G^-1 B = B^T G^-1 l
388 Gvec.SetSize(G.Height());
389 b.SetSize(B.Width());
390 A.SetSize(B.Width());
391
392 CholeskyFactors chol(G.GetData());
393 chol.Factor(G.Height());
394
395 chol.LSolve(B.Height(), B.Width(), B.GetData());
396 chol.LSolve(vec.Size(), 1, vec.GetData());
397 if (store_matrices)
398 {
399 Bmat[iel] = new DenseMatrix(B);
400 fvec[iel] = new Vector(vec);
401 }
402 mfem::MultAtB(B,B,A);
403 B.MultTranspose(vec,b);
404
405 if (static_cond)
406 {
408 }
409 else
410 {
411 // Assembly
412 for (int i = 0; i<trial_fes.Size(); i++)
413 {
414 Array<int> vdofs_i;
415 doftrans_i.SetDofTransformation(nullptr);
416 if (IsTraceFes[i])
417 {
418 Array<int> face_vdofs;
419 for (int k = 0; k < numfaces; k++)
420 {
421 int iface = faces[k];
422 trial_fes[i]->GetFaceVDofs(iface, face_vdofs);
423 vdofs_i.Append(face_vdofs);
424 }
425 }
426 else
427 {
428 trial_fes[i]->GetElementVDofs(iel, vdofs_i, doftrans_i);
429 }
430 for (int j = 0; j<trial_fes.Size(); j++)
431 {
432 Array<int> vdofs_j;
433 doftrans_j.SetDofTransformation(nullptr);
434
435 if (IsTraceFes[j])
436 {
437 Array<int> face_vdofs;
438 for (int k = 0; k < numfaces; k++)
439 {
440 int iface = faces[k];
441 trial_fes[j]->GetFaceVDofs(iface, face_vdofs);
442 vdofs_j.Append(face_vdofs);
443 }
444 }
445 else
446 {
447 trial_fes[j]->GetElementVDofs(iel, vdofs_j, doftrans_j);
448 }
449
450 DenseMatrix Ae;
451 A.GetSubMatrix(trial_offs[i],trial_offs[i+1],
452 trial_offs[j],trial_offs[j+1], Ae);
453 TransformDual(doftrans_i, doftrans_j, Ae);
454 mat->GetBlock(i,j).AddSubMatrix(vdofs_i,vdofs_j, Ae);
455 }
456
457 // assemble rhs
458 real_t * data = b.GetData();
459 Vector vec1;
460 // ref subvector
461 vec1.SetDataAndSize(&data[trial_offs[i]],
462 trial_offs[i+1]-trial_offs[i]);
463 doftrans_i.TransformDual(vec1);
464 y->GetBlock(i).AddElementVector(vdofs_i,vec1);
465 }
466 }
467 }
468}
469
471 &ess_tdof_list,
472 Vector &x,
473 OperatorHandle &A, Vector &X,
474 Vector &B, int copy_interior)
475{
476 FormSystemMatrix(ess_tdof_list, A);
477 if (static_cond)
478 {
479 // Schur complement reduction to the exposed dofs
480 static_cond->ReduceSystem(x, X, B, copy_interior);
481 }
482 else if (!P)
483 {
484 EliminateVDofsInRHS(ess_tdof_list, x, *y);
485 X.MakeRef(x, 0, x.Size());
486 B.MakeRef(*y, 0, y->Size());
487 if (!copy_interior) { X.SetSubVectorComplement(ess_tdof_list, 0.0); }
488 }
489 else // non conforming space
490 {
491 B.SetSize(P->Width());
492
493 P->MultTranspose(*y, B);
494 real_t *data = y->GetData();
495 Vector tmp;
496 for (int i = 0; i<nblocks; i++)
497 {
498 if (P->IsZeroBlock(i,i))
499 {
500 int offset = tdof_offsets[i];
501 tmp.SetDataAndSize(&data[offset],tdof_offsets[i+1]-tdof_offsets[i]);
502 B.SetVector(tmp,offset);
503 }
504 }
505
506 X.SetSize(R->Height());
507
508 R->Mult(x, X);
509 data = x.GetData();
510 for (int i = 0; i<nblocks; i++)
511 {
512 if (R->IsZeroBlock(i,i))
513 {
514 int offset = tdof_offsets[i];
515 tmp.SetDataAndSize(&data[offset],tdof_offsets[i+1]-tdof_offsets[i]);
516 X.SetVector(tmp,offset);
517 }
518 }
519
520 EliminateVDofsInRHS(ess_tdof_list, X, B);
521 if (!copy_interior) { X.SetSubVectorComplement(ess_tdof_list, 0.0); }
522 }
523}
524
526 &ess_tdof_list,
528{
529 if (static_cond)
530 {
532 {
533 static_cond->SetEssentialTrueDofs(ess_tdof_list);
535 }
536 A.Reset(&static_cond->GetSchurMatrix(), false);
537 }
538 else
539 {
540 if (!mat_e)
541 {
542 bool conforming = true;
543 for (int i = 0; i<nblocks; i++)
544 {
545 const SparseMatrix *P_ = trial_fes[i]->GetConformingProlongation();
546 if (P_)
547 {
548 conforming = false;
549 break;
550 }
551 }
552 if (!conforming) { ConformingAssemble(); }
553 const int remove_zeros = 0;
554 EliminateVDofs(ess_tdof_list, diag_policy);
555 Finalize(remove_zeros);
556 }
557 A.Reset(mat, false);
558 }
559}
560
562 const Array<int> &vdofs, const Vector &x, Vector &b)
563{
564 mat_e->AddMult(x,b,-1.);
565 mat->PartMult(vdofs,x,b);
566}
567
570{
571 if (mat_e == NULL)
572 {
573 Array<int> offsets;
574
575 offsets.MakeRef( (P) ? tdof_offsets : dof_offsets);
576
577 mat_e = new BlockMatrix(offsets);
578 mat_e->owns_blocks = 1;
579 for (int i = 0; i<mat_e->NumRowBlocks(); i++)
580 {
581 int h = offsets[i+1] - offsets[i];
582 for (int j = 0; j<mat_e->NumColBlocks(); j++)
583 {
584 int w = offsets[j+1] - offsets[j];
585 mat_e->SetBlock(i,j,new SparseMatrix(h, w));
586 }
587 }
588 }
590}
591
593 Vector &x)
594{
595
596 if (static_cond)
597 {
598 // Private dofs back solve
600 }
601 else if (!P)
602 {
603 x.SyncMemory(X);
604 }
605 else
606 {
607 x.SetSize(P->Height());
608 P->Mult(X, x);
609 real_t *data = X.GetData();
610 Vector tmp;
611 for (int i = 0; i<nblocks; i++)
612 {
613 if (P->IsZeroBlock(i,i))
614 {
615 int offset = tdof_offsets[i];
616 tmp.SetDataAndSize(&data[offset],tdof_offsets[i+1]-tdof_offsets[i]);
617 x.SetVector(tmp,offset);
618 }
619 }
620 }
621}
622
624{
625 if (initialized)
626 {
627 for (int k = 0; k< trial_integs.NumRows(); k++)
628 {
629 for (int l = 0; l<trial_integs.NumCols(); l++)
630 {
631 for (int i = 0; i<trial_integs(k,l)->Size(); i++)
632 {
633 delete (*trial_integs(k,l))[i];
634 }
635 delete trial_integs(k,l);
636 }
637 }
638 trial_integs.DeleteAll();
639
640 for (int k = 0; k < test_integs.NumRows(); k++)
641 {
642 for (int l = 0; l < test_integs.NumCols(); l++)
643 {
644 for (int i = 0; i < test_integs(k,l)->Size(); i++)
645 {
646 delete (*test_integs(k,l))[i];
647 }
648 delete test_integs(k,l);
649 }
650 }
651 test_integs.DeleteAll();
652
653 for (int k = 0; k < lfis.Size(); k++)
654 {
655 for (int i = 0; i < lfis[k]->Size(); i++)
656 {
657 delete (*lfis[k])[i];
658 }
659 delete lfis[k];
660 }
661 lfis.DeleteAll();
662 }
663}
664
666{
667 delete mat_e; mat_e = nullptr;
668 delete mat; mat = nullptr;
669 delete y; y = nullptr;
670
671 if (P)
672 {
673 delete P; P = nullptr;
674 delete R; R = nullptr;
675 }
676
677 if (static_cond)
678 {
680 }
681 else
682 {
683 delete static_cond; static_cond = nullptr;
684 }
685
687
690 width = height;
691
692 initialized = true;
693
694 if (store_matrices)
695 {
696 for (int i = 0; i<Bmat.Size(); i++)
697 {
698 delete Bmat[i]; Bmat[i] = nullptr;
699 delete fvec[i]; fvec[i] = nullptr;
700 }
702 fvec.SetSize(mesh->GetNE());
703 for (int i = 0; i<Bmat.Size(); i++)
704 {
705 Bmat[i] = nullptr;
706 fvec[i] = nullptr;
707 }
708 }
709}
710
716
718{
719 // Element vector of trial space size
720 Vector u;
721 Array<int> vdofs;
722 Array<int> faces, ori;
723 int dim = mesh->Dimension();
725 // loop through elements
726 for (int iel = 0; iel < mesh -> GetNE(); iel++)
727 {
728 if (dim == 1)
729 {
730 mesh->GetElementVertices(iel, faces);
731 }
732 else if (dim == 2)
733 {
734 mesh->GetElementEdges(iel, faces, ori);
735 }
736 else if (dim == 3)
737 {
738 mesh->GetElementFaces(iel,faces,ori);
739 }
740 else
741 {
742 MFEM_ABORT("DPGWeakForm::ComputeResidual: "
743 "dim > 3 not supported");
744 }
745 int numfaces = faces.Size();
746
747 Array<int> trial_offs(trial_fes.Size()+1); trial_offs = 0;
748
749 for (int j = 0; j < trial_fes.Size(); j++)
750 {
751 if (IsTraceFes[j])
752 {
753 for (int ie = 0; ie<faces.Size(); ie++)
754 {
755 trial_offs[j+1] += trial_fes[j]->GetFaceElement(faces[ie])->GetDof();
756 }
757 }
758 else
759 {
760 trial_offs[j+1] = trial_fes[j]->GetVDim() * trial_fes[j]->GetFE(
761 iel)->GetDof();
762 }
763 }
764 trial_offs.PartialSum();
765
766 u.SetSize(trial_offs.Last());
767 real_t * data = u.GetData();
768 DofTransformation doftrans;
769 for (int i = 0; i<trial_fes.Size(); i++)
770 {
771 vdofs.SetSize(0);
772 doftrans.SetDofTransformation(nullptr);
773 if (IsTraceFes[i])
774 {
775 Array<int> face_vdofs;
776 for (int k = 0; k < numfaces; k++)
777 {
778 int iface = faces[k];
779 trial_fes[i]->GetFaceVDofs(iface, face_vdofs);
780 vdofs.Append(face_vdofs);
781 }
782 }
783 else
784 {
785 trial_fes[i]->GetElementVDofs(iel, vdofs, doftrans);
786 }
787 Vector vec1;
788 vec1.SetDataAndSize(&data[trial_offs[i]],
789 trial_offs[i+1]-trial_offs[i]);
790 x.GetBlock(i).GetSubVector(vdofs,vec1);
791 doftrans.InvTransformPrimal(vec1);
792 } // end of loop through trial spaces
793
794 Vector v(Bmat[iel]->Height());
795 Bmat[iel]->Mult(u,v);
796 v -= *fvec[iel];
797 residuals[iel] = v.Norml2();
798 } // end of loop through elements
799 return residuals;
800}
801
803{
804 delete mat_e; mat_e = nullptr;
805 delete mat; mat = nullptr;
806 delete y; y = nullptr;
807
809
810 if (P)
811 {
812 delete P;
813 delete R;
814 }
815
816 delete static_cond;
817
818 if (store_matrices)
819 {
820 for (int i = 0; i<mesh->GetNE(); i++)
821 {
822 delete Bmat[i]; Bmat[i] = nullptr;
823 delete fvec[i]; fvec[i] = nullptr;
824 }
825 }
826}
827
828} // namespace mfem
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:840
int Size() const
Return the logical size of the array.
Definition array.hpp:166
void PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
Definition array.cpp:104
void MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
Definition array.hpp:1053
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Definition array.hpp:912
T & Last()
Return the last element in the array.
Definition array.hpp:945
Abstract base class BilinearFormIntegrator.
void MultTranspose(const Vector &x, Vector &y) const override
MatrixTranspose-Vector Multiplication y = A'*x.
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
Partial matrix vector multiplication of (*this) with x involving only the rows given by rows....
void SetBlock(int i, int j, SparseMatrix *mat)
Set A(i,j) = mat.
void Mult(const Vector &x, Vector &y) const override
Matrix-Vector Multiplication y = A*x.
int NumColBlocks() const
Return the number of column blocks.
int IsZeroBlock(int i, int j) const
Check if block (i,j) is a zero block.
void EliminateRowCols(const Array< int > &vdofs, BlockMatrix *Ae, DiagonalPolicy dpolicy=DIAG_ONE)
Eliminate the rows and columns corresponding to the entries in vdofs + save the eliminated entries in...
SparseMatrix & GetBlock(int i, int j)
Return a reference to block (i,j). Reference may be invalid if Aij(i,j) == NULL.
void AddMult(const Vector &x, Vector &y, const real_t val=1.) const override
Matrix-Vector Multiplication y = y + val*A*x.
int owns_blocks
If owns_blocks the SparseMatrix objects Aij will be deallocated.
void Finalize(int skip_zeros=1) override
Finalize all the submatrices.
int NumRowBlocks() const
Return the number of row blocks.
Class that performs static condensation of interior dofs for multiple FE spaces. This class is used i...
BlockMatrix & GetSchurMatrix()
Return the serial Schur complement matrix.
void FormSystemMatrix(Operator::DiagonalPolicy diag_policy)
void SetEssentialTrueDofs(const Array< int > &ess_tdof_list)
Determine and save internally essential reduced true dofs.
void ReduceSystem(Vector &x, 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 &sc_sol, Vector &sol) const
void Finalize(int skip_zeros=0)
Finalize the construction of the Schur complement matrix.
void AssembleReducedSystem(int el, DenseMatrix &elmat, Vector &elvect)
A class to handle Vectors in a block fashion.
Vector & GetBlock(int i)
Get the i-th vector in the block.
void LSolve(int m, int n, real_t *X) const
bool Factor(int m, real_t TOL=0.0) override
Compute the Cholesky factorization of the current matrix.
Array2D< Array< BilinearFormIntegrator * > * > test_integs
Set of Test Space (broken) Integrators to be applied for matrix G.
Definition weakform.hpp:73
BlockStaticCondensation * static_cond
Owned.
Definition weakform.hpp:38
BlockMatrix * mat
Block matrix to be associated with the Block bilinear form. Owned.
Definition weakform.hpp:49
Array< int > tdof_offsets
Definition weakform.hpp:46
Array< FiniteElementSpace * > trial_fes
Trial FE spaces.
Definition weakform.hpp:60
virtual void Update()
Update the DPGWeakForm after mesh modifications (AMR)
Definition weakform.cpp:665
Array< Array< LinearFormIntegrator * > * > lfis
Set of Linear Form Integrators to be applied.
Definition weakform.hpp:76
void AddTrialIntegrator(BilinearFormIntegrator *bfi, int n, int m)
Adds new Trial Integrator. Assumes ownership of bfi.
Definition weakform.cpp:105
Array< FiniteElementCollection * > test_fecols
Test FE Collections (Broken)
Definition weakform.hpp:66
mfem::Operator::DiagonalPolicy diag_policy
Definition weakform.hpp:83
Array< DenseMatrix * > Bmat
Definition weakform.hpp:101
virtual void FormSystemMatrix(const Array< int > &ess_tdof_list, OperatorHandle &A)
Form the linear system matrix A, see FormLinearSystem() for details.
Definition weakform.cpp:525
Vector & ComputeResidual(const BlockVector &x)
Compute DPG residual based error estimator.
Definition weakform.cpp:717
Array2D< Array< BilinearFormIntegrator * > * > trial_integs
Set of Trial Integrators to be applied for matrix B.
Definition weakform.hpp:70
virtual void BuildProlongation()
Definition weakform.cpp:133
Array< int > dof_offsets
Definition weakform.hpp:45
void AddDomainLFIntegrator(LinearFormIntegrator *lfi, int n)
Adds new Domain LF Integrator. Assumes ownership of bfi.
Definition weakform.cpp:125
void AllocMat()
Allocate appropriate BlockMatrix and assign it to mat.
Definition weakform.cpp:77
void ConformingAssemble()
Definition weakform.cpp:151
Array< Vector * > fvec
Definition weakform.hpp:102
void EnableStaticCondensation()
Definition weakform.cpp:711
BlockMatrix * R
Block Restriction.
Definition weakform.hpp:81
virtual void RecoverFEMSolution(const Vector &X, Vector &x)
Recover the solution of a linear system formed with FormLinearSystem().
Definition weakform.cpp:592
Array< int > test_fecols_vdims
Definition weakform.hpp:67
virtual ~DPGWeakForm()
Definition weakform.cpp:802
void AddTestIntegrator(BilinearFormIntegrator *bfi, int n, int m)
Adds new Test Integrator. Assumes ownership of bfi.
Definition weakform.cpp:117
void ComputeOffsets()
Definition weakform.cpp:61
BlockVector * y
Block vector to be associated with the Block linear form.
Definition weakform.hpp:52
virtual void FormLinearSystem(const Array< int > &ess_tdof_list, Vector &x, OperatorHandle &A, Vector &X, Vector &B, int copy_interior=0)
Form the linear system A X = B, corresponding to this DPG weak form.
Definition weakform.cpp:470
void EliminateVDofsInRHS(const Array< int > &vdofs, const Vector &x, Vector &b)
Use the stored eliminated part of the matrix (see EliminateVDofs(const Array<int> &,...
Definition weakform.cpp:561
void ReleaseInitMemory()
Definition weakform.cpp:623
void Finalize(int skip_zeros=1)
Finalizes the matrix initialization.
Definition weakform.cpp:97
void Assemble(int skip_zeros=1)
Assembles the form i.e. sums over all integrators.
Definition weakform.cpp:247
BlockMatrix * mat_e
Block Matrix used to store the eliminations from the b.c. Owned. .
Definition weakform.hpp:57
void EliminateVDofs(const Array< int > &vdofs, Operator::DiagonalPolicy dpolicy=Operator::DIAG_ONE)
Eliminate the given vdofs, storing the eliminated part internally in .
Definition weakform.cpp:568
Array< int > IsTraceFes
Flags to determine if a FiniteElementSpace is Trace.
Definition weakform.hpp:63
BlockMatrix * P
Block Prolongation.
Definition weakform.hpp:79
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
void MultTranspose(const real_t *x, real_t *y) const
Multiply a vector with the transpose matrix.
Definition densemat.cpp:158
void GetSubMatrix(const Array< int > &idx, DenseMatrix &A) const
real_t * GetData() const
Returns the matrix data array. Warning: this method casts away constness.
Definition densemat.hpp:126
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition densemat.hpp:116
void AddSubMatrix(const Array< int > &idx, const DenseMatrix &A)
(*this)(idx[i],idx[j]) += A(i,j)
void TransformDual(real_t *v) const
Definition doftrans.cpp:77
void InvTransformPrimal(real_t *v) const
Definition doftrans.cpp:47
void SetDofTransformation(const StatelessDofTransformation &dof_trans)
Set or change the nested StatelessDofTransformation object.
Definition doftrans.hpp:176
Geometry::Type GetGeometryType() const
Return the Geometry::Type of the reference element.
Definition eltrans.hpp:175
A specialized ElementTransformation class representing a face and its two neighboring elements.
Definition eltrans.hpp:750
Abstract class for all finite elements.
Definition fe_base.hpp:247
Abstract base class LinearFormIntegrator.
Definition lininteg.hpp:28
virtual FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31)
Definition mesh.cpp:1104
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
Definition mesh.hpp:1609
int GetNE() const
Returns number of elements.
Definition mesh.hpp:1377
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1306
void GetElementTransformation(int i, IsoparametricTransformation *ElTr) const
Builds the transformation defining the i-th element in ElTr. ElTr must be allocated in advance and wi...
Definition mesh.cpp:360
void GetElementFaces(int i, Array< int > &faces, Array< int > &ori) const
Return the indices and the orientations of all faces of element i.
Definition mesh.cpp:7835
void GetElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of element i.
Definition mesh.cpp:7588
Pointer to an Operator of a specified type.
Definition handle.hpp:34
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
Definition handle.hpp:145
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:66
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
Definition operator.hpp:48
@ DIAG_ONE
Set the diagonal value to one.
Definition operator.hpp:50
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition operator.hpp:72
Data type sparse matrix.
Definition sparsemat.hpp:51
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
Vector data type.
Definition vector.hpp:82
void SetVector(const Vector &v, int offset)
(*this)[i + offset] = v[i]
Definition vector.cpp:353
void SetDataAndSize(real_t *d, int s)
Set the Vector data and size.
Definition vector.hpp:191
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add elements of the elemvect Vector to the entries listed in dofs. Negative dof values cause the -dof...
Definition vector.cpp:785
void AddSubVector(const Vector &v, int offset)
(*this)[i + offset] += v[i]
Definition vector.cpp:365
real_t Norml2() const
Returns the l2 norm of the vector.
Definition vector.cpp:968
void SyncMemory(const Vector &v) const
Update the memory location of the vector to match v.
Definition vector.hpp:272
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:584
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
Definition vector.hpp:243
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:854
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
Definition vector.cpp:676
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
Definition vector.hpp:660
int dim
Definition ex24.cpp:53
real_t b
Definition lissajous.cpp:42
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition table.cpp:505
void TransformDual(const DofTransformation &ran_dof_trans, const DofTransformation &dom_dof_trans, DenseMatrix &elmat)
Definition doftrans.cpp:152
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
Definition table.cpp:443
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
float real_t
Definition config.hpp:46