1#ifndef _DUNE_ACFEM_BULK_BLOCKCONSTRAINTS_HH_
2#define _DUNE_ACFEM_BULK_BLOCKCONSTRAINTS_HH_
4#include "blockconstraintsoperator.hh"
5#include "../../common/functor.hh"
6#include <dune/fem/misc/mpimanager.hh>
20 template<
class JacobianOperator,
class Traits>
21 class BulkBlockConstraints;
23 template<
class JacobianOperator,
class Traits>
24 class LocalBulkBlockConstraints;
26 template<
class JacobianOperator>
27 struct BulkBlockConstraintsDefaultTraits
29 BlockConstraintsDefaultStorageTraits<
30 BulkBlockConstraints<JacobianOperator,
31 BulkBlockConstraintsDefaultTraits<JacobianOperator> >,
32 LocalBulkBlockConstraints<JacobianOperator,
33 BulkBlockConstraintsDefaultTraits<JacobianOperator> > >
48 template<
class JacobianOperator,
class Traits = BulkBlockConstra
intsDefaultTraits<JacobianOperator> >
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;
63 typedef typename TraitsType::LocalObjectWrapperType LocalObjectWrapperType;
64 typedef typename TraitsType::LocalObjectType LocalObjectType;
65 typedef typename TraitsType::LocalObjectFactoryType LocalObjectFactoryType;
66 typedef typename TraitsType::LocalObjectStorageType LocalObjectStorageType;
68 typedef LocalBulkBlockConstraints<JacobianOperatorType, TraitsType> LocalBaseObjectType;
70 friend LocalObjectType;
71 friend LocalBaseObjectType;
73 typedef typename DiscreteFunctionType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
74 typedef typename DiscreteFunctionSpaceType::GridPartType GridPartType;
75 typedef typename DiscreteFunctionSpaceType::EntityType EntityType;
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;
83 enum { localBlockSize = DiscreteFunctionSpaceType::localBlockSize };
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())
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),
120 if (sequence_ != space_.sequence()) {
124 constrainedDofsMask_.resize(space_.blockMapper().size(), 0);
127 std::count_if(constrainedDofsMask_.begin(), constrainedDofsMask_.end(),
128 [](
const unsigned& value) { return value > 0; });
130 sequence_ = space_.sequence();
134 void rebuildSlaveDofs()
const
136 const auto& slaveDofs = space_.slaveDofs();
137 numSlaveDofs_ = slaveDofs.size() - 1;
139 slaveDofMask_.resize(space_.blockMapper().size());
140 slaveDofMask_.clear();
141 for (
unsigned i = 0; i < numSlaveDofs_; ++i) {
142 slaveDofMask_[slaveDofs[i]] =
true;
146 bool isSlaveDof(GlobalKeyType index)
const
148 assert(Fem::MPIManager::size() > 1 || numSlaveDofs_ == 0);
149 return numSlaveDofs_ > 0 && slaveDofMask_[index];
163 void operator()(
const DiscreteFunctionType &u, DiscreteFunctionType &w)
const
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) {
178 for (
int l = 0; l < localBlockSize; ++l, ++wIt, ++offsetIt, ++uIt) {
179 *wIt = *uIt - *offsetIt;
182 for (
int l = 0; l < localBlockSize; ++l, ++wIt, ++offsetIt, ++uIt);
194 void jacobian(
const DiscreteFunctionType& u, JacobianOperatorType& jOp)
const
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);
207 localConstraints.jacobian(u.localFunction(*it), jOpLocal);
233 auto wIt = w.dbegin();
234 auto offsetIt = affineOffset_.dbegin();
235 auto maskIt = constrainedDofsMask_.begin();
236 auto maskEnd = constrainedDofsMask_.end();
237 while (maskIt != maskEnd) {
239 for (
int l = 0; l < localBlockSize; ++l, ++wIt, ++offsetIt) {
243 for (
int l = 0; l < localBlockSize; ++l, ++wIt, ++offsetIt);
258 auto wIt = w.dbegin();
259 auto maskIt = constrainedDofsMask_.begin();
260 auto maskEnd = constrainedDofsMask_.end();
261 while (maskIt != maskEnd) {
263 for (
int l = 0; l < localBlockSize; ++l, ++wIt) {
267 for (
int l = 0; l < localBlockSize; ++l, ++wIt);
273 size_t size()
const {
274 return numConstrained_;
277 LocalOperatorType localOperator(
const EntityType& entity)
const
279 return LocalOperatorType(entity, localObjectStorage_);
282 LocalOperatorType localOperator()
const
284 return LocalOperatorType(localObjectStorage_);
288 const DiscreteFunctionSpaceType& space_;
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_;
299 template<
class JacobianOperator,
class Traits>
300 class LocalBulkBlockConstraints
303 typedef Traits TraitsType;
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;
311 friend typename OperatorType::LocalObjectFactoryType;
313 LocalBulkBlockConstraints(
const OperatorType& op)
316 numberOfLocalBlocks_(0),
317 constrainedDofs_(operator_.space_.blockMapper().maxNumDofs()),
318 slaveDofs_(operator_.space_.blockMapper().maxNumDofs())
322 typedef typename DiscreteFunctionType::LocalFunctionType LocalFunctionType;
323 typedef typename DiscreteFunctionSpaceType::EntityType EntityType;
325 enum { localBlockSize = DiscreteFunctionSpaceType::localBlockSize };
327 void init(
const EntityType& entity)
330 numberOfLocalBlocks_ = operator_.space_.blockMapper().numDofs(*entity_);
334 operator_.space_.blockMapper().mapEach(
336 makeTupleFunctor(ExtractFunctor<std::vector<unsigned>, std::vector<unsigned> >(constrainedDofs_, operator_.constrainedDofsMask_),
337 ExtractFunctor<std::vector<bool>, std::vector<bool> >(slaveDofs_, operator_.slaveDofMask_)));
340 operator_.space_.blockMapper().mapEach(
342 makePairFunctor(ExtractFunctor<std::vector<unsigned>, std::vector<unsigned> >(constrainedDofs_, operator_.constrainedDofsMask_),
343 ExtractFunctor<std::vector<bool>, std::vector<bool> >(slaveDofs_, operator_.slaveDofMask_)));
345 numConstrained_ = std::count_if(constrainedDofs_.begin(), constrainedDofs_.end(),
346 [](
const unsigned& value) { return value > 0; });
349 bool unconstrained()
const
351 return numConstrained_ == 0;
354 bool totallyConstrained()
const
356 return numConstrained_ == numberOfLocalBlocks_;
359 size_t numConstrained()
const
361 return numConstrained_;
364 void operator()(
const LocalFunctionType& u, LocalFunctionType& w)
const
366 if (unconstrained()) {
370 LocalFunctionType localOffset(operator_.affineOffset_.localFunction(*entity_));
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) {
380 for (
int l = 0; l < localBlockSize; ++l, ++localDof) {
381 w[localDof] = u[localDof] - localOffset[localDof];
386 localDof += localBlockSize;
391 template<
class LocalMatrix>
392 void jacobian(
const LocalFunctionType& u , LocalMatrix& jOpLocal)
const
394 if (unconstrained()) {
399 for (
int localBlockDof = 0; localBlockDof < numberOfLocalBlocks_; ++localBlockDof) {
400 unsigned constraintFactor = constrainedDofs_[localBlockDof];
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);
405 jOpLocal.set(localDof, localDof, value);
408 localDof += localBlockSize;
413 void constrain(LocalFunctionType& w)
const
415 if (unconstrained()) {
419 LocalFunctionType localOffset(operator_.affineOffset_.localFunction(*entity_));
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) {
429 for (
int l = 0; l < localBlockSize; ++l, ++localDof) {
430 w[localDof] = localOffset[localDof];
435 localDof += localBlockSize;
440 void zeroConstrain(LocalFunctionType& w)
const
442 if (unconstrained()) {
447 for (
int localBlockDof = 0; localBlockDof < numberOfLocalBlocks_; ++localBlockDof) {
448 if (constrainedDofs_[localBlockDof]) {
449 for (
int l = 0; l < localBlockSize; ++l, ++localDof) {
454 localDof += localBlockSize;
460 const EntityType* entity_;
461 const OperatorType& operator_;
462 int numberOfLocalBlocks_;
463 std::vector<unsigned> constrainedDofs_;
464 std::vector<bool> slaveDofs_;
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
Define a factory for a "local object" which has a constructor which accepts a single argument,...
Definition: localobjectstorage.hh:21
Local object stack which (hopefully) efficiently caches local objects.
Definition: localobjectstorage.hh:50
TupleFunctor< Types... > makeTupleFunctor(Types &&... args)
Combine several functors into one.
Definition: functor.hh:142
PairFunctor< FunctorOne, FunctorTwo > makePairFunctor(FunctorOne &&func1, FunctorTwo &&func2)
Combine two functors into one.
Definition: functor.hh:87