MFEM  v3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
bilinearform.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.googlecode.com.
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 // Implementation of class BilinearForm
13 
14 #include "fem.hpp"
15 #include <cmath>
16 
17 namespace mfem
18 {
19 
21 {
22  if (precompute_sparsity == 0 || fes->GetVDim() > 1)
23  {
24  mat = new SparseMatrix(height);
25  return;
26  }
27 
29  const Table &elem_dof = fes->GetElementToDofTable();
30  Table dof_dof;
31 
32  if (fbfi.Size() > 0)
33  {
34  // the sparsity pattern is defined from the map: face->element->dof
35  Table face_dof, dof_face;
36  {
37  Table *face_elem = fes->GetMesh()->GetFaceToElementTable();
38  mfem::Mult(*face_elem, elem_dof, face_dof);
39  delete face_elem;
40  }
41  Transpose(face_dof, dof_face, height);
42  mfem::Mult(dof_face, face_dof, dof_dof);
43  }
44  else
45  {
46  // the sparsity pattern is defined from the map: element->dof
47  Table dof_elem;
48  Transpose(elem_dof, dof_elem, height);
49  mfem::Mult(dof_elem, elem_dof, dof_dof);
50  }
51 
52  int *I = dof_dof.GetI();
53  int *J = dof_dof.GetJ();
54  double *data = new double[I[height]];
55 
56  mat = new SparseMatrix(I, J, data, height, height);
57  *mat = 0.0;
58 
59  dof_dof.LoseData();
60 }
61 
63  : Matrix (f->GetVSize())
64 {
65  fes = f;
66  mat = mat_e = NULL;
67  extern_bfs = 0;
68  element_matrices = NULL;
70 }
71 
73  : Matrix (f->GetVSize())
74 {
75  int i;
77 
78  fes = f;
79  mat_e = NULL;
80  extern_bfs = 1;
81  element_matrices = NULL;
83 
84  bfi = bf->GetDBFI();
85  dbfi.SetSize (bfi->Size());
86  for (i = 0; i < bfi->Size(); i++)
87  dbfi[i] = (*bfi)[i];
88 
89  bfi = bf->GetBBFI();
90  bbfi.SetSize (bfi->Size());
91  for (i = 0; i < bfi->Size(); i++)
92  bbfi[i] = (*bfi)[i];
93 
94  bfi = bf->GetFBFI();
95  fbfi.SetSize (bfi->Size());
96  for (i = 0; i < bfi->Size(); i++)
97  fbfi[i] = (*bfi)[i];
98 
99  bfi = bf->GetBFBFI();
100  bfbfi.SetSize (bfi->Size());
101  for (i = 0; i < bfi->Size(); i++)
102  bfbfi[i] = (*bfi)[i];
103 
104  AllocMat();
105 }
106 
107 double& BilinearForm::Elem (int i, int j)
108 {
109  return mat -> Elem(i,j);
110 }
111 
112 const double& BilinearForm::Elem (int i, int j) const
113 {
114  return mat -> Elem(i,j);
115 }
116 
117 void BilinearForm::Mult (const Vector & x, Vector & y) const
118 {
119  mat -> Mult (x, y);
120 }
121 
123 {
124  return mat -> Inverse();
125 }
126 
127 void BilinearForm::Finalize (int skip_zeros)
128 {
129  mat -> Finalize (skip_zeros);
130  if (mat_e)
131  mat_e -> Finalize (skip_zeros);
132 }
133 
135 {
136  dbfi.Append (bfi);
137 }
138 
140 {
141  bbfi.Append (bfi);
142 }
143 
145 {
146  fbfi.Append (bfi);
147 }
148 
150 {
151  bfbfi.Append (bfi);
152 }
153 
155 {
156  if (element_matrices)
157  {
159  elmat = element_matrices->GetData(i);
160  return;
161  }
162 
163  if (dbfi.Size())
164  {
165  const FiniteElement &fe = *fes->GetFE(i);
167  dbfi[0]->AssembleElementMatrix(fe, *eltrans, elmat);
168  for (int k = 1; k < dbfi.Size(); k++)
169  {
170  dbfi[k]->AssembleElementMatrix(fe, *eltrans, elemmat);
171  elmat += elemmat;
172  }
173  }
174  else
175  {
177  elmat.SetSize(vdofs.Size());
178  elmat = 0.0;
179  }
180 }
181 
183  int i, const DenseMatrix &elmat, Array<int> &vdofs, int skip_zeros)
184 {
185  if (mat == NULL)
186  AllocMat();
187  fes->GetElementVDofs(i, vdofs);
188  mat->AddSubMatrix(vdofs, vdofs, elmat, skip_zeros);
189 }
190 
191 void BilinearForm::Assemble (int skip_zeros)
192 {
193  ElementTransformation *eltrans;
194  Mesh *mesh = fes -> GetMesh();
195 
196  int i;
197 
198  if (mat == NULL)
199  AllocMat();
200 
201 #ifdef MFEM_USE_OPENMP
202  int free_element_matrices = 0;
203  if (!element_matrices)
204  {
206  free_element_matrices = 1;
207  }
208 #endif
209 
210  if (dbfi.Size())
211  {
212  for (i = 0; i < fes -> GetNE(); i++)
213  {
215  if (element_matrices)
216  {
217  mat->AddSubMatrix(vdofs, vdofs, (*element_matrices)(i), skip_zeros);
218  }
219  else
220  {
221  const FiniteElement &fe = *fes->GetFE(i);
222  eltrans = fes->GetElementTransformation(i);
223  for (int k = 0; k < dbfi.Size(); k++)
224  {
225  dbfi[k]->AssembleElementMatrix(fe, *eltrans, elemmat);
226  mat->AddSubMatrix(vdofs, vdofs, elemmat, skip_zeros);
227  }
228  }
229  }
230  }
231 
232  if (bbfi.Size())
233  {
234  for (i = 0; i < fes -> GetNBE(); i++)
235  {
236  const FiniteElement &be = *fes->GetBE(i);
237  fes -> GetBdrElementVDofs (i, vdofs);
238  eltrans = fes -> GetBdrElementTransformation (i);
239  for (int k=0; k < bbfi.Size(); k++)
240  {
241  bbfi[k] -> AssembleElementMatrix(be, *eltrans, elemmat);
242  mat -> AddSubMatrix (vdofs, vdofs, elemmat, skip_zeros);
243  }
244  }
245  }
246 
247  if (fbfi.Size())
248  {
250  Array<int> vdofs2;
251 
252  int nfaces = mesh->GetNumFaces();
253  for (i = 0; i < nfaces; i++)
254  {
255  tr = mesh -> GetInteriorFaceTransformations (i);
256  if (tr != NULL)
257  {
258  fes -> GetElementVDofs (tr -> Elem1No, vdofs);
259  fes -> GetElementVDofs (tr -> Elem2No, vdofs2);
260  vdofs.Append (vdofs2);
261  for (int k = 0; k < fbfi.Size(); k++)
262  {
263  fbfi[k] -> AssembleFaceMatrix (*fes -> GetFE (tr -> Elem1No),
264  *fes -> GetFE (tr -> Elem2No),
265  *tr, elemmat);
266  mat -> AddSubMatrix (vdofs, vdofs, elemmat, skip_zeros);
267  }
268  }
269  }
270  }
271 
272  if (bfbfi.Size())
273  {
275  const FiniteElement *nfe = NULL;
276 
277  for (i = 0; i < fes -> GetNBE(); i++)
278  {
279  tr = mesh -> GetBdrFaceTransformations (i);
280  if (tr != NULL)
281  {
282  fes -> GetElementVDofs (tr -> Elem1No, vdofs);
283  for (int k = 0; k < bfbfi.Size(); k++)
284  {
285  bfbfi[k] -> AssembleFaceMatrix (*fes -> GetFE (tr -> Elem1No),
286  *nfe, *tr, elemmat);
287  mat -> AddSubMatrix (vdofs, vdofs, elemmat, skip_zeros);
288  }
289  }
290  }
291  }
292 
293 #ifdef MFEM_USE_OPENMP
294  if (free_element_matrices)
296 #endif
297 }
298 
300 {
301  // Do not remove zero entries to preserve the symmetric structure of the
302  // matrix which in turn will give rise to symmetric structure in the new
303  // matrix. This ensures that subsequent calls to EliminateRowCol will work
304  // correctly.
305  Finalize(0);
306 
308  if (!P) return; // assume conforming mesh
309 
310  SparseMatrix *R = Transpose(*P);
311  SparseMatrix *RA = mfem::Mult(*R, *mat);
312  delete mat;
313  if (mat_e)
314  {
315  SparseMatrix *RAe = mfem::Mult(*R, *mat_e);
316  delete mat_e;
317  mat_e = RAe;
318  }
319  delete R;
320  mat = mfem::Mult(*RA, *P);
321  delete RA;
322  if (mat_e)
323  {
324  SparseMatrix *RAeP = mfem::Mult(*mat_e, *P);
325  delete mat_e;
326  mat_e = RAeP;
327  }
328 
329  height = mat->Height();
330  width = mat->Width();
331 }
332 
334 {
335  if (element_matrices || dbfi.Size() == 0 || fes->GetNE() == 0)
336  return;
337 
338  int num_elements = fes->GetNE();
339  int num_dofs_per_el = fes->GetFE(0)->GetDof() * fes->GetVDim();
340 
341  element_matrices = new DenseTensor(num_dofs_per_el, num_dofs_per_el,
342  num_elements);
343 
344  DenseMatrix tmp;
346 
347 #ifdef MFEM_USE_OPENMP
348 #pragma omp parallel for private(tmp,eltrans)
349 #endif
350  for (int i = 0; i < num_elements; i++)
351  {
353  num_dofs_per_el, num_dofs_per_el);
354  const FiniteElement &fe = *fes->GetFE(i);
355 #ifdef MFEM_DEBUG
356  if (num_dofs_per_el != fe.GetDof()*fes->GetVDim())
357  mfem_error("BilinearForm::ComputeElementMatrices:"
358  " all elements must have same number of dofs");
359 #endif
360  fes->GetElementTransformation(i, &eltrans);
361 
362  dbfi[0]->AssembleElementMatrix(fe, eltrans, elmat);
363  for (int k = 1; k < dbfi.Size(); k++)
364  {
365  // note: some integrators may not be thread-safe
366  dbfi[k]->AssembleElementMatrix(fe, eltrans, tmp);
367  elmat += tmp;
368  }
369  elmat.ClearExternalData();
370  }
371 }
372 
374  Array<int> &bdr_attr_is_ess, Vector &sol, Vector &rhs, int d )
375 {
376  Array<int> ess_dofs, conf_ess_dofs;
377  fes->GetEssentialVDofs(bdr_attr_is_ess, ess_dofs);
378  if (fes->GetConformingProlongation() == NULL)
379  {
380  EliminateEssentialBCFromDofs(ess_dofs, sol, rhs, d);
381  }
382  else
383  {
384  fes->ConvertToConformingVDofs(ess_dofs, conf_ess_dofs);
385  EliminateEssentialBCFromDofs(conf_ess_dofs, sol, rhs, d);
386  }
387 }
388 
390  Array<int> &vdofs, Vector &sol, Vector &rhs, int d)
391 {
392  for (int i = 0; i < vdofs.Size(); i++)
393  {
394  int vdof = vdofs[i];
395  if ( vdof >= 0 )
396  mat -> EliminateRowCol (vdof, sol(vdof), rhs, d);
397  else
398  mat -> EliminateRowCol (-1-vdof, sol(-1-vdof), rhs, d);
399  }
400 }
401 
403 {
404  if (mat_e == NULL)
405  mat_e = new SparseMatrix(height);
406 
407  for (int i = 0; i < vdofs.Size(); i++)
408  {
409  int vdof = vdofs[i];
410  if ( vdof >= 0 )
411  mat -> EliminateRowCol (vdof, *mat_e, d);
412  else
413  mat -> EliminateRowCol (-1-vdof, *mat_e, d);
414  }
415 }
416 
418  Array<int> &vdofs, const Vector &x, Vector &b)
419 {
420  mat_e->AddMult(x, b, -1.);
421  mat->PartMult(vdofs, x, b);
422 }
423 
424 void BilinearForm::EliminateEssentialBC (Array<int> &bdr_attr_is_ess, int d)
425 {
426  Array<int> ess_dofs, conf_ess_dofs;
427  fes->GetEssentialVDofs(bdr_attr_is_ess, ess_dofs);
428  if (fes->GetConformingProlongation() == NULL)
429  {
430  EliminateEssentialBCFromDofs(ess_dofs, d);
431  }
432  else
433  {
434  fes->ConvertToConformingVDofs(ess_dofs, conf_ess_dofs);
435  EliminateEssentialBCFromDofs(conf_ess_dofs, d);
436  }
437 }
438 
440  Array<int> &ess_dofs, Vector &sol, Vector &rhs, int d )
441 {
442  MFEM_ASSERT(ess_dofs.Size() == height, "incorrect dof Array size");
443  MFEM_ASSERT(sol.Size() == height, "incorrect sol Vector size");
444  MFEM_ASSERT(rhs.Size() == height, "incorrect rhs Vector size");
445 
446  for (int i = 0; i < ess_dofs.Size(); i++)
447  if (ess_dofs[i] < 0)
448  mat -> EliminateRowCol (i, sol(i), rhs, d);
449 }
450 
452 {
453  MFEM_ASSERT(ess_dofs.Size() == height, "incorrect dof Array size");
454 
455  for (int i = 0; i < ess_dofs.Size(); i++)
456  if (ess_dofs[i] < 0)
457  mat -> EliminateRowCol (i, d);
458 }
459 
461 {
462  if (nfes) fes = nfes;
463 
464  delete mat_e;
465  delete mat;
467 
468  height = width = fes->GetVSize();
469 
470  mat = mat_e = NULL;
471 }
472 
474 {
475  delete mat_e;
476  delete mat;
477  delete element_matrices;
478 
479  if (!extern_bfs)
480  {
481  int k;
482  for (k=0; k < dbfi.Size(); k++) delete dbfi[k];
483  for (k=0; k < bbfi.Size(); k++) delete bbfi[k];
484  for (k=0; k < fbfi.Size(); k++) delete fbfi[k];
485  for (k=0; k < bfbfi.Size(); k++) delete bfbfi[k];
486  }
487 }
488 
489 
491  FiniteElementSpace *te_fes)
492  : Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
493 {
494  trial_fes = tr_fes;
495  test_fes = te_fes;
496  mat = NULL;
497 }
498 
499 double & MixedBilinearForm::Elem (int i, int j)
500 {
501  return (*mat)(i, j);
502 }
503 
504 const double & MixedBilinearForm::Elem (int i, int j) const
505 {
506  return (*mat)(i, j);
507 }
508 
509 void MixedBilinearForm::Mult (const Vector & x, Vector & y) const
510 {
511  mat -> Mult (x, y);
512 }
513 
515  const double a) const
516 {
517  mat -> AddMult (x, y, a);
518 }
519 
521  const double a) const
522 {
523  mat -> AddMultTranspose (x, y, a);
524 }
525 
527 {
528  return mat -> Inverse ();
529 }
530 
531 void MixedBilinearForm::Finalize (int skip_zeros)
532 {
533  mat -> Finalize (skip_zeros);
534 }
535 
537 {
540  mfem_error("MixedBilinearForm::GetBlocks :\n"
541  " Both trial and test spaces must use Ordering::byNODES!");
542 
543  blocks.SetSize(test_fes->GetVDim(), trial_fes->GetVDim());
544 
545  mat->GetBlocks(blocks);
546 }
547 
549 {
550  dom.Append (bfi);
551 }
552 
554 {
555  bdr.Append (bfi);
556 }
557 
559 {
560  skt.Append (bfi);
561 }
562 
563 void MixedBilinearForm::Assemble (int skip_zeros)
564 {
565  int i, k;
566  Array<int> tr_vdofs, te_vdofs;
567  ElementTransformation *eltrans;
568  DenseMatrix elemmat;
569 
570  Mesh *mesh = test_fes -> GetMesh();
571 
572  if (mat == NULL)
573  mat = new SparseMatrix(height, width);
574 
575  if (dom.Size())
576  {
577  for (i = 0; i < test_fes -> GetNE(); i++)
578  {
579  trial_fes -> GetElementVDofs (i, tr_vdofs);
580  test_fes -> GetElementVDofs (i, te_vdofs);
581  eltrans = test_fes -> GetElementTransformation (i);
582  for (k = 0; k < dom.Size(); k++)
583  {
584  dom[k] -> AssembleElementMatrix2 (*trial_fes -> GetFE(i),
585  *test_fes -> GetFE(i),
586  *eltrans, elemmat);
587  mat -> AddSubMatrix (te_vdofs, tr_vdofs, elemmat, skip_zeros);
588  }
589  }
590  }
591 
592  if (bdr.Size())
593  {
594  for (i = 0; i < test_fes -> GetNBE(); i++)
595  {
596  trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
597  test_fes -> GetBdrElementVDofs (i, te_vdofs);
598  eltrans = test_fes -> GetBdrElementTransformation (i);
599  for (k = 0; k < bdr.Size(); k++)
600  {
601  bdr[k] -> AssembleElementMatrix2 (*trial_fes -> GetBE(i),
602  *test_fes -> GetBE(i),
603  *eltrans, elemmat);
604  mat -> AddSubMatrix (te_vdofs, tr_vdofs, elemmat, skip_zeros);
605  }
606  }
607  }
608 
609  if (skt.Size())
610  {
612  Array<int> te_vdofs2;
613  const FiniteElement *trial_face_fe, *test_fe1, *test_fe2;
614 
615  int nfaces = mesh->GetNumFaces();
616  for (i = 0; i < nfaces; i++)
617  {
618  ftr = mesh->GetFaceElementTransformations(i);
619  trial_fes->GetFaceVDofs(i, tr_vdofs);
620  test_fes->GetElementVDofs(ftr->Elem1No, te_vdofs);
621  trial_face_fe = trial_fes->GetFaceElement(i);
622  test_fe1 = test_fes->GetFE(ftr->Elem1No);
623  if (ftr->Elem2No >= 0)
624  {
625  test_fes->GetElementVDofs(ftr->Elem2No, te_vdofs2);
626  te_vdofs.Append(te_vdofs2);
627  test_fe2 = test_fes->GetFE(ftr->Elem2No);
628  }
629  else
630  test_fe2 = NULL;
631  for (int k = 0; k < skt.Size(); k++)
632  {
633  skt[k]->AssembleFaceMatrix(*trial_face_fe, *test_fe1, *test_fe2,
634  *ftr, elemmat);
635  mat->AddSubMatrix(te_vdofs, tr_vdofs, elemmat, skip_zeros);
636  }
637  }
638  }
639 }
640 
642 {
643  Finalize();
644 
646  if (P2)
647  {
648  SparseMatrix *R = Transpose(*P2);
649  SparseMatrix *RA = mfem::Mult(*R, *mat);
650  delete R;
651  delete mat;
652  mat = RA;
653  }
654 
656  if (P1)
657  {
658  SparseMatrix *RAP = mfem::Mult(*mat, *P1);
659  delete mat;
660  mat = RAP;
661  }
662 
663  height = mat->Height();
664  width = mat->Width();
665 }
666 
668  Array<int> &bdr_attr_is_ess, Vector &sol, Vector &rhs )
669 {
670  int i, j, k;
671  Array<int> tr_vdofs, cols_marker (trial_fes -> GetVSize());
672 
673  cols_marker = 0;
674  for (i = 0; i < trial_fes -> GetNBE(); i++)
675  if (bdr_attr_is_ess[trial_fes -> GetBdrAttribute (i)-1])
676  {
677  trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
678  for (j = 0; j < tr_vdofs.Size(); j++)
679  {
680  if ( (k = tr_vdofs[j]) < 0 )
681  k = -1-k;
682  cols_marker[k] = 1;
683  }
684  }
685  mat -> EliminateCols (cols_marker, &sol, &rhs);
686 }
687 
689  Array<int> &marked_vdofs, Vector &sol, Vector &rhs)
690 {
691  mat -> EliminateCols (marked_vdofs, &sol, &rhs);
692 }
693 
695 {
696  int i, j, k;
697  Array<int> te_vdofs;
698 
699  for (i = 0; i < test_fes -> GetNBE(); i++)
700  if (bdr_attr_is_ess[test_fes -> GetBdrAttribute (i)-1])
701  {
702  test_fes -> GetBdrElementVDofs (i, te_vdofs);
703  for (j = 0; j < te_vdofs.Size(); j++)
704  {
705  if ( (k = te_vdofs[j]) < 0 )
706  k = -1-k;
707  mat -> EliminateRow (k);
708  }
709  }
710 }
711 
713 {
714  delete mat;
715  mat = NULL;
716  height = test_fes->GetVSize();
717  width = trial_fes->GetVSize();
718 }
719 
721 {
722  int i;
723 
724  if (mat) delete mat;
725  for (i = 0; i < dom.Size(); i++) delete dom[i];
726  for (i = 0; i < bdr.Size(); i++) delete bdr[i];
727  for (i = 0; i < skt.Size(); i++) delete skt[i];
728 }
729 
730 
732 {
733  Array<int> dom_vdofs, ran_vdofs;
735  const FiniteElement *dom_fe, *ran_fe;
736  DenseMatrix totelmat, elmat;
737 
738  if (mat == NULL)
739  mat = new SparseMatrix(height, width);
740 
741  if (dom.Size() > 0)
742  for (int i = 0; i < test_fes->GetNE(); i++)
743  {
744  trial_fes->GetElementVDofs(i, dom_vdofs);
745  test_fes->GetElementVDofs(i, ran_vdofs);
747  dom_fe = trial_fes->GetFE(i);
748  ran_fe = test_fes->GetFE(i);
749 
750  dom[0]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, totelmat);
751  for (int j = 1; j < dom.Size(); j++)
752  {
753  dom[j]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, elmat);
754  totelmat += elmat;
755  }
756  mat->SetSubMatrix(ran_vdofs, dom_vdofs, totelmat, skip_zeros);
757  }
758 }
759 
760 }
Abstract class for Finite Elements.
Definition: fe.hpp:42
void EliminateEssentialBCFromDofs(Array< int > &ess_dofs, Vector &sol, Vector &rhs, int d=0)
int Size() const
Logical size of the array.
Definition: array.hpp:108
int GetVSize() const
Definition: fespace.hpp:151
Array< BilinearFormIntegrator * > * GetBBFI()
int * GetJ()
Definition: table.hpp:88
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
virtual void AddMult(const Vector &x, Vector &y, const double a=1.0) const
Array< BilinearFormIntegrator * > skt
virtual MatrixInverse * Inverse() const
Returns a pointer to (approximation) of the matrix inverse.
Array< BilinearFormIntegrator * > fbfi
Set of interior face Integrators to be applied.
void Assemble(int skip_zeros=1)
Assembles the form i.e. sums over all domain/bdr integrators.
Array< BilinearFormIntegrator * > * GetDBFI()
Array< BilinearFormIntegrator * > dbfi
Set of Domain Integrators to be applied.
Array< BilinearFormIntegrator * > * GetBFBFI()
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:351
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols.
Definition: operator.hpp:41
Data type dense matrix.
Definition: densemat.hpp:22
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:318
int Size() const
Returns the size of the vector.
Definition: vector.hpp:76
Abstract data type for matrix inverse.
Definition: matrix.hpp:58
void LoseData()
Call this if data has been stolen.
Definition: table.hpp:112
const FiniteElement * GetFaceElement(int i) const
Definition: fespace.cpp:998
virtual void Finalize(int skip_zeros=1)
Finalizes the matrix initialization.
Array< BilinearFormIntegrator * > * GetFBFI()
MixedBilinearForm(FiniteElementSpace *tr_fes, FiniteElementSpace *te_fes)
FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31)
Definition: mesh.cpp:499
void GetBlocks(Array2D< SparseMatrix * > &blocks) const
Definition: sparsemat.cpp:601
SparseMatrix * GetConformingProlongation()
Definition: fespace.hpp:137
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
Definition: mesh.cpp:3083
void EliminateEssentialBCFromTrialDofs(Array< int > &marked_vdofs, Vector &sol, Vector &rhs)
Array< BilinearFormIntegrator * > bdr
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
int GetNE() const
Returns number of elements in the mesh.
Definition: fespace.hpp:169
void EliminateVDofs(Array< int > &vdofs, Vector &sol, Vector &rhs, int d=0)
Here, vdofs is a list of DOFs.
void SetSize(int m, int n)
Definition: array.hpp:226
virtual void AddMultTranspose(const Vector &x, Vector &y, const double a=1.0) const
Data type sparse matrix.
Definition: sparsemat.hpp:38
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows.
Definition: operator.hpp:35
int Append(const T &el)
Append element to array, resize if necessary.
Definition: array.hpp:330
Mesh * GetMesh() const
Returns the mesh.
Definition: fespace.hpp:132
SparseMatrix * mat
Sparse matrix to be associated with the form.
Abstract data type matrix.
Definition: matrix.hpp:27
HypreParMatrix * RAP(HypreParMatrix *A, HypreParMatrix *P)
Returns the matrix P^t * A * P.
Definition: hypre.cpp:781
void Assemble(int skip_zeros=1)
void Transpose(const Table &A, Table &At, int _ncols_A)
Transpose a Table.
Definition: table.cpp:305
double * GetData(int k)
Definition: densemat.hpp:461
void Update(FiniteElementSpace *nfes=NULL)
void EliminateTrialDofs(Array< int > &bdr_attr_is_ess, Vector &sol, Vector &rhs)
int GetVDim() const
Returns vector dimension.
Definition: fespace.hpp:143
void AddTraceFaceIntegrator(BilinearFormIntegrator *bfi)
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
Definition: sparsemat.cpp:1468
void GetBlocks(Array2D< SparseMatrix * > &blocks) const
void SetSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
Definition: sparsemat.cpp:1544
int SizeI() const
Definition: densemat.hpp:442
void ComputeElementMatrix(int i, DenseMatrix &elmat)
int GetOrdering() const
Return the ordering method.
Definition: fespace.hpp:160
SparseMatrix * mat_e
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i&#39;th element.
Definition: fespace.hpp:190
Abstract base class BilinearFormIntegrator.
Definition: bilininteg.hpp:22
void AssembleElementMatrix(int i, const DenseMatrix &elmat, Array< int > &vdofs, int skip_zeros=1)
Abstract finite element space.
Definition: fespace.hpp:61
int GetDof() const
Returns the degrees of freedom in the FE space.
Definition: fe.hpp:86
Array< BilinearFormIntegrator * > bfbfi
Set of boundary face Integrators to be applied.
Array< BilinearFormIntegrator * > bbfi
Set of Boundary Integrators to be applied.
DenseTensor * element_matrices
void mfem_error(const char *msg)
Definition: error.cpp:23
void ClearExternalData()
Definition: densemat.hpp:57
void GetElementVDofs(int i, Array< int > &dofs) const
Returns indexes of degrees of freedom in array dofs for i&#39;th element.
Definition: fespace.cpp:117
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
Array< BilinearFormIntegrator * > dom
virtual void GetEssentialVDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_dofs) const
Determine the boundary degrees of freedom.
Definition: fespace.cpp:362
void GetFaceVDofs(int iF, Array< int > &dofs) const
Returns indexes of degrees of freedom for i&#39;th face element (2D and 3D).
Definition: fespace.cpp:129
Table * GetFaceToElementTable() const
Definition: mesh.cpp:3506
FiniteElementSpace * test_fes
int SizeJ() const
Definition: densemat.hpp:443
void ConvertToConformingVDofs(const Array< int > &dofs, Array< int > &cdofs)
Definition: fespace.hpp:295
virtual void EliminateTestDofs(Array< int > &bdr_attr_is_ess)
void EliminateVDofsInRHS(Array< int > &vdofs, const Vector &x, Vector &b)
virtual void Finalize(int skip_zeros=1)
Finalizes the matrix initialization.
void AddBoundaryIntegrator(BilinearFormIntegrator *bfi)
Adds new Boundary Integrator.
void AddInteriorFaceIntegrator(BilinearFormIntegrator *bfi)
Adds new interior Face Integrator.
FiniteElementSpace * fes
FE space on which the form lives.
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
Adds new Domain Integrator.
void ComputeElementMatrices()
Compute and store internally all element matrices.
const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement associated with i&#39;th element.
Definition: fespace.cpp:814
DenseMatrix elemmat
FiniteElementSpace * trial_fes
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
virtual ~BilinearForm()
Destroys bilinear form.
Vector data type.
Definition: vector.hpp:29
void AddBoundaryIntegrator(BilinearFormIntegrator *bfi)
virtual MatrixInverse * Inverse() const
Returns a pointer to (an approximation) of the matrix inverse.
int * GetI()
Definition: table.hpp:87
const Table & GetElementToDofTable() const
Definition: fespace.hpp:257
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement for the i&#39;th boundary element.
Definition: fespace.cpp:976
Array< int > vdofs
void SetSize(int s)
If the matrix is not a square matrix of size s then recreate it.
Definition: densemat.cpp:73
void FreeElementMatrices()
Free the memory used by the element matrices.
virtual void Assemble(int skip_zeros=1)
Rank 3 tensor (array of matrices)
Definition: densemat.hpp:428
void EliminateEssentialBC(Array< int > &bdr_attr_is_ess, Vector &sol, Vector &rhs, int d=0)
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
void AddBdrFaceIntegrator(BilinearFormIntegrator *bfi)
Adds new boundary Face Integrator.
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
Definition: sparsemat.cpp:432