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
9namespace 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
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.111.3 (Jul 15, 22:36, 2024)