MFEM  v3.1
Finite element discretization library
 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.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 #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  {
30  nv++;
31  }
32 
33  ess_vdofs.SetSize(nv);
34 
35  for (i = j = 0; i < vsize; i++)
36  if (vdof_marker[i])
37  {
38  ess_vdofs[j++] = i;
39  }
40 
41  if (rhs)
42  for (i = 0; i < nv; i++)
43  {
44  (*rhs)(ess_vdofs[i]) = 0.0;
45  }
46 }
47 
48 double NonlinearForm::GetEnergy(const Vector &x) const
49 {
50  Array<int> vdofs;
51  Vector el_x;
52  const FiniteElement *fe;
54  double energy = 0.0;
55 
56  if (dfi.Size())
57  for (int i = 0; i < fes->GetNE(); i++)
58  {
59  fe = fes->GetFE(i);
60  fes->GetElementVDofs(i, vdofs);
62  x.GetSubVector(vdofs, el_x);
63  for (int k = 0; k < dfi.Size(); k++)
64  {
65  energy += dfi[k]->GetElementEnergy(*fe, *T, el_x);
66  }
67  }
68 
69  return energy;
70 }
71 
72 void NonlinearForm::Mult(const Vector &x, Vector &y) const
73 {
74  Array<int> vdofs;
75  Vector el_x, el_y;
76  const FiniteElement *fe;
78 
79  y = 0.0;
80 
81  if (dfi.Size())
82  for (int i = 0; i < fes->GetNE(); i++)
83  {
84  fe = fes->GetFE(i);
85  fes->GetElementVDofs(i, vdofs);
87  x.GetSubVector(vdofs, el_x);
88  for (int k = 0; k < dfi.Size(); k++)
89  {
90  dfi[k]->AssembleElementVector(*fe, *T, el_x, el_y);
91  y.AddElementVector(vdofs, el_y);
92  }
93  }
94 
95  for (int i = 0; i < ess_vdofs.Size(); i++)
96  {
97  y(ess_vdofs[i]) = 0.0;
98  }
99  // y(ess_vdofs[i]) = x(ess_vdofs[i]);
100 }
101 
103 {
104  const int skip_zeros = 0;
105  Array<int> vdofs;
106  Vector el_x;
107  DenseMatrix elmat;
108  const FiniteElement *fe;
110 
111  if (Grad == NULL)
112  {
113  Grad = new SparseMatrix(fes->GetVSize());
114  }
115  else
116  {
117  *Grad = 0.0;
118  }
119 
120  if (dfi.Size())
121  for (int i = 0; i < fes->GetNE(); i++)
122  {
123  fe = fes->GetFE(i);
124  fes->GetElementVDofs(i, vdofs);
126  x.GetSubVector(vdofs, el_x);
127  for (int k = 0; k < dfi.Size(); k++)
128  {
129  dfi[k]->AssembleElementGrad(*fe, *T, el_x, elmat);
130  Grad->AddSubMatrix(vdofs, vdofs, elmat, skip_zeros);
131  // Grad->AddSubMatrix(vdofs, vdofs, elmat, 1);
132  }
133  }
134 
135  for (int i = 0; i < ess_vdofs.Size(); i++)
136  {
138  }
139 
140  if (!Grad->Finalized())
141  {
142  Grad->Finalize(skip_zeros);
143  }
144 
145  return *Grad;
146 }
147 
149 {
150  delete Grad;
151  for (int i = 0; i < dfi.Size(); i++)
152  {
153  delete dfi[i];
154  }
155 }
156 
157 }
Abstract class for Finite Elements.
Definition: fe.hpp:44
int Size() const
Logical size of the array.
Definition: array.hpp:109
int GetVSize() const
Definition: fespace.hpp:164
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:161
virtual void GetEssentialVDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_vdofs) const
Definition: fespace.cpp:432
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Definition: vector.cpp:457
void EliminateRowCol(int rc, const double sol, Vector &rhs, int d=0)
Definition: sparsemat.cpp:1045
Data type dense matrix using column-major storage.
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:185
Data type sparse matrix.
Definition: sparsemat.hpp:38
Array< int > ess_vdofs
virtual void Finalize(int skip_zeros=1)
Definition: sparsemat.cpp:680
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add (element) subvector to the vector.
Definition: vector.cpp:527
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
Definition: sparsemat.cpp:1733
bool Finalized() const
Definition: sparsemat.hpp:256
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:206
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:323
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:1199
virtual void SetEssentialBC(const Array< int > &bdr_attr_is_ess, Vector *rhs=NULL)
Vector data type.
Definition: vector.hpp:33
SparseMatrix * Grad
virtual double GetEnergy(const Vector &x) const
Abstract operator.
Definition: operator.hpp:21