1#ifndef _DUNE_ACFEM_BULK_BLOCKCONSTRAINTS_HH_
2#define _DUNE_ACFEM_BULK_BLOCKCONSTRAINTS_HH_
4#include "../../common/functor.hh"
5#include "../../common/dofmappertupledatahandle.hh"
6#include <dune/fem/operator/common/differentiableoperator.hh>
7#include <dune/fem/function/blockvectorfunction/blockvectorfunction.hh>
33 template<
class DiscreteFunctionSpace,
34 template<
class T,
class Alloc = std::allocator<T> >
class MaskStorage = std::vector>
39 typedef DiscreteFunctionSpace DiscreteFunctionSpaceType;
42 typedef Fem::ISTLBlockVectorDiscreteFunction<DiscreteFunctionSpaceType> ConstraintsStorageType;
43 enum { localBlockSize = DiscreteFunctionSpaceType::localBlockSize };
44 typedef typename DiscreteFunctionSpaceType::GridPartType GridPartType;
45 typedef typename DiscreteFunctionSpaceType::EntityType EntityType;
46 typedef std::bitset<localBlockSize> MaskType;
47 typedef MaskStorage<MaskType> MaskStorageType;
49 typedef typename DiscreteFunctionSpaceType::BlockMapperType BlockMapperType;
50 typedef typename BlockMapperType::GlobalKeyType GlobalKeyType;
57 values_(
"Constraint Values", space_),
58 mask_(space_.blockMapper().
size(), 0),
73 if (!force && sequence_ == space_.sequence()) {
77 mask_.resize(space_.blockMapper().size(), 0);
80 std::count_if(mask_.begin(), mask_.end(),
81 [](
const MaskType& value) { return value.count(); });
85 sequence_ = space_.sequence();
108 template<
class DomainDiscreteFunction,
class RangeDiscreteFunction>
109 void operator()(
const DomainDiscreteFunction& u, RangeDiscreteFunction& w)
const
117 auto uIt = u.dbegin();
118 auto wIt = w.dbegin();
119 auto offsetIt = values_.dbegin();
120 for (
const auto& mask : mask_) {
121 for (
int l = 0; l < localBlockSize; ++l, ++wIt, ++offsetIt, ++uIt) {
123 *wIt = *uIt - *offsetIt;
135 template<
class DomainDiscreteFunction,
class JacobianOperator>
136 void jacobian(
const DomainDiscreteFunction& u, JacobianOperator& jOp)
const
144 std::vector<size_t> rows;
145 rows.reserve(
size());
147 for (
const auto& mask : mask_) {
148 for (
int l = 0; l < localBlockSize; ++l) {
155 jOp.setUnitRows(rows);
159 template<
class DomainDiscreteFunction,
class JacobianOperator>
176 template<
class DomainDiscreteFunction>
186 auto wIt = w.dbegin();
187 auto offsetIt = values_.dbegin();
188 for (
const auto& mask : mask_) {
189 for (
int l = 0; l < localBlockSize; ++l, ++wIt, ++offsetIt) {
198 template<
class DomainDiscreteFunction>
207 auto wIt = w.dbegin();
208 for (
const auto& mask : mask_) {
209 for (
int l = 0; l < localBlockSize; ++l, ++wIt) {
219 return numConstrained_;
236 if (space_.sequence() != sequence_) {
246 if (space_.gridPart().comm().size() <= 1) {
252 typename ConstraintsStorageType::DofVectorType>
254 typedef typename CommTraitsType::DataItemType DataItemType;
255 typedef typename CommTraitsType::DataItemScatterType DataItemScatterType;
257 auto dataHandle = dofMapperTupleDataHandle(
259 [](
const DataItemType& a,
const DataItemScatterType& b) {
260 for (
int l = 0; l < localBlockSize; ++l) {
265 assert(std::get<0>(b)[l] && std::get<0>(a)[l] &&
266 std::abs(std::get<1>(b)[l] - std::get<1>(a)[l]) < 1e-8);
267 if (std::get<0>(a)[l]) {
268 std::get<1>(b)[l] = std::get<1>(a)[l];
271 std::get<0>(b) |= std::get<0>(a);
274 values_.dofVector());
276 space_.gridPart().communicate(dataHandle,
277 DiscreteFunctionSpaceType::GridPartType::indexSetInterfaceType,
278 Dune::ForwardCommunication);
282 const DiscreteFunctionSpaceType& space_;
283 mutable ConstraintsStorageType values_;
284 mutable MaskStorageType mask_;
285 mutable unsigned numConstrained_;
286 mutable int sequence_;
A default implementation for bulk block constraints.
Definition: bulkblockconstraints.hh:36
void zeroConstrain(DomainDiscreteFunction &w) const
Unconditionally set the values of all masked DoFs to zero.
Definition: bulkblockconstraints.hh:199
void constrain(DomainDiscreteFunction &w) const
The solution operator; unconditionally install the given constraints into the argument.
Definition: bulkblockconstraints.hh:177
BulkBlockConstraints(const DiscreteFunctionSpaceType &space)
Construct an empty operator.
Definition: bulkblockconstraints.hh:55
virtual void communicate() const
Communicate the mask-values and the Dirichlet values as needed.
Definition: bulkblockconstraints.hh:244
void jacobian(const DomainDiscreteFunction &u, JacobianOperator &jOp) const
The Jacobian of the operator.
Definition: bulkblockconstraints.hh:136
void reset() const
Delete the cached "sequence" of the underlying discrete space.
Definition: bulkblockconstraints.hh:226
void checkUpdate() const
Update mask and values if the underlying space has changed.
Definition: bulkblockconstraints.hh:234
size_t size() const
Return the number of constrained scalar DoFs.
Definition: bulkblockconstraints.hh:218
void operator()(const DomainDiscreteFunction &u, RangeDiscreteFunction &w) const
Apply the operator to the given argument.
Definition: bulkblockconstraints.hh:109
virtual void update() const =0
Update the set of constrained DoFs and their prescirbed DoF-values.
virtual void updateValues() const
Only update the prescribed values.
Definition: bulkblockconstraints.hh:94
void applyToOperator(const DomainDiscreteFunction &u, JacobianOperator &jOp) const
Dune::Fem compat.
Definition: bulkblockconstraints.hh:160
Traits for just something indexable.
Definition: dofmappertupledatahandle.hh:15