DUNE-ACFEM (unstable)

bulkblockconstraints.hh
1 #ifndef _DUNE_ACFEM_BULK_BLOCKCONSTRAINTS_HH_
2 #define _DUNE_ACFEM_BULK_BLOCKCONSTRAINTS_HH_
3 
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>
8 
9 namespace Dune {
10 
11  namespace ACFem {
12 
33  template<class DiscreteFunctionSpace,
34  template<class T, class Alloc = std::allocator<T> > class MaskStorage = std::vector>
36  {
38  public:
39  typedef DiscreteFunctionSpace DiscreteFunctionSpaceType;
40  // AdaptiveDiscreteFunction does not work with our tuple data-handle.
41  //typedef Fem::AdaptiveDiscreteFunction<DiscreteFunctionSpaceType> ConstraintsStorageType;
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;
48  protected:
49  typedef typename DiscreteFunctionSpaceType::BlockMapperType BlockMapperType;
50  typedef typename BlockMapperType::GlobalKeyType GlobalKeyType;
51 
52  public:
53 
55  BulkBlockConstraints(const DiscreteFunctionSpaceType& space)
56  : space_(space),
57  values_("Constraint Values", space_),
58  mask_(space_.blockMapper().size(), 0),
59  numConstrained_(0),
60  sequence_(-1)
61  {}
62 
63  virtual ~BulkBlockConstraints()
64  {}
65 
70  virtual void update() const = 0;
71 #if 0
72  {
73  if (!force && sequence_ == space_.sequence()) {
74  return;
75  }
76 
77  mask_.resize(space_.blockMapper().size(), 0);
78 
79  numConstrained_ =
80  std::count_if(mask_.begin(), mask_.end(),
81  [](const MaskType& value) { return value.count(); });
82 
83  communicate();
84 
85  sequence_ = space_.sequence();
86  }
87 #endif
88 
94  virtual void updateValues() const {
95  reset();
96  update();
97  }
98 
108  template<class DomainDiscreteFunction, class RangeDiscreteFunction>
109  void operator()(const DomainDiscreteFunction& u, RangeDiscreteFunction& w) const
110  {
111  checkUpdate();
112 
113  if (size() == 0) {
114  return;
115  }
116 
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) {
122  if (mask[l]) {
123  *wIt = *uIt - *offsetIt;
124  }
125  }
126  }
127  }
128 
135  template<class DomainDiscreteFunction, class JacobianOperator>
136  void jacobian(const DomainDiscreteFunction& u, JacobianOperator& jOp) const
137  {
138  checkUpdate();
139 
140  if (size() == 0) {
141  return;
142  }
143 
144  std::vector<size_t> rows;
145  rows.reserve(size());
146  size_t r = 0;
147  for (const auto& mask : mask_) {
148  for (int l = 0; l < localBlockSize; ++l) {
149  if (mask[l]) {
150  rows.push_back(r);
151  }
152  ++r;
153  }
154  }
155  jOp.setUnitRows(rows);
156  }
157 
159  template<class DomainDiscreteFunction, class JacobianOperator>
160  void applyToOperator(const DomainDiscreteFunction& u, JacobianOperator& jOp) const
161  {
162  jacobian(u, jOp);
163  }
164 
176  template<class DomainDiscreteFunction>
177  void constrain(DomainDiscreteFunction& w) const
178  {
179  checkUpdate();
180 
181  if (size() == 0) {
182  // nothing to do.
183  return;
184  }
185 
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) {
190  if (mask[l]) {
191  *wIt = *offsetIt;
192  }
193  }
194  }
195  }
196 
198  template<class DomainDiscreteFunction>
199  void zeroConstrain(DomainDiscreteFunction& w) const
200  {
201  checkUpdate();
202 
203  if (size() == 0) {
204  return;
205  }
206 
207  auto wIt = w.dbegin();
208  for (const auto& mask : mask_) {
209  for (int l = 0; l < localBlockSize; ++l, ++wIt) {
210  if (mask[l]) {
211  *wIt = 0;
212  }
213  }
214  }
215  }
216 
218  size_t size() const {
219  return numConstrained_;
220  }
221 
226  void reset() const {
227  sequence_ = -1;
228  }
229 
230  protected:
234  void checkUpdate() const
235  {
236  if (space_.sequence() != sequence_) {
237  update();
238  }
239  }
240 
244  virtual void communicate() const
245  {
246  if (space_.gridPart().comm().size() <= 1) {
247  return; // serial run
248  }
249 
250  typedef
251  DofMapperTupleDataHandleTraits<MaskStorageType,
252  typename ConstraintsStorageType::DofVectorType>
253  CommTraitsType;
254  typedef typename CommTraitsType::DataItemType DataItemType;
255  typedef typename CommTraitsType::DataItemScatterType DataItemScatterType;
256 
257  auto dataHandle = dofMapperTupleDataHandle(
258  space_,
259  [](const DataItemType& a, const DataItemScatterType& b) {
260  for (int l = 0; l < localBlockSize; ++l) {
261  // copy over data from a if it is constraint. Otherwise
262  // keep our data. If both bits are set check for
263  // consistency, otherwise we end up with
264  // "constraint-ping-pong" with inconsistent values.
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];
269  }
270  }
271  std::get<0>(b) |= std::get<0>(a);
272  },
273  mask_,
274  values_.dofVector());
275 
276  space_.gridPart().communicate(dataHandle,
277  DiscreteFunctionSpaceType::GridPartType::indexSetInterfaceType,
278  Dune::ForwardCommunication);
279  }
280 
281  protected:
282  const DiscreteFunctionSpaceType& space_;
283  mutable ConstraintsStorageType values_;
284  mutable MaskStorageType mask_;
285  mutable unsigned numConstrained_;
286  mutable int sequence_;
287  };
288 
290 
292 
293  } // ACFem::
294 
295 } // Dune::
296 
297 
298 #endif // _DUNE_ACFEM_EMPTY_BLOCKCONSTRAINTS_HH_
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
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 6, 22:30, 2024)