MFEM  v4.2.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
nonlinearform.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2020, 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 #ifndef MFEM_NONLINEARFORM
13 #define MFEM_NONLINEARFORM
14 
15 #include "../config/config.hpp"
16 #include "nonlininteg.hpp"
17 #include "nonlinearform_ext.hpp"
18 #include "bilinearform.hpp"
19 #include "gridfunc.hpp"
20 
21 namespace mfem
22 {
23 
24 class NonlinearForm : public Operator
25 {
26 protected:
27  /// The assembly level.
29 
30  /** Extension for supporting Partial Assembly (PA) or
31  Matrix Free assembly (MF). */
33 
34  /// FE space on which the form lives.
35  FiniteElementSpace *fes; // not owned
36 
37  /// Set of Domain Integrators to be assembled (added).
39 
40  /// Set of interior face Integrators to be assembled (added).
42 
43  /// Set of boundary face Integrators to be assembled (added).
46 
47  mutable SparseMatrix *Grad, *cGrad; // owned
48 
49  /// A list of all essential true dofs
51 
52  /// Counter for updates propagated from the FiniteElementSpace.
53  long sequence;
54 
55  /// Auxiliary Vector%s
56  mutable Vector aux1, aux2;
57 
58  /// Pointer to the prolongation matrix of fes, may be NULL.
59  const Operator *P; // not owned
60  /// The result of dynamic-casting P to SparseMatrix pointer.
61  const SparseMatrix *cP; // not owned
62 
63  bool Serial() const { return (!P || cP); }
64  const Vector &Prolongate(const Vector &x) const;
65 
66 public:
67  /// Construct a NonlinearForm on the given FiniteElementSpace, @a f.
68  /** As an Operator, the NonlinearForm has input and output size equal to the
69  number of true degrees of freedom, i.e. f->GetTrueVSize(). */
71  : Operator(f->GetTrueVSize()), assembly(AssemblyLevel::NONE),
72  ext(NULL), fes(f), Grad(NULL), cGrad(NULL),
73  sequence(f->GetSequence()), P(f->GetProlongationMatrix()),
74  cP(dynamic_cast<const SparseMatrix*>(P))
75  { }
76 
77  /// Set the desired assembly level. The default is AssemblyLevel::NONE.
78  /** This method must be called before assembly. */
79  void SetAssemblyLevel(AssemblyLevel assembly_level);
80 
82  const FiniteElementSpace *FESpace() const { return fes; }
83 
84  /// Adds new Domain Integrator.
86  { dnfi.Append(nlfi); }
87 
88  /// Access all integrators added with AddDomainIntegrator().
90  const Array<NonlinearFormIntegrator*> *GetDNFI() const { return &dnfi; }
91 
92  /// Adds new Interior Face Integrator.
94  { fnfi.Append(nlfi); }
95 
96  /// Adds new Boundary Face Integrator.
98  { bfnfi.Append(nlfi); bfnfi_marker.Append(NULL); }
99 
100  /** @brief Adds new Boundary Face Integrator, restricted to specific boundary
101  attributes. */
103  Array<int> &bdr_marker)
104  { bfnfi.Append(nfi); bfnfi_marker.Append(&bdr_marker); }
105 
106  /// Specify essential boundary conditions.
107  /** This method calls FiniteElementSpace::GetEssentialTrueDofs() and stores
108  the result internally for use by other methods. If the @a rhs pointer is
109  not NULL, its essential true dofs will be set to zero. This makes it
110  "compatible" with the output vectors from the Mult() method which also
111  have zero entries at the essential true dofs. */
112  void SetEssentialBC(const Array<int> &bdr_attr_is_ess, Vector *rhs = NULL);
113 
114  /// Specify essential boundary conditions.
115  /** Use either SetEssentialBC() or SetEssentialTrueDofs() if possible. */
116  void SetEssentialVDofs(const Array<int> &ess_vdofs_list);
117 
118  /// Specify essential boundary conditions.
120  { ess_tdof_list.Copy(this->ess_tdof_list); }
121 
122  /// Return a (read-only) list of all essential true dofs.
123  const Array<int> &GetEssentialTrueDofs() const { return ess_tdof_list; }
124 
125  /// Compute the enery corresponding to the state @a x.
126  /** In general, @a x may have non-homogeneous essential boundary values.
127 
128  The state @a x must be a "GridFunction size" vector, i.e. its size must
129  be fes->GetVSize(). */
130  double GetGridFunctionEnergy(const Vector &x) const;
131 
132  /// Compute the enery corresponding to the state @a x.
133  /** In general, @a x may have non-homogeneous essential boundary values.
134 
135  The state @a x must be a true-dof vector. */
136  virtual double GetEnergy(const Vector &x) const
137  { return GetGridFunctionEnergy(Prolongate(x)); }
138 
139  /// Evaluate the action of the NonlinearForm.
140  /** The input essential dofs in @a x will, generally, be non-zero. However,
141  the output essential dofs in @a y will always be set to zero.
142 
143  Both the input and the output vectors, @a x and @a y, must be true-dof
144  vectors, i.e. their size must be fes->GetTrueVSize(). */
145  virtual void Mult(const Vector &x, Vector &y) const;
146 
147  /** @brief Compute the gradient Operator of the NonlinearForm corresponding
148  to the state @a x. */
149  /** Any previously specified essential boundary conditions will be
150  automatically imposed on the gradient operator.
151 
152  The returned object is valid until the next call to this method or the
153  destruction of this object.
154 
155  In general, @a x may have non-homogeneous essential boundary values.
156 
157  The state @a x must be a true-dof vector. */
158  virtual Operator &GetGradient(const Vector &x) const;
159 
160  /// Update the NonlinearForm to propagate updates of the associated FE space.
161  /** After calling this method, the essential boundary conditions need to be
162  set again. */
163  virtual void Update();
164 
165  /// Setup the NonlinearForm
166  virtual void Setup();
167 
168  /// Get the finite element space prolongation matrix
169  virtual const Operator *GetProlongation() const { return P; }
170  /// Get the finite element space restriction matrix
171  virtual const Operator *GetRestriction() const
172  { return fes->GetRestrictionMatrix(); }
173 
174  /** @brief Destroy the NoninearForm including the owned
175  NonlinearFormIntegrator%s and gradient Operator. */
176  virtual ~NonlinearForm();
177 };
178 
179 
180 /** @brief A class representing a general block nonlinear operator defined on
181  the Cartesian product of multiple FiniteElementSpace%s. */
183 {
184 protected:
185  /// FE spaces on which the form lives.
187 
188  /// Set of Domain Integrators to be assembled (added).
190 
191  /// Set of interior face Integrators to be assembled (added).
193 
194  /// Set of Boundary Face Integrators to be assembled (added).
197 
198  /** Auxiliary block-vectors for wrapping input and output vectors or holding
199  GridFunction-like block-vector data (e.g. in parallel). */
200  mutable BlockVector xs, ys;
201 
204 
205  // A list of the offsets
208 
209  // Array of Arrays of tdofs for each space in 'fes'
211 
212  /// Array of pointers to the prolongation matrix of fes, may be NULL
214 
215  /// Array of results of dynamic-casting P to SparseMatrix pointer
217 
218  /// Indicator if the Operator is part of a parallel run
219  bool is_serial = true;
220 
221  /// Indicator if the Operator needs prolongation on assembly
222  bool needs_prolongation = false;
223 
225 
226  const BlockVector &Prolongate(const BlockVector &bx) const;
227 
228  /// Specialized version of GetEnergy() for BlockVectors
229  double GetEnergyBlocked(const BlockVector &bx) const;
230 
231  /// Specialized version of Mult() for BlockVector%s
232  /// Block L-Vector to Block L-Vector
233  void MultBlocked(const BlockVector &bx, BlockVector &by) const;
234 
235  /// Specialized version of GetGradient() for BlockVector
236  void ComputeGradientBlocked(const BlockVector &bx) const;
237 
238 public:
239  /// Construct an empty BlockNonlinearForm. Initialize with SetSpaces().
241 
242  /// Construct a BlockNonlinearForm on the given set of FiniteElementSpace%s.
244 
245  /// Return the @a k-th FE space of the BlockNonlinearForm.
246  FiniteElementSpace *FESpace(int k) { return fes[k]; }
247  /// Return the @a k-th FE space of the BlockNonlinearForm (const version).
248  const FiniteElementSpace *FESpace(int k) const { return fes[k]; }
249 
250  /// (Re)initialize the BlockNonlinearForm.
251  /** After a call to SetSpaces(), the essential b.c. must be set again. */
253 
254  /// Return the regular dof offsets.
255  const Array<int> &GetBlockOffsets() const { return block_offsets; }
256  /// Return the true-dof offsets.
258 
259  /// Adds new Domain Integrator.
261  { dnfi.Append(nlfi); }
262 
263  /// Adds new Interior Face Integrator.
265  { fnfi.Append(nlfi); }
266 
267  /// Adds new Boundary Face Integrator.
269  { bfnfi.Append(nlfi); bfnfi_marker.Append(NULL); }
270 
271  /** @brief Adds new Boundary Face Integrator, restricted to specific boundary
272  attributes. */
274  Array<int> &bdr_marker);
275 
276  virtual void SetEssentialBC(const Array<Array<int> *>&bdr_attr_is_ess,
277  Array<Vector *> &rhs);
278 
279  virtual double GetEnergy(const Vector &x) const;
280 
281  /// Method is only called in serial, the parallel version calls MultBlocked
282  /// directly.
283  virtual void Mult(const Vector &x, Vector &y) const;
284 
285  /// Method is only called in serial, the parallel version calls
286  /// GetGradientBlocked directly.
287  virtual Operator &GetGradient(const Vector &x) const;
288 
289  /// Destructor.
290  virtual ~BlockNonlinearForm();
291 };
292 
293 
294 }
295 
296 #endif
virtual const Operator * GetProlongation() const
Get the finite element space prolongation matrix.
Array< const Operator * > P
Array of pointers to the prolongation matrix of fes, may be NULL.
BlockNonlinearForm()
Construct an empty BlockNonlinearForm. Initialize with SetSpaces().
AssemblyLevel
Enumeration defining the assembly level for bilinear and nonlinear form classes derived from Operator...
bool is_serial
Indicator if the Operator is part of a parallel run.
Array< NonlinearFormIntegrator * > dnfi
Set of Domain Integrators to be assembled (added).
const FiniteElementSpace * FESpace(int k) const
Return the k-th FE space of the BlockNonlinearForm (const version).
Array< BlockNonlinearFormIntegrator * > dnfi
Set of Domain Integrators to be assembled (added).
A class to handle Vectors in a block fashion.
Definition: blockvector.hpp:30
const Array< int > & GetBlockOffsets() const
Return the regular dof offsets.
void AddDomainIntegrator(BlockNonlinearFormIntegrator *nlfi)
Adds new Domain Integrator.
SparseMatrix * cGrad
virtual void SetEssentialBC(const Array< Array< int > * > &bdr_attr_is_ess, Array< Vector * > &rhs)
Array2D< SparseMatrix * > cGrads
virtual void Setup()
Setup the NonlinearForm.
const FiniteElementSpace * FESpace() const
void AddDomainIntegrator(NonlinearFormIntegrator *nlfi)
Adds new Domain Integrator.
void Copy(Array &copy) const
Create a copy of the internal array to the provided copy.
Definition: array.hpp:831
void AddBdrFaceIntegrator(NonlinearFormIntegrator *nfi, Array< int > &bdr_marker)
Adds new Boundary Face Integrator, restricted to specific boundary attributes.
A class representing a general block nonlinear operator defined on the Cartesian product of multiple ...
Array< NonlinearFormIntegrator * > bfnfi
Set of boundary face Integrators to be assembled (added).
Array< BlockNonlinearFormIntegrator * > bfnfi
Set of Boundary Face Integrators to be assembled (added).
Array< int > ess_tdof_list
A list of all essential true dofs.
FiniteElementSpace * fes
FE space on which the form lives.
void AddInteriorFaceIntegrator(NonlinearFormIntegrator *nlfi)
Adds new Interior Face Integrator.
void AddBdrFaceIntegrator(NonlinearFormIntegrator *nlfi)
Adds new Boundary Face Integrator.
virtual const Operator * GetRestriction() const
Get the finite element space restriction matrix.
Array< const SparseMatrix * > cP
Array of results of dynamic-casting P to SparseMatrix pointer.
Array2D< SparseMatrix * > Grads
void SetSpaces(Array< FiniteElementSpace * > &f)
(Re)initialize the BlockNonlinearForm.
virtual double GetEnergy(const Vector &x) const
Compute the enery corresponding to the state x.
virtual double GetEnergy(const Vector &x) const
void AddBdrFaceIntegrator(BlockNonlinearFormIntegrator *nlfi)
Adds new Boundary Face Integrator.
const Array< int > & GetBlockTrueOffsets() const
Return the true-dof offsets.
const Array< NonlinearFormIntegrator * > * GetDNFI() const
Array< FiniteElementSpace * > fes
FE spaces on which the form lives.
Data type sparse matrix.
Definition: sparsemat.hpp:46
const Array< int > & GetEssentialTrueDofs() const
Return a (read-only) list of all essential true dofs.
void AddInteriorFaceIntegrator(BlockNonlinearFormIntegrator *nlfi)
Adds new Interior Face Integrator.
Array< NonlinearFormIntegrator * > * GetDNFI()
Access all integrators added with AddDomainIntegrator().
Array< NonlinearFormIntegrator * > fnfi
Set of interior face Integrators to be assembled (added).
NonlinearForm(FiniteElementSpace *f)
Construct a NonlinearForm on the given FiniteElementSpace, f.
const SparseMatrix * cP
The result of dynamic-casting P to SparseMatrix pointer.
Vector aux1
Auxiliary Vectors.
Array< BlockNonlinearFormIntegrator * > fnfi
Set of interior face Integrators to be assembled (added).
AssemblyLevel assembly
The assembly level.
const Operator * P
Pointer to the prolongation matrix of fes, may be NULL.
Array< Array< int > * > bfnfi_marker
Array< Array< int > * > bfnfi_marker
void SetAssemblyLevel(AssemblyLevel assembly_level)
Set the desired assembly level. The default is AssemblyLevel::NONE.
Dynamic 2D array using row-major layout.
Definition: array.hpp:333
FiniteElementSpace * FESpace()
bool Serial() const
virtual void Mult(const Vector &x, Vector &y) const
Evaluate the action of the NonlinearForm.
virtual void Update()
Update the NonlinearForm to propagate updates of the associated FE space.
void SetEssentialTrueDofs(const Array< int > &ess_tdof_list)
Specify essential boundary conditions.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition: fespace.hpp:87
NonlinearFormExtension * ext
virtual ~BlockNonlinearForm()
Destructor.
virtual ~NonlinearForm()
Destroy the NoninearForm including the owned NonlinearFormIntegrators and gradient Operator...
double GetGridFunctionEnergy(const Vector &x) const
Compute the enery corresponding to the state x.
virtual void Mult(const Vector &x, Vector &y) const
This class is used to express the local action of a general nonlinear finite element operator...
Definition: nonlininteg.hpp:26
virtual Operator & GetGradient(const Vector &x) const
Compute the gradient Operator of the NonlinearForm corresponding to the state x.
double GetEnergyBlocked(const BlockVector &bx) const
Specialized version of GetEnergy() for BlockVectors.
long sequence
Counter for updates propagated from the FiniteElementSpace.
bool needs_prolongation
Indicator if the Operator needs prolongation on assembly.
void SetEssentialBC(const Array< int > &bdr_attr_is_ess, Vector *rhs=NULL)
Specify essential boundary conditions.
Vector data type.
Definition: vector.hpp:51
void ComputeGradientBlocked(const BlockVector &bx) const
Specialized version of GetGradient() for BlockVector.
SparseMatrix * Grad
const BlockVector & Prolongate(const BlockVector &bx) const
virtual Operator & GetGradient(const Vector &x) const
void SetEssentialVDofs(const Array< int > &ess_vdofs_list)
Specify essential boundary conditions.
Array< Array< int > * > ess_tdofs
Abstract operator.
Definition: operator.hpp:24
virtual const SparseMatrix * GetRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Definition: fespace.hpp:334
A class to handle Block systems in a matrix-free implementation.
FiniteElementSpace * FESpace(int k)
Return the k-th FE space of the BlockNonlinearForm.
const Vector & Prolongate(const Vector &x) const
void MultBlocked(const BlockVector &bx, BlockVector &by) const
double f(const Vector &p)