MFEM  v4.5.1
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
pparamnonlinearform.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, 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 #include "mfem.hpp"
13 #include "pparamnonlinearform.hpp"
14 
15 #ifdef MFEM_USE_MPI
16 
17 namespace mfem
18 {
19 
21  &statef,
24 {
25  pBlockGrad = nullptr;
26  SetParSpaces(statef,paramf);
27 }
28 
31 {
32  delete pBlockGrad;
33  pBlockGrad = nullptr;
34 
35  for (int s1=0; s1<fes.Size(); ++s1)
36  {
37  for (int s2=0; s2<fes.Size(); ++s2)
38  {
39  delete phBlockGrad(s1,s2);
40  }
41  }
42 
43  Array<FiniteElementSpace *> serialSpaces(statef.Size());
44  Array<FiniteElementSpace *> prmserialSpaces(paramf.Size());
45  for (int s=0; s<statef.Size(); s++)
46  {
47  serialSpaces[s] = (FiniteElementSpace *) statef[s];
48  }
49  for (int s=0; s<paramf.Size(); s++)
50  {
51  prmserialSpaces[s] = (FiniteElementSpace *) paramf[s];
52  }
53 
54  SetSpaces(serialSpaces,prmserialSpaces);
55 
56  phBlockGrad.SetSize(fes.Size(), fes.Size());
57 
58  for (int s1=0; s1<fes.Size(); ++s1)
59  {
60  for (int s2=0; s2<fes.Size(); ++s2)
61  {
63  }
64  }
65 }
66 
68 {
69  return (ParFiniteElementSpace *)fes[k];
70 }
71 
73 {
74  return (const ParFiniteElementSpace *)fes[k];
75 }
76 
77 
79 {
80  return (ParFiniteElementSpace *)paramfes[k];
81 }
82 
84 {
85  return (const ParFiniteElementSpace *)paramfes[k];
86 }
87 
88 // Here, rhs is a true dof vector
90  Array<Array<int> *>&bdr_attr_is_ess,
91  Array<Vector *> &rhs)
92 {
93  Array<Vector *> nullarray(fes.Size());
94  nullarray = NULL;
95 
96  ParametricBNLForm::SetEssentialBC(bdr_attr_is_ess, nullarray);
97 
98  for (int s = 0; s < fes.Size(); ++s)
99  {
100  if (rhs[s])
101  {
102  rhs[s]->SetSubVector(*ess_tdofs[s], 0.0);
103  }
104  }
105 }
106 
108  Array<Array<int> *>&bdr_attr_is_ess,
109  Array<Vector *> &rhs)
110 {
111  Array<Vector *> nullarray(fes.Size());
112  nullarray = NULL;
113 
114  ParametricBNLForm::SetParamEssentialBC(bdr_attr_is_ess, nullarray);
115 
116  for (int s = 0; s < paramfes.Size(); ++s)
117  {
118  if (rhs[s])
119  {
120  rhs[s]->SetSubVector(*paramess_tdofs[s], 0.0);
121  }
122  }
123 }
124 
126 {
127  xs_true.Update(const_cast<Vector&>(x), block_trueOffsets);
129 
130  for (int s = 0; s < fes.Size(); ++s)
131  {
132  fes[s]->GetProlongationMatrix()->Mult(xs_true.GetBlock(s), xs.GetBlock(s));
133  }
134 
136  double englo = 0.0;
137 
138  MPI_Allreduce(&enloc, &englo, 1, MPI_DOUBLE, MPI_SUM,
139  ParFESpace(0)->GetComm());
140 
141  return englo;
142 }
143 
144 void ParParametricBNLForm::Mult(const Vector &x, Vector &y) const
145 {
146  xs_true.Update(const_cast<Vector&>(x), block_trueOffsets);
150 
151  for (int s=0; s<fes.Size(); ++s)
152  {
153  fes[s]->GetProlongationMatrix()->Mult(
155  }
156 
158 
159  if (fnfi.Size() > 0)
160  {
161  MFEM_ABORT("TODO: assemble contributions from shared face terms");
162  }
163 
164  for (int s=0; s<fes.Size(); ++s)
165  {
166  fes[s]->GetProlongationMatrix()->MultTranspose(
168 
170  }
171 }
172 
173 /// Block T-Vector to Block T-Vector
175 {
176  xs_true.Update(const_cast<Vector&>(x), paramblock_trueOffsets);
180 
181  for (int s=0; s<paramfes.Size(); ++s)
182  {
183  paramfes[s]->GetProlongationMatrix()->Mult(
185  }
186 
188 
189  if (fnfi.Size() > 0)
190  {
191  MFEM_ABORT("TODO: assemble contributions from shared face terms");
192  }
193 
194  for (int s=0; s<paramfes.Size(); ++s)
195  {
196  paramfes[s]->GetProlongationMatrix()->MultTranspose(
198 
200  }
201 
202 }
203 
204 /// Return the local gradient matrix for the given true-dof vector x
206  const Vector &x) const
207 {
208  xs_true.Update(const_cast<Vector&>(x), block_trueOffsets);
210 
211  for (int s=0; s<fes.Size(); ++s)
212  {
213  fes[s]->GetProlongationMatrix()->Mult(
215  }
216 
218  xdv); // (re)assemble Grad with b.c.
219 
220  delete BlockGrad;
222 
223  for (int i = 0; i < fes.Size(); ++i)
224  {
225  for (int j = 0; j < fes.Size(); ++j)
226  {
227  BlockGrad->SetBlock(i, j, Grads(i, j));
228  }
229  }
230  return *BlockGrad;
231 }
232 
233 // Set the operator type id for the parallel gradient matrix/operator.
235 {
236  for (int s1=0; s1<fes.Size(); ++s1)
237  {
238  for (int s2=0; s2<fes.Size(); ++s2)
239  {
240  phBlockGrad(s1,s2)->SetType(tid);
241  }
242  }
243 }
244 
246 {
247  if (pBlockGrad == NULL)
248  {
250  }
251 
253 
254  for (int s1=0; s1<fes.Size(); ++s1)
255  {
256  pfes[s1] = ParFESpace(s1);
257 
258  for (int s2=0; s2<fes.Size(); ++s2)
259  {
260  phBlockGrad(s1,s2)->Clear();
261  }
262  }
263 
264  GetLocalGradient(x); // gradients are stored in 'Grads'
265 
266  if (fnfi.Size() > 0)
267  {
268  MFEM_ABORT("TODO: assemble contributions from shared face terms");
269  }
270 
271  for (int s1=0; s1<fes.Size(); ++s1)
272  {
273  for (int s2=0; s2<fes.Size(); ++s2)
274  {
275  OperatorHandle dA(phBlockGrad(s1,s2)->Type()),
276  Ph(phBlockGrad(s1,s2)->Type()),
277  Rh(phBlockGrad(s1,s2)->Type());
278 
279  if (s1 == s2)
280  {
281  dA.MakeSquareBlockDiag(pfes[s1]->GetComm(), pfes[s1]->GlobalVSize(),
282  pfes[s1]->GetDofOffsets(), Grads(s1,s1));
283  Ph.ConvertFrom(pfes[s1]->Dof_TrueDof_Matrix());
284  phBlockGrad(s1,s1)->MakePtAP(dA, Ph);
285 
286  OperatorHandle Ae;
287  Ae.EliminateRowsCols(*phBlockGrad(s1,s1), *ess_tdofs[s1]);
288  }
289  else
290  {
291  dA.MakeRectangularBlockDiag(pfes[s1]->GetComm(),
292  pfes[s1]->GlobalVSize(),
293  pfes[s2]->GlobalVSize(),
294  pfes[s1]->GetDofOffsets(),
295  pfes[s2]->GetDofOffsets(),
296  Grads(s1,s2));
297  Rh.ConvertFrom(pfes[s1]->Dof_TrueDof_Matrix());
298  Ph.ConvertFrom(pfes[s2]->Dof_TrueDof_Matrix());
299 
300  phBlockGrad(s1,s2)->MakeRAP(Rh, dA, Ph);
301 
302  phBlockGrad(s1,s2)->EliminateRows(*ess_tdofs[s1]);
303  phBlockGrad(s1,s2)->EliminateCols(*ess_tdofs[s2]);
304  }
305 
306  pBlockGrad->SetBlock(s1, s2, phBlockGrad(s1,s2)->Ptr());
307  }
308  }
309 
310  return *pBlockGrad;
311 }
312 
314 {
315  delete pBlockGrad;
316  for (int s1=0; s1<fes.Size(); ++s1)
317  {
318  for (int s2=0; s2<fes.Size(); ++s2)
319  {
320  delete phBlockGrad(s1,s2);
321  }
322  }
323 }
324 
325 
327 {
328  xs_true.Update(const_cast<Vector&>(xv), block_trueOffsets);
330  for (int s=0; s<fes.Size(); ++s)
331  {
332  fes[s]->GetProlongationMatrix()->Mult(
334  }
335 }
336 
337 
339 {
340  xs_true.Update(const_cast<Vector&>(av), block_trueOffsets);
342  for (int s=0; s<fes.Size(); ++s)
343  {
344  fes[s]->GetProlongationMatrix()->Mult(
346  }
347 }
348 
350 {
351  xs_true.Update(const_cast<Vector&>(dv),paramblock_trueOffsets);
353  for (int s=0; s<paramfes.Size(); ++s)
354  {
355  paramfes[s]->GetProlongationMatrix()->Mult(
357  }
358 }
359 
360 }
361 
362 #endif
virtual void SetParamFields(const Vector &dv) const
Set the parameters/design fields.
int Size() const
Return the logical size of the array.
Definition: array.hpp:138
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
Definition: vector.cpp:573
virtual void ParamMult(const Vector &x, Vector &y) const
Calculates the product of the adjoint field and the derivative of the state residual with respect to ...
void ConvertFrom(OperatorHandle &A)
Convert the given OperatorHandle A to the currently set type id.
Definition: handle.cpp:200
virtual void SetEssentialBC(const Array< Array< int > * > &bdr_attr_is_ess, Array< Vector * > &rhs)
Set the state essential BCs. Here, rhs is a true dof vector!
Array2D< OperatorHandle * > phBlockGrad
virtual void SetParamEssentialBC(const Array< Array< int > * > &bdr_attr_is_ess, Array< Vector * > &rhs)
Set the essential boundary conditions on the parametric fields.
Array< FiniteElementSpace * > fes
FE spaces on which the form lives.
virtual void Mult(const Vector &x, Vector &y) const
Calculates the residual for a state input given by block T-Vector. The result is Block T-Vector! The ...
Pointer to an Operator of a specified type.
Definition: handle.hpp:33
A class representing a general parametric block nonlinear operator defined on the Cartesian product o...
void Update(double *data, const Array< int > &bOffsets)
Update method.
Definition: blockvector.cpp:85
const BlockOperator & GetLocalGradient(const Vector &x) const
Return the local block gradient matrix for the given true-dof vector x.
Abstract parallel finite element space.
Definition: pfespace.hpp:28
ParParametricBNLForm()
Construct an empty ParParametricBNLForm. Initialize with SetParSpaces().
ParFiniteElementSpace * ParFESpace(int k)
Return the k-th parallel FE state space of the ParParametricBNLForm.
Array< Array< int > * > paramess_tdofs
Array< FiniteElementSpace * > paramfes
FE spaces for the parametric fields.
void SetParSpaces(Array< ParFiniteElementSpace * > &statef, Array< ParFiniteElementSpace * > &paramf)
Set the parallel FE spaces for the state and the parametric fields. After a call to SetParSpaces()...
virtual ~ParParametricBNLForm()
Destructor.
virtual void SetParamEssentialBC(const Array< Array< int > * > &bdr_attr_is_ess, Array< Vector * > &rhs)
Set the essential boundary conditions on the parametric fields.
double GetEnergyBlocked(const BlockVector &bx, const BlockVector &dx) const
void SetGradientType(Operator::Type tid)
Set the operator type id for the blocks of the parallel gradient matrix/operator. The default type is...
void EliminateRowsCols(OperatorHandle &A, const Array< int > &ess_dof_list)
Reset the OperatorHandle to be the eliminated part of A after elimination of the essential dofs ess_d...
Definition: handle.cpp:252
Array< ParametricBNLFormIntegrator * > fnfi
Set of interior face Integrators to be assembled (added).
void MultBlocked(const BlockVector &bx, const BlockVector &dx, BlockVector &by) const
virtual void SetEssentialBC(const Array< Array< int > * > &bdr_attr_is_ess, Array< Vector * > &rhs)
Set the essential boundary conditions.
void MultParamBlocked(const BlockVector &bx, const BlockVector &ax, const BlockVector &dx, BlockVector &dy) const
virtual void SetStateFields(const Vector &xv) const
Set the state fields.
Type
Enumeration defining IDs for some classes derived from Operator.
Definition: operator.hpp:256
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition: fespace.hpp:96
virtual void SetAdjointFields(const Vector &av) const
Set the adjoint fields.
Array< Array< int > * > ess_tdofs
virtual double GetEnergy(const Vector &x) const
Computes the energy of the system.
void ComputeGradientBlocked(const BlockVector &bx, const BlockVector &dx) const
Specialized version of GetGradient() for BlockVector.
Array2D< SparseMatrix * > Grads
Vector data type.
Definition: vector.hpp:60
ID for class HypreParMatrix.
Definition: operator.hpp:260
RefCoord s[3]
A class to handle Block systems in a matrix-free implementation.
ParFiniteElementSpace * ParParamFESpace(int k)
void SetSpaces(Array< FiniteElementSpace * > &statef, Array< FiniteElementSpace * > &paramf)
(Re)initialize the ParametricBNLForm.
virtual BlockOperator & GetGradient(const Vector &x) const
Return the block gradient matrix for the given true-dof vector x.
void SetBlock(int iRow, int iCol, Operator *op, double c=1.0)
Add a block op in the block-entry (iblock, jblock).
Vector & GetBlock(int i)
Get the i-th vector in the block.
Definition: blockvector.hpp:90