DUNE-ACFEM (2.5.1)

bulkblockconstraints.hh
1 #ifndef _DUNE_ACFEM_BULK_BLOCKCONSTRAINTS_HH_
2 #define _DUNE_ACFEM_BULK_BLOCKCONSTRAINTS_HH_
3 
4 #include "blockconstraintsoperator.hh"
5 #include "../../common/functor.hh"
6 #include <dune/fem/misc/mpimanager.hh>
7 
8 namespace Dune {
9 
10  namespace ACFem {
11 
20  template<class JacobianOperator, class Traits>
21  class BulkBlockConstraints;
22 
23  template<class JacobianOperator, class Traits>
24  class LocalBulkBlockConstraints;
25 
26  template<class JacobianOperator>
27  struct BulkBlockConstraintsDefaultTraits
28  : public
29  BlockConstraintsDefaultStorageTraits<
30  BulkBlockConstraints<JacobianOperator,
31  BulkBlockConstraintsDefaultTraits<JacobianOperator> >,
32  LocalBulkBlockConstraints<JacobianOperator,
33  BulkBlockConstraintsDefaultTraits<JacobianOperator> > >
34  {};
35 
48  template<class JacobianOperator, class Traits = BulkBlockConstraintsDefaultTraits<JacobianOperator> >
50  : public DifferentiableBlockConstraintsOperatorInterface<JacobianOperator, Traits>
51  {
53  typedef
55  BaseType;
56  public:
57  typedef Traits TraitsType;
58  typedef typename TraitsType::GlobalOperatorType GlobalOperatorType;
59  typedef JacobianOperator JacobianOperatorType;
60  typedef typename JacobianOperatorType::DomainFunctionType DiscreteFunctionType;
61  typedef typename TraitsType::LocalOperatorType LocalOperatorType;
62 
63  typedef typename TraitsType::LocalObjectWrapperType LocalObjectWrapperType;
64  typedef typename TraitsType::LocalObjectType LocalObjectType;
65  typedef typename TraitsType::LocalObjectFactoryType LocalObjectFactoryType;
66  typedef typename TraitsType::LocalObjectStorageType LocalObjectStorageType;
67 
68  typedef LocalBulkBlockConstraints<JacobianOperatorType, TraitsType> LocalBaseObjectType;
69 
70  friend LocalObjectType; // not necessarily identical to LocalBulkBlockConstraints
71  friend LocalBaseObjectType;
72 
73  typedef typename DiscreteFunctionType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
74  typedef typename DiscreteFunctionSpaceType::GridPartType GridPartType;
75  typedef typename DiscreteFunctionSpaceType::EntityType EntityType;
76  protected:
77  typedef typename DiscreteFunctionSpaceType::BlockMapperType BlockMapperType;
78  typedef Dune::Fem::SlaveDofs<DiscreteFunctionSpaceType, BlockMapperType> SlaveDofsType;
79  typedef typename SlaveDofsType::SingletonKey SlaveDofsKeyType;
80  typedef Dune::Fem::SingletonList<SlaveDofsKeyType, SlaveDofsType> SlaveDofsProviderType;
81  typedef typename BlockMapperType::GlobalKeyType GlobalKeyType;
82 
83  enum { localBlockSize = DiscreteFunctionSpaceType::localBlockSize };
84  public:
85 
87  BulkBlockConstraints(const DiscreteFunctionType& values, const std::vector<unsigned>& mask)
88  : space_(values.space()),
89  localObjectFactory_(*static_cast<GlobalOperatorType *>(this)),
90  localObjectStorage_(localObjectFactory_),
91  affineOffset_(values),
92  constrainedDofsMask_(mask),
93  slaveDofMask_(space_.blockMapper().size(), false),
94  numSlaveDofs_(space_.slaveDofs().size()-1),
95  numConstrained_(std::count_if(constrainedDofsMask_.begin(), constrainedDofsMask_.end(),
96  [](const unsigned& value) { return value > 0; })),
97  sequence_(space_.sequence())
98  {}
99 
101  BulkBlockConstraints(const DiscreteFunctionSpaceType& space)
102  : space_(space),
103  localObjectFactory_(*static_cast<GlobalOperatorType *>(this)),
104  localObjectStorage_(localObjectFactory_),
105  affineOffset_("Constraint Values", space_),
106  constrainedDofsMask_(space_.blockMapper().size(), 0),
107  slaveDofMask_(space_.blockMapper().size(), false),
108  numSlaveDofs_(space_.slaveDofs().size()-1),
109  numConstrained_(0),
110  sequence_(-1)
111  {}
112 
118  void rebuild() const
119  {
120  if (sequence_ != space_.sequence()) {
121  rebuildSlaveDofs();
122  }
123 
124  constrainedDofsMask_.resize(space_.blockMapper().size(), 0);
125 
126  numConstrained_ =
127  std::count_if(constrainedDofsMask_.begin(), constrainedDofsMask_.end(),
128  [](const unsigned& value) { return value > 0; });
129 
130  sequence_ = space_.sequence();
131  }
132 
133  protected:
134  void rebuildSlaveDofs() const
135  {
136  const auto& slaveDofs = space_.slaveDofs();
137  numSlaveDofs_ = slaveDofs.size() - 1;
138 
139  slaveDofMask_.resize(space_.blockMapper().size());
140  slaveDofMask_.clear();
141  for (unsigned i = 0; i < numSlaveDofs_; ++i) {
142  slaveDofMask_[slaveDofs[i]] = true;
143  }
144  }
145 
146  bool isSlaveDof(GlobalKeyType index) const
147  {
148  assert(Fem::MPIManager::size() > 1 || numSlaveDofs_ == 0);
149  return numSlaveDofs_ > 0 && slaveDofMask_[index];
150  }
151  public:
163  void operator()(const DiscreteFunctionType &u, DiscreteFunctionType &w) const
164  {
165  BaseType::rebuild(); // Update if out of sequence_ number
166 
167  if (size() == 0) {
168  return;
169  }
170 
171  auto uIt = u.dbegin();
172  auto wIt = w.dbegin();
173  auto offsetIt = affineOffset_.dbegin();
174  auto maskIt = constrainedDofsMask_.begin();
175  auto maskEnd = constrainedDofsMask_.end();
176  while (maskIt != maskEnd) {
177  if (*maskIt) {
178  for (int l = 0; l < localBlockSize; ++l, ++wIt, ++offsetIt, ++uIt) {
179  *wIt = *uIt - *offsetIt;
180  }
181  } else {
182  for (int l = 0; l < localBlockSize; ++l, ++wIt, ++offsetIt, ++uIt);
183  }
184  ++maskIt;
185  }
186  }
187 
194  void jacobian(const DiscreteFunctionType& u, JacobianOperatorType& jOp) const
195  {
196  BaseType::rebuild(); // Update if out of sequence_ number
197 
198  if (size() == 0) {
199  return;
200  }
201 
202  const auto end = space_.end();
203  for (auto it = space_.begin(); it != end; ++it) {
204  auto localConstraints = localOperator(*it);
205  auto jOpLocal = jOp.localMatrix(*it, *it);
206 
207  localConstraints.jacobian(u.localFunction(*it), jOpLocal);
208  }
209 
210  jOp.communicate();
211  }
212 
224  void constrain(DiscreteFunctionType& w) const
225  {
226  BaseType::rebuild(); // Update if out of sequence_ number
227 
228  if (size() == 0) {
229  // nothing to do.
230  return;
231  }
232 
233  auto wIt = w.dbegin();
234  auto offsetIt = affineOffset_.dbegin();
235  auto maskIt = constrainedDofsMask_.begin();
236  auto maskEnd = constrainedDofsMask_.end();
237  while (maskIt != maskEnd) {
238  if (*maskIt) {
239  for (int l = 0; l < localBlockSize; ++l, ++wIt, ++offsetIt) {
240  *wIt = *offsetIt;
241  }
242  } else {
243  for (int l = 0; l < localBlockSize; ++l, ++wIt, ++offsetIt);
244  }
245  ++maskIt;
246  }
247  }
248 
250  void zeroConstrain(DiscreteFunctionType& w) const
251  {
253 
254  if (size() == 0) {
255  return;
256  }
257 
258  auto wIt = w.dbegin();
259  auto maskIt = constrainedDofsMask_.begin();
260  auto maskEnd = constrainedDofsMask_.end();
261  while (maskIt != maskEnd) {
262  if (*maskIt) {
263  for (int l = 0; l < localBlockSize; ++l, ++wIt) {
264  *wIt = 0;
265  }
266  } else {
267  for (int l = 0; l < localBlockSize; ++l, ++wIt);
268  }
269  ++maskIt;
270  }
271  }
272 
273  size_t size() const {
274  return numConstrained_;
275  }
276 
277  LocalOperatorType localOperator(const EntityType& entity) const
278  {
279  return LocalOperatorType(entity, localObjectStorage_);
280  }
281 
282  LocalOperatorType localOperator() const
283  {
284  return LocalOperatorType(localObjectStorage_);
285  }
286 
287  protected:
288  const DiscreteFunctionSpaceType& space_;
289  mutable LocalObjectFactoryType localObjectFactory_;
290  mutable LocalObjectStorageType localObjectStorage_;
291  mutable DiscreteFunctionType affineOffset_;
292  mutable std::vector<unsigned> constrainedDofsMask_;
293  mutable std::vector<bool> slaveDofMask_;
294  mutable std::size_t numSlaveDofs_;
295  mutable unsigned numConstrained_;
296  mutable int sequence_;
297  };
298 
299  template<class JacobianOperator, class Traits>
300  class LocalBulkBlockConstraints
301  {
302  protected:
303  typedef Traits TraitsType;
304  typedef BulkBlockConstraints<JacobianOperator, TraitsType> OperatorType;
305  typedef JacobianOperator JacobianOperatorType;
306  typedef typename JacobianOperatorType::RangeFunctionType DiscreteFunctionType;
307  typedef typename DiscreteFunctionType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
308  typedef typename DiscreteFunctionSpaceType::BlockMapperType BlockMapperType;
309  typedef typename BlockMapperType::GlobalKeyType GlobalKeyType;
310 
311  friend typename OperatorType::LocalObjectFactoryType;
312 
313  LocalBulkBlockConstraints(const OperatorType& op)
314  : entity_(0),
315  operator_(op),
316  numberOfLocalBlocks_(0),
317  constrainedDofs_(operator_.space_.blockMapper().maxNumDofs()),
318  slaveDofs_(operator_.space_.blockMapper().maxNumDofs())
319  {}
320 
321  public:
322  typedef typename DiscreteFunctionType::LocalFunctionType LocalFunctionType;
323  typedef typename DiscreteFunctionSpaceType::EntityType EntityType;
324 
325  enum { localBlockSize = DiscreteFunctionSpaceType::localBlockSize };
326 
327  void init(const EntityType& entity)
328  {
329  entity_ = &entity;
330  numberOfLocalBlocks_ = operator_.space_.blockMapper().numDofs(*entity_);
331 
332 #if 1
333  // ... this way :::
334  operator_.space_.blockMapper().mapEach(
335  *entity_,
336  makeTupleFunctor(ExtractFunctor<std::vector<unsigned>, std::vector<unsigned> >(constrainedDofs_, operator_.constrainedDofsMask_),
337  ExtractFunctor<std::vector<bool>, std::vector<bool> >(slaveDofs_, operator_.slaveDofMask_)));
338 #else
339  // ... likewise ...
340  operator_.space_.blockMapper().mapEach(
341  *entity_,
342  makePairFunctor(ExtractFunctor<std::vector<unsigned>, std::vector<unsigned> >(constrainedDofs_, operator_.constrainedDofsMask_),
343  ExtractFunctor<std::vector<bool>, std::vector<bool> >(slaveDofs_, operator_.slaveDofMask_)));
344 #endif
345  numConstrained_ = std::count_if(constrainedDofs_.begin(), constrainedDofs_.end(),
346  [](const unsigned& value) { return value > 0; });
347  }
348 
349  bool unconstrained() const
350  {
351  return numConstrained_ == 0;
352  }
353 
354  bool totallyConstrained() const
355  {
356  return numConstrained_ == numberOfLocalBlocks_;
357  }
358 
359  size_t numConstrained() const
360  {
361  return numConstrained_;
362  }
363 
364  void operator()(const LocalFunctionType& u, LocalFunctionType& w) const
365  {
366  if (unconstrained()) {
367  return;
368  }
369 
370  LocalFunctionType localOffset(operator_.affineOffset_.localFunction(*entity_));
371 
372  int localDof = 0;
373  for (int localBlockDof = 0; localBlockDof < numberOfLocalBlocks_; ++localBlockDof) {
374  if (constrainedDofs_[localBlockDof]) {
375  if (slaveDofs_[localBlockDof]) {
376  for (int l = 0; l < localBlockSize; ++l, ++localDof) {
377  w[localDof] = 0;
378  }
379  } else {
380  for (int l = 0; l < localBlockSize; ++l, ++localDof) {
381  w[localDof] = u[localDof] - localOffset[localDof];
382  }
383  }
384  } else {
385  // Do nothing, operation is restricted to masked-out DOFs
386  localDof += localBlockSize;
387  }
388  }
389  }
390 
391  template<class LocalMatrix>
392  void jacobian(const LocalFunctionType& u /* unused */, LocalMatrix& jOpLocal) const
393  {
394  if (unconstrained()) {
395  return;
396  }
397 
398  int localDof = 0;
399  for (int localBlockDof = 0; localBlockDof < numberOfLocalBlocks_; ++localBlockDof) {
400  unsigned constraintFactor = constrainedDofs_[localBlockDof]; // 0: unconstrained, > 0: number of elements sharing this DOF.
401  if (constraintFactor > 0) {
402  double value = slaveDofs_[localBlockDof] ? 0.0 : 1.0 / (double)constraintFactor;
403  for (int l = 0; l < localBlockSize; ++l, ++localDof) {
404  jOpLocal.clearRow(localDof); // indexed by non-block-DoF
405  jOpLocal.set(localDof, localDof, value);
406  }
407  } else {
408  localDof += localBlockSize;
409  }
410  }
411  }
412 
413  void constrain(LocalFunctionType& w) const
414  {
415  if (unconstrained()) {
416  return;
417  }
418 
419  LocalFunctionType localOffset(operator_.affineOffset_.localFunction(*entity_));
420 
421  int localDof = 0;
422  for (int localBlockDof = 0; localBlockDof < numberOfLocalBlocks_; ++localBlockDof) {
423  if (constrainedDofs_[localBlockDof]) {
424  if (slaveDofs_[localBlockDof]) {
425  for (int l = 0; l < localBlockSize; ++l, ++localDof) {
426  w[localDof] = 0;
427  }
428  } else {
429  for (int l = 0; l < localBlockSize; ++l, ++localDof) {
430  w[localDof] = localOffset[localDof];
431  }
432  }
433  } else {
434  // Do nothing, operation is restricted to masked-out DOFs
435  localDof += localBlockSize;
436  }
437  }
438  }
439 
440  void zeroConstrain(LocalFunctionType& w) const
441  {
442  if (unconstrained()) {
443  return;
444  }
445 
446  int localDof = 0;
447  for (int localBlockDof = 0; localBlockDof < numberOfLocalBlocks_; ++localBlockDof) {
448  if (constrainedDofs_[localBlockDof]) {
449  for (int l = 0; l < localBlockSize; ++l, ++localDof) {
450  w[localDof] = 0;
451  }
452  } else {
453  // Do nothing, operation is restricted to masked-out DOFs
454  localDof += localBlockSize;
455  }
456  }
457  }
458 
459  protected:
460  const EntityType* entity_;
461  const OperatorType& operator_;
462  int numberOfLocalBlocks_;
463  std::vector<unsigned> constrainedDofs_;
464  std::vector<bool> slaveDofs_;
465  int numConstrained_;
466  };
467 
469 
471 
472  } // ACFem::
473 
474 } // Dune::
475 
476 
477 #endif // _DUNE_ACFEM_EMPTY_BLOCKCONSTRAINTS_HH_
Interface class for a block-constraints-operator.
Definition: blockconstraintsoperator.hh:75
A default implementation for bulk block constraints.
Definition: bulkblockconstraints.hh:51
void operator()(const DiscreteFunctionType &u, DiscreteFunctionType &w) const
Apply the operator to the given argument.
Definition: bulkblockconstraints.hh:163
void zeroConstrain(DiscreteFunctionType &w) const
Unconditionally set the values of all masked DoFs to zero.
Definition: bulkblockconstraints.hh:250
BulkBlockConstraints(const DiscreteFunctionSpaceType &space)
Construct an empty operator.
Definition: bulkblockconstraints.hh:101
BulkBlockConstraints(const DiscreteFunctionType &values, const std::vector< unsigned > &mask)
Explicitly set the constraints to defined values.
Definition: bulkblockconstraints.hh:87
void rebuild() const
An update method which has to be called initially or after mesh-adaptation, or for time-dependent con...
Definition: bulkblockconstraints.hh:118
void constrain(DiscreteFunctionType &w) const
The solution operator; unconditionally install the given constraints into the argument.
Definition: bulkblockconstraints.hh:224
void jacobian(const DiscreteFunctionType &u, JacobianOperatorType &jOp) const
The Jacobian of the operator.
Definition: bulkblockconstraints.hh:194
Interface class for a differentiable block-constraints-operator.
Definition: blockconstraintsoperator.hh:182
void rebuild() const
An update method which has to be called initially or after mesh-adaptation, or for time-dependent con...
Definition: blockconstraintsoperator.hh:98
PairFunctor< FunctorOne, FunctorTwo > makePairFunctor(FunctorOne &&func1, FunctorTwo &&func2)
Combine two functors into one.
Definition: functor.hh:87
TupleFunctor< Types... > makeTupleFunctor(Types &&... args)
Combine several functors into one.
Definition: functor.hh:142
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)