MFEM  v3.3
Finite element discretization library
 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.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 // Implementation of class BilinearForm
13 
14 #include "fem.hpp"
15 #include <cmath>
16 
17 namespace mfem
18 {
19 
21 {
22  if (static_cond) { return; }
23 
24  if (precompute_sparsity == 0 || fes->GetVDim() > 1)
25  {
26  mat = new SparseMatrix(height);
27  return;
28  }
29 
30  const Table &elem_dof = fes->GetElementToDofTable();
31  Table dof_dof;
32 
33  if (fbfi.Size() > 0)
34  {
35  // the sparsity pattern is defined from the map: face->element->dof
36  Table face_dof, dof_face;
37  {
38  Table *face_elem = fes->GetMesh()->GetFaceToElementTable();
39  mfem::Mult(*face_elem, elem_dof, face_dof);
40  delete face_elem;
41  }
42  Transpose(face_dof, dof_face, height);
43  mfem::Mult(dof_face, face_dof, dof_dof);
44  }
45  else
46  {
47  // the sparsity pattern is defined from the map: element->dof
48  Table dof_elem;
49  Transpose(elem_dof, dof_elem, height);
50  mfem::Mult(dof_elem, elem_dof, dof_dof);
51  }
52 
53  dof_dof.SortRows();
54 
55  int *I = dof_dof.GetI();
56  int *J = dof_dof.GetJ();
57  double *data = new double[I[height]];
58 
59  mat = new SparseMatrix(I, J, data, height, height, true, true, true);
60  *mat = 0.0;
61 
62  dof_dof.LoseData();
63 }
64 
66  : Matrix (f->GetVSize())
67 {
68  fes = f;
69  sequence = f->GetSequence();
70  mat = mat_e = NULL;
71  extern_bfs = 0;
72  element_matrices = NULL;
73  static_cond = NULL;
74  hybridization = NULL;
76 }
77 
79  : Matrix (f->GetVSize())
80 {
81  int i;
83 
84  fes = f;
85  sequence = f->GetSequence();
86  mat_e = NULL;
87  extern_bfs = 1;
88  element_matrices = NULL;
89  static_cond = NULL;
90  hybridization = NULL;
92 
93  bfi = bf->GetDBFI();
94  dbfi.SetSize (bfi->Size());
95  for (i = 0; i < bfi->Size(); i++)
96  {
97  dbfi[i] = (*bfi)[i];
98  }
99 
100  bfi = bf->GetBBFI();
101  bbfi.SetSize (bfi->Size());
102  for (i = 0; i < bfi->Size(); i++)
103  {
104  bbfi[i] = (*bfi)[i];
105  }
106 
107  bfi = bf->GetFBFI();
108  fbfi.SetSize (bfi->Size());
109  for (i = 0; i < bfi->Size(); i++)
110  {
111  fbfi[i] = (*bfi)[i];
112  }
113 
114  bfi = bf->GetBFBFI();
115  bfbfi.SetSize (bfi->Size());
116  for (i = 0; i < bfi->Size(); i++)
117  {
118  bfbfi[i] = (*bfi)[i];
119  }
120 
121  AllocMat();
122 }
123 
125 {
126  delete static_cond;
129  {
130  bool symmetric = false; // TODO
131  bool block_diagonal = false; // TODO
132  static_cond->Init(symmetric, block_diagonal);
133  }
134  else
135  {
136  delete static_cond;
137  static_cond = NULL;
138  }
139 }
140 
142  BilinearFormIntegrator *constr_integ,
143  const Array<int> &ess_tdof_list)
144 {
145  delete hybridization;
146  hybridization = new Hybridization(fes, constr_space);
147  hybridization->SetConstraintIntegrator(constr_integ);
148  hybridization->Init(ess_tdof_list);
149 }
150 
151 void BilinearForm::UseSparsity(int *I, int *J, bool isSorted)
152 {
153  if (static_cond) { return; }
154 
155  if (mat)
156  {
157  if (mat->Finalized() && mat->GetI() == I && mat->GetJ() == J)
158  {
159  return; // mat is already using the given sparsity
160  }
161  delete mat;
162  }
163  height = width = fes->GetVSize();
164  mat = new SparseMatrix(I, J, NULL, height, width, false, true, isSorted);
165 }
166 
168 {
169  MFEM_ASSERT(A.Height() == fes->GetVSize() && A.Width() == fes->GetVSize(),
170  "invalid matrix A dimensions: "
171  << A.Height() << " x " << A.Width());
172  MFEM_ASSERT(A.Finalized(), "matrix A must be Finalized");
173 
174  UseSparsity(A.GetI(), A.GetJ(), A.areColumnsSorted());
175 }
176 
177 double& BilinearForm::Elem (int i, int j)
178 {
179  return mat -> Elem(i,j);
180 }
181 
182 const double& BilinearForm::Elem (int i, int j) const
183 {
184  return mat -> Elem(i,j);
185 }
186 
187 void BilinearForm::Mult (const Vector & x, Vector & y) const
188 {
189  mat -> Mult (x, y);
190 }
191 
193 {
194  return mat -> Inverse();
195 }
196 
197 void BilinearForm::Finalize (int skip_zeros)
198 {
199  if (!static_cond) { mat->Finalize(skip_zeros); }
200  if (mat_e) { mat_e->Finalize(skip_zeros); }
201  if (static_cond) { static_cond->Finalize(); }
203 }
204 
206 {
207  dbfi.Append (bfi);
208 }
209 
211 {
212  bbfi.Append (bfi);
213 }
214 
216 {
217  fbfi.Append (bfi);
218 }
219 
221 {
222  bfbfi.Append(bfi);
223  bfbfi_marker.Append(NULL); // NULL marker means apply everywhere
224 }
225 
227  Array<int> &bdr_marker)
228 {
229  bfbfi.Append(bfi);
230  bfbfi_marker.Append(&bdr_marker);
231 }
232 
234 {
235  if (element_matrices)
236  {
238  elmat = element_matrices->GetData(i);
239  return;
240  }
241 
242  if (dbfi.Size())
243  {
244  const FiniteElement &fe = *fes->GetFE(i);
246  dbfi[0]->AssembleElementMatrix(fe, *eltrans, elmat);
247  for (int k = 1; k < dbfi.Size(); k++)
248  {
249  dbfi[k]->AssembleElementMatrix(fe, *eltrans, elemmat);
250  elmat += elemmat;
251  }
252  }
253  else
254  {
256  elmat.SetSize(vdofs.Size());
257  elmat = 0.0;
258  }
259 }
260 
262  int i, const DenseMatrix &elmat, Array<int> &vdofs, int skip_zeros)
263 {
264  fes->GetElementVDofs(i, vdofs);
265  if (static_cond)
266  {
267  static_cond->AssembleMatrix(i, elmat);
268  }
269  else
270  {
271  if (mat == NULL)
272  {
273  AllocMat();
274  }
275  mat->AddSubMatrix(vdofs, vdofs, elmat, skip_zeros);
276  if (hybridization)
277  {
278  hybridization->AssembleMatrix(i, elmat);
279  }
280  }
281 }
282 
284  int i, const DenseMatrix &elmat, Array<int> &vdofs, int skip_zeros)
285 {
286  fes->GetBdrElementVDofs(i, vdofs);
287  if (static_cond)
288  {
289  static_cond->AssembleBdrMatrix(i, elmat);
290  }
291  else
292  {
293  if (mat == NULL)
294  {
295  AllocMat();
296  }
297  mat->AddSubMatrix(vdofs, vdofs, elmat, skip_zeros);
298  if (hybridization)
299  {
300  hybridization->AssembleBdrMatrix(i, elmat);
301  }
302  }
303 }
304 
305 void BilinearForm::Assemble (int skip_zeros)
306 {
307  ElementTransformation *eltrans;
308  Mesh *mesh = fes -> GetMesh();
309  DenseMatrix elmat, *elmat_p;
310 
311  int i;
312 
313  if (mat == NULL)
314  {
315  AllocMat();
316  }
317 
318 #ifdef MFEM_USE_OPENMP
319  int free_element_matrices = 0;
320  if (!element_matrices)
321  {
323  free_element_matrices = 1;
324  }
325 #endif
326 
327  if (dbfi.Size())
328  {
329  for (i = 0; i < fes -> GetNE(); i++)
330  {
332  if (element_matrices)
333  {
334  elmat_p = &(*element_matrices)(i);
335  }
336  else
337  {
338  const FiniteElement &fe = *fes->GetFE(i);
339  eltrans = fes->GetElementTransformation(i);
340  dbfi[0]->AssembleElementMatrix(fe, *eltrans, elmat);
341  for (int k = 1; k < dbfi.Size(); k++)
342  {
343  dbfi[k]->AssembleElementMatrix(fe, *eltrans, elemmat);
344  elmat += elemmat;
345  }
346  elmat_p = &elmat;
347  }
348  if (static_cond)
349  {
350  static_cond->AssembleMatrix(i, *elmat_p);
351  }
352  else
353  {
354  mat->AddSubMatrix(vdofs, vdofs, *elmat_p, skip_zeros);
355  if (hybridization)
356  {
357  hybridization->AssembleMatrix(i, *elmat_p);
358  }
359  }
360  }
361  }
362 
363  if (bbfi.Size())
364  {
365  for (i = 0; i < fes -> GetNBE(); i++)
366  {
367  const FiniteElement &be = *fes->GetBE(i);
368  fes -> GetBdrElementVDofs (i, vdofs);
369  eltrans = fes -> GetBdrElementTransformation (i);
370  bbfi[0]->AssembleElementMatrix(be, *eltrans, elmat);
371  for (int k = 1; k < bbfi.Size(); k++)
372  {
373  bbfi[k]->AssembleElementMatrix(be, *eltrans, elemmat);
374  elmat += elemmat;
375  }
376  if (!static_cond)
377  {
378  mat->AddSubMatrix(vdofs, vdofs, elmat, skip_zeros);
379  if (hybridization)
380  {
381  hybridization->AssembleBdrMatrix(i, elmat);
382  }
383  }
384  else
385  {
386  static_cond->AssembleBdrMatrix(i, elmat);
387  }
388  }
389  }
390 
391  if (fbfi.Size())
392  {
394  Array<int> vdofs2;
395 
396  int nfaces = mesh->GetNumFaces();
397  for (i = 0; i < nfaces; i++)
398  {
399  tr = mesh -> GetInteriorFaceTransformations (i);
400  if (tr != NULL)
401  {
402  fes -> GetElementVDofs (tr -> Elem1No, vdofs);
403  fes -> GetElementVDofs (tr -> Elem2No, vdofs2);
404  vdofs.Append (vdofs2);
405  for (int k = 0; k < fbfi.Size(); k++)
406  {
407  fbfi[k] -> AssembleFaceMatrix (*fes -> GetFE (tr -> Elem1No),
408  *fes -> GetFE (tr -> Elem2No),
409  *tr, elemmat);
410  mat -> AddSubMatrix (vdofs, vdofs, elemmat, skip_zeros);
411  }
412  }
413  }
414  }
415 
416  if (bfbfi.Size())
417  {
419  const FiniteElement *fe1, *fe2;
420 
421  // Which boundary attributes need to be processed?
422  Array<int> bdr_attr_marker(mesh->bdr_attributes.Size() ?
423  mesh->bdr_attributes.Max() : 0);
424  bdr_attr_marker = 0;
425  for (int k = 0; k < bfbfi.Size(); k++)
426  {
427  if (bfbfi_marker[k] == NULL)
428  {
429  bdr_attr_marker = 1;
430  break;
431  }
432  Array<int> &bdr_marker = *bfbfi_marker[k];
433  MFEM_ASSERT(bdr_marker.Size() == bdr_attr_marker.Size(),
434  "invalid boundary marker for boundary face integrator #"
435  << k << ", counting from zero");
436  for (int i = 0; i < bdr_attr_marker.Size(); i++)
437  {
438  bdr_attr_marker[i] |= bdr_marker[i];
439  }
440  }
441 
442  for (i = 0; i < fes -> GetNBE(); i++)
443  {
444  const int bdr_attr = mesh->GetBdrAttribute(i);
445  if (bdr_attr_marker[bdr_attr-1] == 0) { continue; }
446 
447  tr = mesh -> GetBdrFaceTransformations (i);
448  if (tr != NULL)
449  {
450  fes -> GetElementVDofs (tr -> Elem1No, vdofs);
451  fe1 = fes -> GetFE (tr -> Elem1No);
452  // The fe2 object is really a dummy and not used on the boundaries,
453  // but we can't dereference a NULL pointer, and we don't want to
454  // actually make a fake element.
455  fe2 = fe1;
456  for (int k = 0; k < bfbfi.Size(); k++)
457  {
458  if (bfbfi_marker[k] &&
459  (*bfbfi_marker[k])[bdr_attr-1] == 0) { continue; }
460 
461  bfbfi[k] -> AssembleFaceMatrix (*fe1, *fe2, *tr, elemmat);
462  mat -> AddSubMatrix (vdofs, vdofs, elemmat, skip_zeros);
463  }
464  }
465  }
466  }
467 
468 #ifdef MFEM_USE_OPENMP
469  if (free_element_matrices)
470  {
472  }
473 #endif
474 }
475 
477 {
478  // Do not remove zero entries to preserve the symmetric structure of the
479  // matrix which in turn will give rise to symmetric structure in the new
480  // matrix. This ensures that subsequent calls to EliminateRowCol will work
481  // correctly.
482  Finalize(0);
483  MFEM_ASSERT(mat, "the BilinearForm is not assembled");
484 
486  if (!P) { return; } // conforming mesh
487 
488  SparseMatrix *R = Transpose(*P);
489  SparseMatrix *RA = mfem::Mult(*R, *mat);
490  delete mat;
491  if (mat_e)
492  {
493  SparseMatrix *RAe = mfem::Mult(*R, *mat_e);
494  delete mat_e;
495  mat_e = RAe;
496  }
497  delete R;
498  mat = mfem::Mult(*RA, *P);
499  delete RA;
500  if (mat_e)
501  {
502  SparseMatrix *RAeP = mfem::Mult(*mat_e, *P);
503  delete mat_e;
504  mat_e = RAeP;
505  }
506 
507  height = mat->Height();
508  width = mat->Width();
509 }
510 
511 void BilinearForm::FormLinearSystem(const Array<int> &ess_tdof_list,
512  Vector &x, Vector &b,
513  SparseMatrix &A, Vector &X, Vector &B,
514  int copy_interior)
515 {
517 
518  FormSystemMatrix(ess_tdof_list, A);
519 
520  // Transform the system and perform the elimination in B, based on the
521  // essential BC values from x. Restrict the BC part of x in X, and set the
522  // non-BC part to zero. Since there is no good initial guess for the Lagrange
523  // multipliers, set X = 0.0 for hybridization.
524  if (static_cond)
525  {
526  // Schur complement reduction to the exposed dofs
527  static_cond->ReduceSystem(x, b, X, B, copy_interior);
528  }
529  else if (!P) // conforming space
530  {
531  if (hybridization)
532  {
533  // Reduction to the Lagrange multipliers system
534  EliminateVDofsInRHS(ess_tdof_list, x, b);
535  hybridization->ReduceRHS(b, B);
536  X.SetSize(B.Size());
537  X = 0.0;
538  }
539  else
540  {
541  // A, X and B point to the same data as mat, x and b
542  EliminateVDofsInRHS(ess_tdof_list, x, b);
543  X.NewDataAndSize(x.GetData(), x.Size());
544  B.NewDataAndSize(b.GetData(), b.Size());
545  if (!copy_interior) { X.SetSubVectorComplement(ess_tdof_list, 0.0); }
546  }
547  }
548  else // non-conforming space
549  {
550  if (hybridization)
551  {
552  // Reduction to the Lagrange multipliers system
554  Vector conf_b(P->Width()), conf_x(P->Width());
555  P->MultTranspose(b, conf_b);
556  R->Mult(x, conf_x);
557  EliminateVDofsInRHS(ess_tdof_list, conf_x, conf_b);
558  R->MultTranspose(conf_b, b); // store eliminated rhs in b
559  hybridization->ReduceRHS(conf_b, B);
560  X.SetSize(B.Size());
561  X = 0.0;
562  }
563  else
564  {
565  // Variational restriction with P
567  B.SetSize(P->Width());
568  P->MultTranspose(b, B);
569  X.SetSize(R->Height());
570  R->Mult(x, X);
571  EliminateVDofsInRHS(ess_tdof_list, X, B);
572  if (!copy_interior) { X.SetSubVectorComplement(ess_tdof_list, 0.0); }
573  }
574  }
575 }
576 
577 void BilinearForm::FormSystemMatrix(const Array<int> &ess_tdof_list,
578  SparseMatrix &A)
579 {
580  // Finish the matrix assembly and perform BC elimination, storing the
581  // eliminated part of the matrix.
582  const int keep_diag = 1;
583  if (static_cond)
584  {
586  {
587  static_cond->SetEssentialTrueDofs(ess_tdof_list);
588  static_cond->Finalize(); // finalize Schur complement (to true dofs)
590  static_cond->Finalize(); // finalize eliminated part
591  }
593  }
594  else
595  {
596  if (!mat_e)
597  {
599  if (P) { ConformingAssemble(); }
600  EliminateVDofs(ess_tdof_list, keep_diag);
601  const int remove_zeros = 0;
602  Finalize(remove_zeros);
603  }
604  if (hybridization)
605  {
607  }
608  else
609  {
610  A.MakeRef(*mat);
611  }
612  }
613 }
614 
616  const Vector &b, Vector &x)
617 {
619  if (!P) // conforming space
620  {
621  if (static_cond)
622  {
623  // Private dofs back solve
624  static_cond->ComputeSolution(b, X, x);
625  }
626  else if (hybridization)
627  {
628  // Primal unknowns recovery
629  hybridization->ComputeSolution(b, X, x);
630  }
631  else
632  {
633  // X and x point to the same data
634  }
635  }
636  else // non-conforming space
637  {
638  if (static_cond)
639  {
640  // Private dofs back solve
641  static_cond->ComputeSolution(b, X, x);
642  }
643  else if (hybridization)
644  {
645  // Primal unknowns recovery
646  Vector conf_b(P->Width()), conf_x(P->Width());
647  P->MultTranspose(b, conf_b);
649  R->Mult(x, conf_x); // get essential b.c. from x
650  hybridization->ComputeSolution(conf_b, X, conf_x);
651  x.SetSize(P->Height());
652  P->Mult(conf_x, x);
653  }
654  else
655  {
656  // Apply conforming prolongation
657  x.SetSize(P->Height());
658  P->Mult(X, x);
659  }
660  }
661 }
662 
664 {
665  if (element_matrices || dbfi.Size() == 0 || fes->GetNE() == 0)
666  {
667  return;
668  }
669 
670  int num_elements = fes->GetNE();
671  int num_dofs_per_el = fes->GetFE(0)->GetDof() * fes->GetVDim();
672 
673  element_matrices = new DenseTensor(num_dofs_per_el, num_dofs_per_el,
674  num_elements);
675 
676  DenseMatrix tmp;
678 
679 #ifdef MFEM_USE_OPENMP
680  #pragma omp parallel for private(tmp,eltrans)
681 #endif
682  for (int i = 0; i < num_elements; i++)
683  {
685  num_dofs_per_el, num_dofs_per_el);
686  const FiniteElement &fe = *fes->GetFE(i);
687 #ifdef MFEM_DEBUG
688  if (num_dofs_per_el != fe.GetDof()*fes->GetVDim())
689  mfem_error("BilinearForm::ComputeElementMatrices:"
690  " all elements must have same number of dofs");
691 #endif
692  fes->GetElementTransformation(i, &eltrans);
693 
694  dbfi[0]->AssembleElementMatrix(fe, eltrans, elmat);
695  for (int k = 1; k < dbfi.Size(); k++)
696  {
697  // note: some integrators may not be thread-safe
698  dbfi[k]->AssembleElementMatrix(fe, eltrans, tmp);
699  elmat += tmp;
700  }
701  elmat.ClearExternalData();
702  }
703 }
704 
705 void BilinearForm::EliminateEssentialBC(const Array<int> &bdr_attr_is_ess,
706  Vector &sol, Vector &rhs, int d)
707 {
708  Array<int> ess_dofs, conf_ess_dofs;
709  fes->GetEssentialVDofs(bdr_attr_is_ess, ess_dofs);
710 
711  if (fes->GetVSize() == height)
712  {
713  EliminateEssentialBCFromDofs(ess_dofs, sol, rhs, d);
714  }
715  else
716  {
717  fes->GetRestrictionMatrix()->BooleanMult(ess_dofs, conf_ess_dofs);
718  EliminateEssentialBCFromDofs(conf_ess_dofs, sol, rhs, d);
719  }
720 }
721 
722 void BilinearForm::EliminateEssentialBC(const Array<int> &bdr_attr_is_ess,
723  int d)
724 {
725  Array<int> ess_dofs, conf_ess_dofs;
726  fes->GetEssentialVDofs(bdr_attr_is_ess, ess_dofs);
727 
728  if (fes->GetVSize() == height)
729  {
730  EliminateEssentialBCFromDofs(ess_dofs, d);
731  }
732  else
733  {
734  fes->GetRestrictionMatrix()->BooleanMult(ess_dofs, conf_ess_dofs);
735  EliminateEssentialBCFromDofs(conf_ess_dofs, d);
736  }
737 }
738 
740  double value)
741 {
742  Array<int> ess_dofs, conf_ess_dofs;
743  fes->GetEssentialVDofs(bdr_attr_is_ess, ess_dofs);
744 
745  if (fes->GetVSize() == height)
746  {
747  EliminateEssentialBCFromDofsDiag(ess_dofs, value);
748  }
749  else
750  {
751  fes->GetRestrictionMatrix()->BooleanMult(ess_dofs, conf_ess_dofs);
752  EliminateEssentialBCFromDofsDiag(conf_ess_dofs, value);
753  }
754 }
755 
757  Vector &sol, Vector &rhs, int d)
758 {
759  for (int i = 0; i < vdofs.Size(); i++)
760  {
761  int vdof = vdofs[i];
762  if ( vdof >= 0 )
763  {
764  mat -> EliminateRowCol (vdof, sol(vdof), rhs, d);
765  }
766  else
767  {
768  mat -> EliminateRowCol (-1-vdof, sol(-1-vdof), rhs, d);
769  }
770  }
771 }
772 
773 void BilinearForm::EliminateVDofs(const Array<int> &vdofs, int d)
774 {
775  if (mat_e == NULL)
776  {
777  mat_e = new SparseMatrix(height);
778  }
779 
780  for (int i = 0; i < vdofs.Size(); i++)
781  {
782  int vdof = vdofs[i];
783  if ( vdof >= 0 )
784  {
785  mat -> EliminateRowCol (vdof, *mat_e, d);
786  }
787  else
788  {
789  mat -> EliminateRowCol (-1-vdof, *mat_e, d);
790  }
791  }
792 }
793 
795  const Array<int> &ess_dofs, Vector &sol, Vector &rhs, int d)
796 {
797  MFEM_ASSERT(ess_dofs.Size() == height, "incorrect dof Array size");
798  MFEM_ASSERT(sol.Size() == height, "incorrect sol Vector size");
799  MFEM_ASSERT(rhs.Size() == height, "incorrect rhs Vector size");
800 
801  for (int i = 0; i < ess_dofs.Size(); i++)
802  if (ess_dofs[i] < 0)
803  {
804  mat -> EliminateRowCol (i, sol(i), rhs, d);
805  }
806 }
807 
809  int d)
810 {
811  MFEM_ASSERT(ess_dofs.Size() == height, "incorrect dof Array size");
812 
813  for (int i = 0; i < ess_dofs.Size(); i++)
814  if (ess_dofs[i] < 0)
815  {
816  mat -> EliminateRowCol (i, d);
817  }
818 }
819 
821  double value)
822 {
823  MFEM_ASSERT(ess_dofs.Size() == height, "incorrect dof Array size");
824 
825  for (int i = 0; i < ess_dofs.Size(); i++)
826  if (ess_dofs[i] < 0)
827  {
828  mat -> EliminateRowColDiag (i, value);
829  }
830 }
831 
833  const Array<int> &vdofs, const Vector &x, Vector &b)
834 {
835  mat_e->AddMult(x, b, -1.);
836  mat->PartMult(vdofs, x, b);
837 }
838 
840 {
841  bool full_update;
842 
843  if (nfes && nfes != fes)
844  {
845  full_update = true;
846  fes = nfes;
847  }
848  else
849  {
850  // Check for different size (e.g. assembled form on non-conforming space)
851  // or different sequence number.
852  full_update = (fes->GetVSize() != Height() ||
853  sequence < fes->GetSequence());
854  }
855 
856  delete mat_e;
857  mat_e = NULL;
859  delete static_cond;
860  static_cond = NULL;
861 
862  if (full_update)
863  {
864  delete mat;
865  mat = NULL;
866  delete hybridization;
867  hybridization = NULL;
868  sequence = fes->GetSequence();
869  }
870  else
871  {
872  if (mat) { *mat = 0.0; }
873  if (hybridization) { hybridization->Reset(); }
874  }
875 
876  height = width = fes->GetVSize();
877 }
878 
880 {
881  delete mat_e;
882  delete mat;
883  delete element_matrices;
884  delete static_cond;
885  delete hybridization;
886 
887  if (!extern_bfs)
888  {
889  int k;
890  for (k=0; k < dbfi.Size(); k++) { delete dbfi[k]; }
891  for (k=0; k < bbfi.Size(); k++) { delete bbfi[k]; }
892  for (k=0; k < fbfi.Size(); k++) { delete fbfi[k]; }
893  for (k=0; k < bfbfi.Size(); k++) { delete bfbfi[k]; }
894  }
895 }
896 
897 
899  FiniteElementSpace *te_fes)
900  : Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
901 {
902  trial_fes = tr_fes;
903  test_fes = te_fes;
904  mat = NULL;
905 }
906 
907 double & MixedBilinearForm::Elem (int i, int j)
908 {
909  return (*mat)(i, j);
910 }
911 
912 const double & MixedBilinearForm::Elem (int i, int j) const
913 {
914  return (*mat)(i, j);
915 }
916 
917 void MixedBilinearForm::Mult (const Vector & x, Vector & y) const
918 {
919  mat -> Mult (x, y);
920 }
921 
923  const double a) const
924 {
925  mat -> AddMult (x, y, a);
926 }
927 
929  const double a) const
930 {
931  mat -> AddMultTranspose (x, y, a);
932 }
933 
935 {
936  return mat -> Inverse ();
937 }
938 
939 void MixedBilinearForm::Finalize (int skip_zeros)
940 {
941  mat -> Finalize (skip_zeros);
942 }
943 
945 {
946  MFEM_VERIFY(trial_fes->GetOrdering() == Ordering::byNODES &&
948  "MixedBilinearForm::GetBlocks: both trial and test spaces "
949  "must use Ordering::byNODES!");
950 
951  blocks.SetSize(test_fes->GetVDim(), trial_fes->GetVDim());
952 
953  mat->GetBlocks(blocks);
954 }
955 
957 {
958  dom.Append (bfi);
959 }
960 
962 {
963  bdr.Append (bfi);
964 }
965 
967 {
968  skt.Append (bfi);
969 }
970 
971 void MixedBilinearForm::Assemble (int skip_zeros)
972 {
973  int i, k;
974  Array<int> tr_vdofs, te_vdofs;
975  ElementTransformation *eltrans;
976  DenseMatrix elemmat;
977 
978  Mesh *mesh = test_fes -> GetMesh();
979 
980  if (mat == NULL)
981  {
982  mat = new SparseMatrix(height, width);
983  }
984 
985  if (dom.Size())
986  {
987  for (i = 0; i < test_fes -> GetNE(); i++)
988  {
989  trial_fes -> GetElementVDofs (i, tr_vdofs);
990  test_fes -> GetElementVDofs (i, te_vdofs);
991  eltrans = test_fes -> GetElementTransformation (i);
992  for (k = 0; k < dom.Size(); k++)
993  {
994  dom[k] -> AssembleElementMatrix2 (*trial_fes -> GetFE(i),
995  *test_fes -> GetFE(i),
996  *eltrans, elemmat);
997  mat -> AddSubMatrix (te_vdofs, tr_vdofs, elemmat, skip_zeros);
998  }
999  }
1000  }
1001 
1002  if (bdr.Size())
1003  {
1004  for (i = 0; i < test_fes -> GetNBE(); i++)
1005  {
1006  trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
1007  test_fes -> GetBdrElementVDofs (i, te_vdofs);
1008  eltrans = test_fes -> GetBdrElementTransformation (i);
1009  for (k = 0; k < bdr.Size(); k++)
1010  {
1011  bdr[k] -> AssembleElementMatrix2 (*trial_fes -> GetBE(i),
1012  *test_fes -> GetBE(i),
1013  *eltrans, elemmat);
1014  mat -> AddSubMatrix (te_vdofs, tr_vdofs, elemmat, skip_zeros);
1015  }
1016  }
1017  }
1018 
1019  if (skt.Size())
1020  {
1022  Array<int> te_vdofs2;
1023  const FiniteElement *trial_face_fe, *test_fe1, *test_fe2;
1024 
1025  int nfaces = mesh->GetNumFaces();
1026  for (i = 0; i < nfaces; i++)
1027  {
1028  ftr = mesh->GetFaceElementTransformations(i);
1029  trial_fes->GetFaceVDofs(i, tr_vdofs);
1030  test_fes->GetElementVDofs(ftr->Elem1No, te_vdofs);
1031  trial_face_fe = trial_fes->GetFaceElement(i);
1032  test_fe1 = test_fes->GetFE(ftr->Elem1No);
1033  if (ftr->Elem2No >= 0)
1034  {
1035  test_fes->GetElementVDofs(ftr->Elem2No, te_vdofs2);
1036  te_vdofs.Append(te_vdofs2);
1037  test_fe2 = test_fes->GetFE(ftr->Elem2No);
1038  }
1039  else
1040  {
1041  // The test_fe2 object is really a dummy and not used on the
1042  // boundaries, but we can't dereference a NULL pointer, and we don't
1043  // want to actually make a fake element.
1044  test_fe2 = test_fe1;
1045  }
1046  for (int k = 0; k < skt.Size(); k++)
1047  {
1048  skt[k]->AssembleFaceMatrix(*trial_face_fe, *test_fe1, *test_fe2,
1049  *ftr, elemmat);
1050  mat->AddSubMatrix(te_vdofs, tr_vdofs, elemmat, skip_zeros);
1051  }
1052  }
1053  }
1054 }
1055 
1057 {
1058  Finalize();
1059 
1061  if (P2)
1062  {
1063  SparseMatrix *R = Transpose(*P2);
1064  SparseMatrix *RA = mfem::Mult(*R, *mat);
1065  delete R;
1066  delete mat;
1067  mat = RA;
1068  }
1069 
1071  if (P1)
1072  {
1073  SparseMatrix *RAP = mfem::Mult(*mat, *P1);
1074  delete mat;
1075  mat = RAP;
1076  }
1077 
1078  height = mat->Height();
1079  width = mat->Width();
1080 }
1081 
1083  Array<int> &bdr_attr_is_ess, Vector &sol, Vector &rhs )
1084 {
1085  int i, j, k;
1086  Array<int> tr_vdofs, cols_marker (trial_fes -> GetVSize());
1087 
1088  cols_marker = 0;
1089  for (i = 0; i < trial_fes -> GetNBE(); i++)
1090  if (bdr_attr_is_ess[trial_fes -> GetBdrAttribute (i)-1])
1091  {
1092  trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
1093  for (j = 0; j < tr_vdofs.Size(); j++)
1094  {
1095  if ( (k = tr_vdofs[j]) < 0 )
1096  {
1097  k = -1-k;
1098  }
1099  cols_marker[k] = 1;
1100  }
1101  }
1102  mat -> EliminateCols (cols_marker, &sol, &rhs);
1103 }
1104 
1106  Array<int> &marked_vdofs, Vector &sol, Vector &rhs)
1107 {
1108  mat -> EliminateCols (marked_vdofs, &sol, &rhs);
1109 }
1110 
1112 {
1113  int i, j, k;
1114  Array<int> te_vdofs;
1115 
1116  for (i = 0; i < test_fes -> GetNBE(); i++)
1117  if (bdr_attr_is_ess[test_fes -> GetBdrAttribute (i)-1])
1118  {
1119  test_fes -> GetBdrElementVDofs (i, te_vdofs);
1120  for (j = 0; j < te_vdofs.Size(); j++)
1121  {
1122  if ( (k = te_vdofs[j]) < 0 )
1123  {
1124  k = -1-k;
1125  }
1126  mat -> EliminateRow (k);
1127  }
1128  }
1129 }
1130 
1132 {
1133  delete mat;
1134  mat = NULL;
1135  height = test_fes->GetVSize();
1136  width = trial_fes->GetVSize();
1137 }
1138 
1140 {
1141  int i;
1142 
1143  if (mat) { delete mat; }
1144  for (i = 0; i < dom.Size(); i++) { delete dom[i]; }
1145  for (i = 0; i < bdr.Size(); i++) { delete bdr[i]; }
1146  for (i = 0; i < skt.Size(); i++) { delete skt[i]; }
1147 }
1148 
1149 
1151 {
1152  Array<int> dom_vdofs, ran_vdofs;
1154  const FiniteElement *dom_fe, *ran_fe;
1155  DenseMatrix totelmat, elmat;
1156 
1157  if (mat == NULL)
1158  {
1159  mat = new SparseMatrix(height, width);
1160  }
1161 
1162  if (dom.Size() > 0)
1163  {
1164  for (int i = 0; i < test_fes->GetNE(); i++)
1165  {
1166  trial_fes->GetElementVDofs(i, dom_vdofs);
1167  test_fes->GetElementVDofs(i, ran_vdofs);
1169  dom_fe = trial_fes->GetFE(i);
1170  ran_fe = test_fes->GetFE(i);
1171 
1172  dom[0]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, totelmat);
1173  for (int j = 1; j < dom.Size(); j++)
1174  {
1175  dom[j]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, elmat);
1176  totelmat += elmat;
1177  }
1178  mat->SetSubMatrix(ran_vdofs, dom_vdofs, totelmat, skip_zeros);
1179  }
1180  }
1181 
1182  if (skt.Size())
1183  {
1184  const int nfaces = test_fes->GetMesh()->GetNumFaces();
1185  for (int i = 0; i < nfaces; i++)
1186  {
1187  trial_fes->GetFaceVDofs(i, dom_vdofs);
1188  test_fes->GetFaceVDofs(i, ran_vdofs);
1190  dom_fe = trial_fes->GetFaceElement(i);
1191  ran_fe = test_fes->GetFaceElement(i);
1192 
1193  skt[0]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, totelmat);
1194  for (int j = 1; j < skt.Size(); j++)
1195  {
1196  skt[j]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, elmat);
1197  totelmat += elmat;
1198  }
1199  mat->SetSubMatrix(ran_vdofs, dom_vdofs, totelmat, skip_zeros);
1200  }
1201  }
1202 }
1203 
1204 }
Abstract class for Finite Elements.
Definition: fe.hpp:46
Ordering::Type GetOrdering() const
Return the ordering method.
Definition: fespace.hpp:175
int Size() const
Logical size of the array.
Definition: array.hpp:109
int GetVSize() const
Definition: fespace.hpp:163
Array< BilinearFormIntegrator * > * GetBBFI()
int * GetJ()
Definition: table.hpp:108
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
Definition: mesh.hpp:824
void NewDataAndSize(double *d, int s)
Set the Vector data and size, deleting the old data, if owned.
Definition: vector.hpp:94
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.
void SetConstraintIntegrator(BilinearFormIntegrator *c_integ)
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.
bool ReducesTrueVSize() const
Definition: staticcond.cpp:118
virtual void Finalize(int skip_zeros=1)
Finalize the matrix initialization, switching the storage format from LIL to CSR. ...
Definition: sparsemat.hpp:278
Array< BilinearFormIntegrator * > * GetDBFI()
void MakeRef(const SparseMatrix &master)
Clear the contents of the SparseMatrix and make it a reference to master.
Definition: sparsemat.cpp:187
void SortRows()
Sort the column (TYPE II) indices in each row.
Definition: table.cpp:188
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:310
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i&#39;th element.
Definition: fespace.cpp:133
Array< BilinearFormIntegrator * > dbfi
Set of Domain Integrators to be applied.
virtual void GetEssentialVDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_vdofs) const
Definition: fespace.cpp:258
Array< BilinearFormIntegrator * > * GetBFBFI()
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, but treat all elements as booleans (zero=false, nonzero=true).
Definition: sparsemat.cpp:633
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:468
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:42
virtual void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x)
Data type dense matrix using column-major storage.
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:481
int Size() const
Returns the size of the vector.
Definition: vector.hpp:106
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:417
Abstract data type for matrix inverse.
Definition: matrix.hpp:58
void EliminateVDofs(const Array< int > &vdofs, Vector &sol, Vector &rhs, int d=0)
Eliminate the given vdofs. NOTE: here, vdofs is a list of DOFs.
void FormSystemMatrix(const Array< int > &ess_tdof_list, SparseMatrix &A)
Form the linear system matrix A, see FormLinearSystem for details.
void LoseData()
Call this if data has been stolen.
Definition: table.hpp:141
const FiniteElement * GetFaceElement(int i) const
Definition: fespace.cpp:1395
void EliminateEssentialBCFromDofs(const Array< int > &ess_dofs, Vector &sol, Vector &rhs, int d=0)
virtual void Finalize(int skip_zeros=1)
Finalizes the matrix initialization.
void ComputeSolution(const Vector &b, const Vector &sc_sol, Vector &sol) const
Definition: staticcond.cpp:477
Array< BilinearFormIntegrator * > * GetFBFI()
double * GetData() const
Definition: vector.hpp:114
MixedBilinearForm(FiniteElementSpace *tr_fes, FiniteElementSpace *te_fes)
FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31)
Definition: mesh.cpp:604
void Reset()
Destroy the current hybridization matrix while preserving the computed constraint matrix and the set ...
void GetBlocks(Array2D< SparseMatrix * > &blocks) const
Definition: sparsemat.cpp:825
void EnableHybridization(FiniteElementSpace *constr_space, BilinearFormIntegrator *constr_integ, const Array< int > &ess_tdof_list)
void EliminateEssentialBCFromDofsDiag(const Array< int > &ess_dofs, double value)
Perform elimination and set the diagonal entry to the given value.
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
Definition: mesh.cpp:3297
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:184
void SetSize(int m, int n)
Definition: array.hpp:282
void Finalize()
Finalize the construction of the hybridized matrix.
void AssembleBdrMatrix(int bdr_el, const DenseMatrix &A)
Assemble the boundary element matrix A into the hybridized system matrix.
const SparseMatrix * GetConformingRestriction()
Definition: fespace.cpp:697
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:36
SparseMatrix & GetMatrix()
Return the serial hybridized matrix.
StaticCondensation * static_cond
int Append(const T &el)
Append element to array, resize if necessary.
Definition: array.hpp:394
Mesh * GetMesh() const
Returns the mesh.
Definition: fespace.hpp:136
SparseMatrix * mat
Sparse matrix to be associated with the form.
bool areColumnsSorted() const
Definition: sparsemat.hpp:284
void GetFaceTransformation(int i, IsoparametricTransformation *FTr)
Definition: mesh.cpp:345
void ComputeSolution(const Vector &b, const Vector &sol_r, Vector &sol) const
Abstract data type matrix.
Definition: matrix.hpp:27
HypreParMatrix * RAP(HypreParMatrix *A, HypreParMatrix *P)
Returns the matrix P^t * A * P.
Definition: hypre.cpp:1385
T Max() const
Find the maximal element in the array, using the comparison operator &lt; for class T.
Definition: array.cpp:108
void Assemble(int skip_zeros=1)
void EliminateEssentialBCDiag(const Array< int > &bdr_attr_is_ess, double value)
Perform elimination and set the diagonal entry to the given value.
void Transpose(const Table &A, Table &At, int _ncols_A)
Transpose a Table.
Definition: table.cpp:408
double * GetData(int k)
Definition: densemat.hpp:648
virtual void Update(FiniteElementSpace *nfes=NULL)
void EliminateTrialDofs(Array< int > &bdr_attr_is_ess, Vector &sol, Vector &rhs)
const SparseMatrix * GetConformingProlongation()
Definition: fespace.cpp:690
int GetVDim() const
Returns vector dimension.
Definition: fespace.hpp:153
virtual const SparseMatrix * GetRestrictionMatrix()
Definition: fespace.hpp:149
void AddTraceFaceIntegrator(BilinearFormIntegrator *bfi)
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
Definition: sparsemat.cpp:1850
void GetBlocks(Array2D< SparseMatrix * > &blocks) const
int * GetI() const
Return the array I.
Definition: sparsemat.hpp:131
void SetSubVectorComplement(const Array< int > &dofs, const double val)
Set all vector entries NOT in the &#39;dofs&#39; array to the given &#39;val&#39;.
Definition: vector.cpp:598
void SetSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
Definition: sparsemat.cpp:1926
int SizeI() const
Definition: densemat.hpp:617
void ComputeElementMatrix(int i, DenseMatrix &elmat)
bool Finalized() const
Definition: sparsemat.hpp:283
SparseMatrix * mat_e
Matrix used to eliminate b.c.
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i&#39;th element.
Definition: fespace.hpp:205
Abstract base class BilinearFormIntegrator.
Definition: bilininteg.hpp:22
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition: mesh.hpp:142
void AssembleElementMatrix(int i, const DenseMatrix &elmat, Array< int > &vdofs, int skip_zeros=1)
void AssembleMatrix(int el, const DenseMatrix &A)
Assemble the element matrix A into the hybridized system matrix.
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition: fe.hpp:121
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
Definition: sparsemat.cpp:475
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 Finalize()
Finalize the construction of the Schur complement matrix.
Definition: staticcond.cpp:235
void mfem_error(const char *msg)
Definition: error.cpp:106
void ClearExternalData()
Definition: densemat.hpp:72
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
Array< BilinearFormIntegrator * > dom
void AssembleBdrMatrix(int el, const DenseMatrix &elmat)
Definition: staticcond.cpp:227
void EliminateReducedTrueDofs(const Array< int > &ess_rtdof_list, int keep_diagonal)
Eliminate the given reduced true dofs from the Schur complement matrix S.
Definition: staticcond.cpp:288
int height
Dimension of the output / number of rows in the matrix.
Definition: operator.hpp:24
Table * GetFaceToElementTable() const
Definition: mesh.cpp:3803
FiniteElementSpace * test_fes
int SizeJ() const
Definition: densemat.hpp:618
virtual void EliminateTestDofs(Array< int > &bdr_attr_is_ess)
virtual void Finalize(int skip_zeros=1)
Finalizes the matrix initialization.
void AssembleMatrix(int el, const DenseMatrix &elmat)
Definition: staticcond.cpp:189
void EliminateVDofsInRHS(const Array< int > &vdofs, const Vector &x, Vector &b)
bool HasEliminatedBC() const
Return true if essential boundary conditions have been eliminated from the Schur complement matrix...
Definition: staticcond.hpp:142
void AddBoundaryIntegrator(BilinearFormIntegrator *bfi)
Adds new Boundary Integrator.
void AddInteriorFaceIntegrator(BilinearFormIntegrator *bfi)
Adds new interior Face Integrator.
void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
Definition: sparsemat.cpp:552
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:1134
void AssembleBdrElementMatrix(int i, const DenseMatrix &elmat, Array< int > &vdofs, int skip_zeros=1)
DenseMatrix elemmat
void GetFaceVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i&#39;th face element (2D and 3D).
Definition: fespace.cpp:145
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:36
void AddBoundaryIntegrator(BilinearFormIntegrator *bfi)
SparseMatrix & GetMatrix()
Return the serial Schur complement matrix.
Definition: staticcond.hpp:152
virtual MatrixInverse * Inverse() const
Returns a pointer to (an approximation) of the matrix inverse.
Hybridization * hybridization
void ReduceRHS(const Vector &b, Vector &b_r) const
int * GetI()
Definition: table.hpp:107
const Table & GetElementToDofTable() const
Definition: fespace.hpp:288
void Init(const Array< int > &ess_tdof_list)
Prepare the Hybridization object for assembly.
Array< Array< int > * > bfbfi_marker
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement for the i&#39;th boundary element.
Definition: fespace.cpp:1369
void GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i&#39;th boundary element.
Definition: fespace.cpp:139
void SetEssentialTrueDofs(const Array< int > &ess_tdof_list)
Determine and save internally essential reduced true dofs.
Definition: staticcond.hpp:128
Array< int > vdofs
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:82
void FreeElementMatrices()
Free the memory used by the element matrices.
long GetSequence() const
Return update counter (see Mesh::sequence)
Definition: fespace.hpp:370
void EliminateEssentialBC(const Array< int > &bdr_attr_is_ess, Vector &sol, Vector &rhs, int d=0)
void Init(bool symmetric, bool block_diagonal)
Definition: staticcond.cpp:134
virtual void Assemble(int skip_zeros=1)
int * GetJ() const
Return the array J.
Definition: sparsemat.hpp:133
void FormLinearSystem(const Array< int > &ess_tdof_list, Vector &x, Vector &b, SparseMatrix &A, Vector &X, Vector &B, int copy_interior=0)
Rank 3 tensor (array of matrices)
Definition: densemat.hpp:593
void UseSparsity(int *I, int *J, bool isSorted)
Use the given CSR sparsity pattern to allocate the internal SparseMatrix.
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
int width
Dimension of the input / number of columns in the matrix.
Definition: operator.hpp:25
void EnableStaticCondensation()
void AddBdrFaceIntegrator(BilinearFormIntegrator *bfi)
Adds new boundary Face Integrator.
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
Definition: sparsemat.cpp:597