MFEM  v3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
nonlinearform.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 #include "fem.hpp"
13 
14 namespace mfem
15 {
16 
17 void NonlinearForm::SetEssentialBC(const Array<int> &bdr_attr_is_ess,
18  Vector *rhs)
19 {
20  int i, j, vsize, nv;
21  vsize = fes->GetVSize();
22  Array<int> vdof_marker(vsize);
23 
24  // virtual call, works in parallel too
25  fes->GetEssentialVDofs(bdr_attr_is_ess, vdof_marker);
26  nv = 0;
27  for (i = 0; i < vsize; i++)
28  if (vdof_marker[i])
29  nv++;
30 
31  ess_vdofs.SetSize(nv);
32 
33  for (i = j = 0; i < vsize; i++)
34  if (vdof_marker[i])
35  ess_vdofs[j++] = i;
36 
37  if (rhs)
38  for (i = 0; i < nv; i++)
39  (*rhs)(ess_vdofs[i]) = 0.0;
40 }
41 
42 double NonlinearForm::GetEnergy(const Vector &x) const
43 {
44  Array<int> vdofs;
45  Vector el_x;
46  const FiniteElement *fe;
48  double energy = 0.0;
49 
50  if (dfi.Size())
51  for (int i = 0; i < fes->GetNE(); i++)
52  {
53  fe = fes->GetFE(i);
54  fes->GetElementVDofs(i, vdofs);
56  x.GetSubVector(vdofs, el_x);
57  for (int k = 0; k < dfi.Size(); k++)
58  {
59  energy += dfi[k]->GetElementEnergy(*fe, *T, el_x);
60  }
61  }
62 
63  return energy;
64 }
65 
66 void NonlinearForm::Mult(const Vector &x, Vector &y) const
67 {
68  Array<int> vdofs;
69  Vector el_x, el_y;
70  const FiniteElement *fe;
72 
73  y = 0.0;
74 
75  if (dfi.Size())
76  for (int i = 0; i < fes->GetNE(); i++)
77  {
78  fe = fes->GetFE(i);
79  fes->GetElementVDofs(i, vdofs);
81  x.GetSubVector(vdofs, el_x);
82  for (int k = 0; k < dfi.Size(); k++)
83  {
84  dfi[k]->AssembleElementVector(*fe, *T, el_x, el_y);
85  y.AddElementVector(vdofs, el_y);
86  }
87  }
88 
89  for (int i = 0; i < ess_vdofs.Size(); i++)
90  y(ess_vdofs[i]) = 0.0;
91  // y(ess_vdofs[i]) = x(ess_vdofs[i]);
92 }
93 
95 {
96  const int skip_zeros = 0;
97  Array<int> vdofs;
98  Vector el_x;
99  DenseMatrix elmat;
100  const FiniteElement *fe;
102 
103  if (Grad == NULL)
104  Grad = new SparseMatrix(fes->GetVSize());
105  else
106  *Grad = 0.0;
107 
108  if (dfi.Size())
109  for (int i = 0; i < fes->GetNE(); i++)
110  {
111  fe = fes->GetFE(i);
112  fes->GetElementVDofs(i, vdofs);
114  x.GetSubVector(vdofs, el_x);
115  for (int k = 0; k < dfi.Size(); k++)
116  {
117  dfi[k]->AssembleElementGrad(*fe, *T, el_x, elmat);
118  Grad->AddSubMatrix(vdofs, vdofs, elmat, skip_zeros);
119  // Grad->AddSubMatrix(vdofs, vdofs, elmat, 1);
120  }
121  }
122 
123  for (int i = 0; i < ess_vdofs.Size(); i++)
124  Grad->EliminateRowCol(ess_vdofs[i]);
125 
126  if (!Grad->Finalized())
127  Grad->Finalize(skip_zeros);
128 
129  return *Grad;
130 }
131 
133 {
134  delete Grad;
135  for (int i = 0; i < dfi.Size(); i++)
136  delete dfi[i];
137 }
138 
139 }
Abstract class for Finite Elements.
Definition: fe.hpp:42
int Size() const
Logical size of the array.
Definition: array.hpp:108
int GetVSize() const
Definition: fespace.hpp:151
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Definition: vector.cpp:403
void EliminateRowCol(int rc, const double sol, Vector &rhs, int d=0)
Definition: sparsemat.cpp:859
Data type dense matrix.
Definition: densemat.hpp:22
FiniteElementSpace * fes
FE space on which the form lives.
int GetNE() const
Returns number of elements in the mesh.
Definition: fespace.hpp:169
Data type sparse matrix.
Definition: sparsemat.hpp:38
Array< int > ess_vdofs
virtual void Finalize(int skip_zeros=1)
Definition: sparsemat.cpp:529
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add (element) subvector to the vector.
Definition: vector.cpp:449
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
Definition: sparsemat.cpp:1468
bool Finalized() const
Definition: sparsemat.hpp:234
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i&#39;th element.
Definition: fespace.hpp:190
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:293
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 void GetEssentialVDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_dofs) const
Determine the boundary degrees of freedom.
Definition: fespace.cpp:362
Array< NonlinearFormIntegrator * > dfi
Set of Domain Integrators to be assembled (added).
virtual Operator & GetGradient(const Vector &x) const
Evaluate the gradient operator at the point x.
const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement associated with i&#39;th element.
Definition: fespace.cpp:814
virtual void SetEssentialBC(const Array< int > &bdr_attr_is_ess, Vector *rhs=NULL)
Vector data type.
Definition: vector.hpp:29
SparseMatrix * Grad
virtual double GetEnergy(const Vector &x) const
Abstract operator.
Definition: operator.hpp:21