3.5-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
intersectionwriter.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
24#ifndef DUMUX_IO_VTK_INTERSECTIONWRITER_HH
25#define DUMUX_IO_VTK_INTERSECTIONWRITER_HH
26
27#include <memory>
28#include <string>
29
30#include <dune/common/typetraits.hh>
31#include <dune/grid/io/file/vtk.hh>
32#include <dune/grid/io/file/vtk/basicwriter.hh>
33#include <dune/grid/io/file/vtk/function.hh>
34#include <dune/grid/io/file/vtk/skeletonfunction.hh>
36
37namespace Dumux::Detail {
38
45template<typename GV>
47: public Dune::ForwardIteratorFacade<GridIntersectionIterator<GV>,
48 const typename GV::Intersection,
49 const typename GV::Intersection&,
50 typename std::iterator_traits<typename GV::template Codim<0>::Iterator>::difference_type>
51{
52public:
54 using Intersection = typename GV::Intersection;
55 using Value = const Intersection;
56 using ElementIterator = typename GV::template Codim<0>::Iterator;
57 using IntersectionIterator = typename GV::IntersectionIterator;
58 using DifferenceType = typename std::iterator_traits<ElementIterator>::difference_type;
59
65 GridIntersectionIterator(const GV& gv, bool end = false)
66 : gridView_(gv), eIt_(end ? gridView_.template end<0>() : gridView_.template begin<0>())
67 {
68 if (eIt_ != gridView_.template end<0>())
69 iIt_ = IntersectionIterator(gridView_.ibegin(*eIt_));
70 }
71
73 {
74 if constexpr (std::is_lvalue_reference_v<decltype(*std::declval<IntersectionIterator>())>)
75 return *iIt_;
76 else
77 {
78 // Some grids only return temporary intersection objects.
79 // If this is the case, story a copy of the intersection here so that
80 // its address can be safely taken later on.
81 intersection_ = *iIt_;
82 return intersection_;
83 }
84 }
85
86 bool equals(const DerivedType& other) const
87 {
88 if (eIt_ != other.eIt_)
89 return false;
90
91 // this is a bit tricky, since we may not compare iIt_ if we are
92 // passed-the-end
93 bool mePassedTheEnd = eIt_ == gridView_.template end<0>();
94 bool otherPassedTheEnd = other.eIt_ == other.gridView_.template end<0>();
95
96 // both passed-the-end => consider them equal
97 if(mePassedTheEnd && otherPassedTheEnd)
98 return true;
99
100 // one passed the end => not equal
101 if(mePassedTheEnd || otherPassedTheEnd)
102 return false;
103
104 // none passed-the-end => do their iIt_ iterators match?
105 return iIt_ == other.iIt_;
106 }
107
109 {
110 ++iIt_;
111 if (iIt_ == gridView_.iend(*eIt_))
112 {
113 iIt_ = IntersectionIterator();
114 ++eIt_;
115 if (eIt_ != gridView_.template end<0>())
116 iIt_ = IntersectionIterator(gridView_.ibegin(*eIt_));
117 }
118 }
119
120private:
121 const GV gridView_;
122 ElementIterator eIt_;
124 mutable Intersection intersection_;
125};
126
131template<class GridView>
133{
134public:
135 static constexpr auto dimCell = GridView::dimension-1;
136 using Cell = typename GridView::Intersection;
138 using Corner = Dune::VTK::Corner<Cell>;
139 using CornerIterator = Dune::VTK::CornerIterator<CellIterator>;
140 using Point = Corner;
142 using ConnectivityWriter = Dune::VTK::NonConformingConnectivityWriter<Cell>;
143 using Communication = typename GridView::CollectiveCommunication;
144
145 explicit NonConformingIntersectionIteratorFactory(const GridView& gv)
146 : gridView_(gv) {}
147
149 { return CellIterator(gridView_); }
150
152 { return CellIterator(gridView_, true); }
153
155 { return CornerIterator(beginCells(), endCells()); }
156
158 { return CornerIterator(endCells()); }
159
161 { return beginCorners(); }
162
164 { return endCorners(); }
165
167 { return ConnectivityWriter(); }
168
169 const Communication& comm() const
170 { return gridView_.comm(); }
171
172private:
173 GridView gridView_;
174};
175
180template<class GridView, class Mapper, class F>
182{
183 using Intersection = typename GridView::Intersection;
184public:
185 using Traits = Dune::VTK::SkeletonFunctionTraits<GridView, typename GridView::ctype>;
186
187 SkeletonFunction(const GridView& gv, const Mapper& mapper, const F& field)
188 : gv_(gv)
189 , mapper_(mapper)
190 , field_(field)
191 , components_(1)
192 {
193 if constexpr (std::is_invocable_v<F, Intersection, int>)
194 {
195 if constexpr (Dune::IsIndexable<std::decay_t<decltype(field(std::declval<Intersection>(), 0))>>{})
196 {
197 if constexpr (Dune::IsIndexable<std::decay_t<decltype(field(std::declval<Intersection>(), 0)[0])>>{})
198 DUNE_THROW(Dune::InvalidStateException, "Invalid field type");
199 else
200 {
201 const auto& is = *(intersections(gv, *(elements(gv).begin())).begin());
202 components_ = field(is, mapper_(is, gv_)).size();
203 }
204 }
205 }
206 else if constexpr (Dune::IsIndexable<std::decay_t<decltype(field[0])>>{})
207 {
208 assert(field.size() == gv.size(1));
209 if constexpr (Dune::IsIndexable<std::decay_t<decltype(field[0][0])>>{})
210 DUNE_THROW(Dune::InvalidStateException, "Invalid field type");
211 else
212 components_ = field[0].size();
213 }
214 }
215
217 unsigned dimRange() const { return components_; }
218
219 void evaluate(const typename Traits::Cell& intersection,
220 const typename Traits::Domain& xl,
221 typename Traits::Range& result) const
222 {
223 assert(intersection.conforming());
224 result.resize(components_);
225 const auto idx = mapper_(intersection, gv_);
226
227 auto accessEntry = [&](auto i)
228 {
229 if constexpr (std::is_invocable_v<F, Intersection, int>)
230 {
231 if constexpr (Dune::IsIndexable<std::decay_t<decltype(field_(intersection, idx))>>{})
232 return field_(intersection, idx)[i];
233 else
234 return field_(intersection, idx);
235 }
236 else
237 {
238 if constexpr (Dune::IsIndexable<std::decay_t<decltype(std::declval<F>()[0])>>{})
239 return field_[idx][i];
240 else
241 return field_[idx];
242 }
243 };
244
245 for (int i = 0; i < components_; ++i)
246 result[i] = accessEntry(i);
247 }
248
249private:
250 GridView gv_;
251 const Mapper& mapper_;
252
253 // If F is callable we store a copy of it, otherwise we assume that F is a container
254 // stored somewhere else, thus we only keep a reference here
255 std::conditional_t<std::is_invocable_v<F,Intersection, int>, const F, const F&> field_;
256
257 std::size_t components_;
258};
259
260} // end namespace Dumux::Detail
261
262namespace Dumux {
267template<class GridView>
270, public Dune::VTK::BasicWriter<Detail::NonConformingIntersectionIteratorFactory<GridView>>
271{
273 using Base = Dune::VTK::BasicWriter<Factory>;
274
275public:
276 ConformingIntersectionWriter(const GridView& gridView, const std::string& paramGroup = "")
277 : Factory(gridView), Base(static_cast<const Factory&>(*this)), gridView_(gridView)
278 {
279 static bool addProcessRank = getParamFromGroup<bool>(paramGroup, "Vtk.AddProcessRank");
280 if (addProcessRank)
281 {
282 auto getRank = [rank = gridView_.comm().rank()](const auto& is, const auto idx)
283 { return rank; };
284
285 auto mapper = getStandardMapper();
286 using SF = Detail::SkeletonFunction<GridView, decltype(mapper), decltype(getRank)>;
287 auto fun = std::make_shared<SF>(gridView_, mapper, getRank);
288 addCellData(fun, "processRank");
289 }
290 }
291
292 using Base::addCellData;
293
294 static auto getStandardMapper()
295 {
296 return [](const auto& is, const GridView& gridView){ return gridView.indexSet().subIndex(is.inside(), is.indexInInside(), 1); };
297 }
298
299 template<class F, class Mapper = decltype(getStandardMapper())>
300 auto makeSkeletonFunction(const F& f, const Mapper& mapper = getStandardMapper()) const
301 {
302 return std::make_shared<Detail::SkeletonFunction<GridView, decltype(mapper), decltype(f)>>(gridView_, mapper, f);
303 }
304
305 template<class Func>
306 void addCellData(const std::shared_ptr<Func>& p, const std::string& name)
307 {
308 addCellData(std::shared_ptr<typename Base::FunctionWriter>
309 (new Dune::VTK::SkeletonFunctionWriter<Func>(p, name)));
310 }
311
312 template<class Func>
313 void addCellData(Func* p, const std::string& name)
314 {
315 addCellData(std::shared_ptr<Func>(p), name);
316 }
317
318 template<class F>
319 void addField(const F& field, const std::string& name)
320 {
321 auto mapper = getStandardMapper();
322 addCellData(makeSkeletonFunction(field, mapper), name);
323 }
324
325 using Base::addPointData;
326
327 template<class Func>
328 void addPointData(const std::shared_ptr<Func>& p, const std::string& name)
329 {
330 addPointData(std::shared_ptr<typename Base::FunctionWriter>
331 (new Dune::VTK::SkeletonFunctionWriter<Func>(p, name)));
332 }
333
334 template<class Func>
335 void addPointData(Func* p, const std::string& name)
336 {
337 addPointData(std::shared_ptr<Func>(p), name);
338 }
339
340 std::string write(const std::string& name, Dune::VTK::OutputType outputType = Dune::VTK::OutputType::ascii)
341 {
342 return Base::write(name, outputType);
343 }
344
345private:
346 GridView gridView_;
347};
348
349} // end namespace Dumux
350
351#endif
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Definition: adapt.hh:29
Distance implementation details.
Definition: fclocalassembler.hh:42
double accessEntry(const Field &f, int mycomp, int i)
Definition: function.hh:43
Iterate over the GridViews boundary intersections This will visit all intersections for which boundar...
Definition: intersectionwriter.hh:51
typename GV::Intersection Intersection
Definition: intersectionwriter.hh:54
typename std::iterator_traits< ElementIterator >::difference_type DifferenceType
Definition: intersectionwriter.hh:58
const Intersection & dereference() const
Definition: intersectionwriter.hh:72
typename GV::IntersectionIterator IntersectionIterator
Definition: intersectionwriter.hh:57
GridIntersectionIterator(const GV &gv, bool end=false)
Construct a GridIntersectionIterator If end == true, construct an end iterator for the given gridview...
Definition: intersectionwriter.hh:65
void increment()
Definition: intersectionwriter.hh:108
typename GV::template Codim< 0 >::Iterator ElementIterator
Definition: intersectionwriter.hh:56
const Intersection Value
Definition: intersectionwriter.hh:55
bool equals(const DerivedType &other) const
Definition: intersectionwriter.hh:86
Non conforming intersection iterator factory.
Definition: intersectionwriter.hh:133
PointIterator beginPoints() const
Definition: intersectionwriter.hh:160
CornerIterator PointIterator
Definition: intersectionwriter.hh:141
Corner Point
Definition: intersectionwriter.hh:140
PointIterator endPoints() const
Definition: intersectionwriter.hh:163
static constexpr auto dimCell
Definition: intersectionwriter.hh:135
GridIntersectionIterator< GridView > CellIterator
Definition: intersectionwriter.hh:137
Dune::VTK::Corner< Cell > Corner
Definition: intersectionwriter.hh:138
Dune::VTK::NonConformingConnectivityWriter< Cell > ConnectivityWriter
Definition: intersectionwriter.hh:142
typename GridView::CollectiveCommunication Communication
Definition: intersectionwriter.hh:143
NonConformingIntersectionIteratorFactory(const GridView &gv)
Definition: intersectionwriter.hh:145
CornerIterator endCorners() const
Definition: intersectionwriter.hh:157
CornerIterator beginCorners() const
Definition: intersectionwriter.hh:154
typename GridView::Intersection Cell
Definition: intersectionwriter.hh:136
CellIterator beginCells() const
Definition: intersectionwriter.hh:148
ConnectivityWriter makeConnectivity() const
Definition: intersectionwriter.hh:166
CellIterator endCells() const
Definition: intersectionwriter.hh:151
Dune::VTK::CornerIterator< CellIterator > CornerIterator
Definition: intersectionwriter.hh:139
const Communication & comm() const
Definition: intersectionwriter.hh:169
Skeleton function for intersection writer.
Definition: intersectionwriter.hh:182
Dune::VTK::SkeletonFunctionTraits< GridView, typename GridView::ctype > Traits
Definition: intersectionwriter.hh:185
SkeletonFunction(const GridView &gv, const Mapper &mapper, const F &field)
Definition: intersectionwriter.hh:187
unsigned dimRange() const
return number of components
Definition: intersectionwriter.hh:217
void evaluate(const typename Traits::Cell &intersection, const typename Traits::Domain &xl, typename Traits::Range &result) const
Definition: intersectionwriter.hh:219
Conforming intersection writer.
Definition: intersectionwriter.hh:271
void addCellData(const std::shared_ptr< Func > &p, const std::string &name)
Definition: intersectionwriter.hh:306
void addPointData(const std::shared_ptr< Func > &p, const std::string &name)
Definition: intersectionwriter.hh:328
ConformingIntersectionWriter(const GridView &gridView, const std::string &paramGroup="")
Definition: intersectionwriter.hh:276
static auto getStandardMapper()
Definition: intersectionwriter.hh:294
void addCellData(Func *p, const std::string &name)
Definition: intersectionwriter.hh:313
auto makeSkeletonFunction(const F &f, const Mapper &mapper=getStandardMapper()) const
Definition: intersectionwriter.hh:300
void addField(const F &field, const std::string &name)
Definition: intersectionwriter.hh:319
void addPointData(Func *p, const std::string &name)
Definition: intersectionwriter.hh:335
std::string write(const std::string &name, Dune::VTK::OutputType outputType=Dune::VTK::OutputType::ascii)
Definition: intersectionwriter.hh:340