50preAdapt(B
const& basis, C
const& coeff,
bool mightCoarsen)
52 GridView gv = basis.gridView();
53 LocalView lv = basis.localView();
54 auto const& grid = gv.grid();
55 auto const& idSet = grid.localIdSet();
57 nodeDataTransfer_.resize(lv.tree());
58 Traversal::forEachLeafNode(lv.tree(), [&](
auto const& node,
auto const& tp) {
59 nodeDataTransfer_[tp].preAdaptInit(lv, coeff, node);
63 persistentContainer_.clear();
64 for (
const auto& e : elements(gv))
66 auto it = persistentContainer_.emplace(idSet.id(e),
67 Dune::TypeTree::makeTreeContainer(lv.tree(), [](
auto&& node) { return NodeElementData<TYPEOF(node)>{}; }));
70 auto& treeContainer = it.first->second;
71 Traversal::forEachLeafNode(lv.tree(), [&](
auto const& ,
auto const& tp) {
72 nodeDataTransfer_[tp].cacheLocal(treeContainer[tp]);
80 auto maxLevel = grid.maxLevel();
82 typename Grid::ctype
const checkInsideTolerance = sqrt(std::numeric_limits<typename Grid::ctype>::epsilon());
83 using Seed =
typename Grid::template Codim<0>::EntitySeed;
84 std::vector<Seed> seeds(maxLevel+1);
86 for (
auto const& e : entitySet(basis))
89 while (father.mightVanish() && father.hasFather())
91 father = father.father();
92 auto it = persistentContainer_.emplace(idSet.id(father),
93 Dune::TypeTree::makeTreeContainer(lv.tree(), [](
auto&& node) { return NodeElementData<TYPEOF(node)>{}; }));
97 auto& treeContainer = it.first->second;
99 bool restrictLocalCompleted =
false;
100 auto hItEnd = father.hend(maxLevel);
101 for (
auto hIt = father.hbegin(maxLevel); hIt != hItEnd; ++hIt)
103 seeds[hIt->level()] = hIt->seed();
108 auto const& child = *hIt;
109 auto search = persistentContainer_.find(idSet.id(child));
110 assert(search != persistentContainer_.end());
111 auto const& childContainer = search->second;
114 using BoolCoordPair = std::pair<bool, LocalCoordinate>;
115 using CacheImp = std::unordered_map<LocalCoordinate, BoolCoordPair, Impl::CoordHasher>;
116 using ChildCache = ConcurrentCache<LocalCoordinate, BoolCoordPair, ConsecutivePolicy, CacheImp>;
120 auto xInChild = [&](LocalCoordinate
const& x) -> BoolCoordPair {
121 LocalCoordinate y = x;
122 for (
int i = father.level()+1; i <= child.level(); ++i)
124 auto currentElement = grid.entity(seeds[i]);
125 auto const& geoInFather = currentElement.geometryInFather();
126 y = geoInFather.local(y);
129 bool isInside = Dune::Geo::Impl::checkInside(Dune::referenceElement(geoInFather).type().
id(), Geometry::mydimension, y, checkInsideTolerance);
131 return BoolCoordPair(
false, std::move(y));
133 return BoolCoordPair(
true, std::move(y));
137 ChildCache childCache;
138 auto xInChildCached = [&](LocalCoordinate
const& x) -> BoolCoordPair {
139 return childCache.get(x, [&](LocalCoordinate
const& x) {
return xInChild(x); });
142 restrictLocalCompleted =
true;
143 Traversal::forEachLeafNode(lv.tree(), [&](
auto const& ,
auto const& tp) {
144 restrictLocalCompleted &=
145 nodeDataTransfer_[tp].restrictLocal(father, treeContainer[tp], xInChildCached,
146 childContainer[tp], init);
151 assert(restrictLocalCompleted);
165 if (persistentContainer_.empty())
168 GridView gv = basis.gridView();
169 LocalView lv = basis.localView();
170 auto const& idSet = gv.grid().localIdSet();
171 Traversal::forEachLeafNode(lv.tree(), [&](
auto const& node,
auto const& tp) {
172 nodeDataTransfer_[tp].adaptInit(lv, coeff, node);
175 using Mapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
176 Mapper mapper{gv, Dune::mcmgElementLayout()};
178 std::vector<bool> finished(mapper.size(),
false);
179 for (
const auto& e : entitySet(basis))
181 auto index = mapper.index(e);
185 auto it = persistentContainer_.find(idSet.id(e));
188 if (it != persistentContainer_.end()) {
190 auto const& treeContainer = it->second;
191 Traversal::forEachLeafNode(lv.tree(), [&](
auto const& ,
auto const& tp) {
192 nodeDataTransfer_[tp].copyLocal(treeContainer[tp]);
194 finished[index] =
true;
200 while (father.hasFather() && father.isNew())
201 father = father.father();
203 auto maxLevel = gv.grid().maxLevel();
206 auto father_it = persistentContainer_.find(idSet.id(father));
207 assert(father_it != persistentContainer_.end());
208 auto const& treeContainer = father_it->second;
210 auto hItEnd = father.hend(maxLevel);
211 for (
auto hIt = father.hbegin(maxLevel); hIt != hItEnd; ++hIt) {
215 auto const& child = *hIt;
219 auto xInFather = [&](LocalCoordinate
const& x) -> LocalCoordinate
222 auto currentElement = child;
223 while (currentElement.level() != father.level())
225 y = currentElement.geometryInFather().global(y);
226 currentElement = currentElement.father();
231 Traversal::forEachLeafNode(lv.tree(), [&](
auto const& ,
auto const& tp) {
232 nodeDataTransfer_[tp].prolongLocal(father, treeContainer[tp], xInFather, init);
235 finished[mapper.index(child)] =
true;
257 using T =
typename Container::value_type;
258 using LocalView =
typename Basis::LocalView;
259 using Element =
typename Node::Element;
261 using LocalBasis =
typename Node::FiniteElement::Traits::LocalBasisType;
262 using LBRangeType =
typename LocalBasis::Traits::RangeType;
263 using LocalInterpolation =
typename Node::FiniteElement::Traits::LocalBasisType;
264 using LIDomainType =
typename LocalInterpolation::Traits::DomainType;
265 using LIRangeType =
typename LocalInterpolation::Traits::RangeType;
268 using NodeElementData = std::vector<T>;
274 void preAdaptInit(LocalView
const& lv, Container
const& coeff, Node
const& node)
278 fatherNode_ = std::make_shared<Node>(node);
279 constCoeff_ = &coeff;
290 constCoeff_->gather(*lv_, *node_, dofs);
308 template <
class Trafo>
309 bool restrictLocal(Element
const& father, NodeElementData& fatherDOFs, Trafo
const& trafo,
310 NodeElementData
const& childDOFs,
bool init);
314 void adaptInit(LocalView
const& lv, Container& coeff, Node
const& node)
318 fatherNode_ = std::make_shared<Node>(node);
341 template <
class Trafo>
342 void prolongLocal(Element
const& father, NodeElementData
const& fatherDOFs,
343 Trafo
const& trafo,
bool init);
347 Node
const* node_ =
nullptr;
348 std::shared_ptr<Node> fatherNode_;
349 Container
const* constCoeff_ =
nullptr;
350 Container* coeff_ =
nullptr;
351 std::vector<bool> finishedDOFs_;
352 NodeElementData fatherDOFsTemp_;
359restrictLocal(Element
const& father, NodeElementData& fatherDOFs, Trafo
const& trafo,
360 NodeElementData
const& childDOFs,
bool init)
362 auto& fatherNode = *fatherNode_;
363 std::size_t currentDOF = 0;
367 bindTree(fatherNode, father);
369 auto const& childNode = *node_;
370 auto const& childFE = childNode.finiteElement();
371 auto const& fatherFE = fatherNode.finiteElement();
374 finishedDOFs_.assign(fatherFE.size(),
false);
375 fatherDOFsTemp_.assign(fatherFE.size(), 0);
378 auto evalLeaf = [&](LIDomainType
const& x) -> LIRangeType {
379 if (!finishedDOFs_[currentDOF])
381 auto const& insideLocal = trafo(x);
382 bool isInside = insideLocal.first;
385 auto const& local = insideLocal.second;
386 thread_local std::vector<LBRangeType> shapeValues;
387 childFE.localBasis().evaluateFunction(local, shapeValues);
389 assert(childDOFs.size() == shapeValues.size());
392 for (std::size_t i = 0; i < shapeValues.size(); ++i)
393 y += shapeValues[i] * childDOFs[i];
395 fatherDOFsTemp_[currentDOF] = T(y);
396 finishedDOFs_[currentDOF++] =
true;
400 return fatherDOFsTemp_[currentDOF++];
403 fatherFE.localInterpolation().interpolate(evalLeaf, fatherDOFs);
406 return std::accumulate(finishedDOFs_.begin(), finishedDOFs_.end(),
true,
407 std::logical_and<bool>());
414prolongLocal(Element
const& father, NodeElementData
const& fatherDOFs,
415 Trafo
const& trafo,
bool init)
417 auto& fatherNode = *fatherNode_;
421 bindTree(fatherNode, father);
423 auto const& childNode = *node_;
426 auto evalFather = [&](LIDomainType
const& x) -> LIRangeType
428 thread_local std::vector<LBRangeType> shapeValues;
429 fatherNode.finiteElement().localBasis().evaluateFunction(trafo(x), shapeValues);
430 assert(shapeValues.size() == fatherDOFs.size());
433 for (std::size_t i = 0; i < shapeValues.size(); ++i)
434 y += shapeValues[i] * fatherDOFs[i];
439 auto const& childFE = childNode.finiteElement();
440 thread_local std::vector<T> childDOFs;
441 childFE.localInterpolation().interpolate(evalFather, childDOFs);