1#ifndef DUNE_PDELAB_GRIDFUNCTIONSPACE_VTK_HH
2#define DUNE_PDELAB_GRIDFUNCTIONSPACE_VTK_HH
12#include <dune/localfunctions/common/interfaceswitch.hh>
14#include <dune/typetree/visitor.hh>
15#include <dune/typetree/traversal.hh>
17#include <dune/pdelab/common/function.hh>
18#include <dune/pdelab/common/vtkexport.hh>
19#include <dune/pdelab/common/vtkexport.hh>
20#include <dune/pdelab/gridfunctionspace/localfunctionspace.hh>
21#include <dune/pdelab/gridfunctionspace/lfsindexcache.hh>
30 class SubsamplingVTKWriter;
33 class VTKSequenceWriter;
41 template<
typename VTKWriter>
42 struct vtk_writer_traits;
45 struct vtk_writer_traits<
Dune::VTKWriter<GV> >
51 struct vtk_writer_traits<
Dune::SubsamplingVTKWriter<GV> >
57 struct vtk_writer_traits<
Dune::VTKSequenceWriter<GV> >
64 template<
typename LFS,
typename Data>
65 class DGFTreeLeafFunction;
67 template<
typename LFS,
typename Data>
68 class DGFTreeVectorFunction;
70 template<
typename VTKWriter,
typename Data>
71 struct OutputCollector;
75 template<
typename GFS,
typename X,
typename Pred>
79 template<
typename LFS,
typename Data>
80 friend class DGFTreeLeafFunction;
82 template<
typename LFS,
typename Data>
83 friend class DGFTreeVectorFunction;
85 template<
typename,
typename>
86 friend struct OutputCollector;
89 typedef LFSIndexCache<LFS> LFSCache;
90 typedef typename X::template ConstLocalView<LFSCache> XView;
92 using EntitySet =
typename GFS::Traits::EntitySet;
93 using Cell =
typename EntitySet::Traits::Element;
94 using IndexSet =
typename EntitySet::Traits::IndexSet;
97 static const auto dim = EntitySet::dimension;
101 typedef GFS GridFunctionSpace;
103 typedef Pred Predicate;
109 , _x_local(_lfs.maxSize())
110 , _index_set(gfs->entitySet().indexSet())
117 void bind(
const Cell& cell)
119 auto cell_index = _index_set.uniqueIndex(cell);
120 if (_current_cell_index == cell_index)
125 _x_view.bind(_lfs_cache);
126 _x_view.read(_x_local);
128 _current_cell_index = cell_index;
135 const IndexSet& _index_set;
136 size_type _current_cell_index;
140 std::shared_ptr<const X> x;
145 template<
typename LFS,
typename Data>
146 class DGFTreeLeafFunction
148 typename LFS::Traits::GridView,
149 typename BasisInterfaceSwitch<
150 typename FiniteElementInterfaceSwitch<
151 typename LFS::Traits::FiniteElement
154 BasisInterfaceSwitch<
155 typename FiniteElementInterfaceSwitch<
156 typename LFS::Traits::FiniteElement
159 typename BasisInterfaceSwitch<
160 typename FiniteElementInterfaceSwitch<
161 typename LFS::Traits::FiniteElement
165 DGFTreeLeafFunction<LFS,Data>
171 typename LFS::Traits::FiniteElement
177 typename LFS::Traits::GridView,
182 DGFTreeLeafFunction<LFS,Data>
188 DGFTreeLeafFunction (
const LFS& lfs,
const std::shared_ptr<Data>& data)
189 : BaseT(lfs.gridFunctionSpace().dataSetType())
192 , _basis(lfs.maxSize())
196 void evaluate (
const typename Traits::ElementType& e,
197 const typename Traits::DomainType& x,
198 typename Traits::RangeType& y)
const
203 typename LFS::Traits::FiniteElement
208 FESwitch::basis(_lfs.finiteElement()).evaluateFunction(x,_basis);
209 for (std::size_t i = 0; i < _lfs.size(); ++i)
210 y.axpy(_data->_x_local(_lfs,i),_basis[i]);
214 const typename Traits::GridViewType& gridView()
const
216 return _lfs.gridFunctionSpace().gridView();
219 const LFS& localFunctionSpace()
const
227 const std::shared_ptr<Data> _data;
228 mutable std::vector<typename Traits::RangeType> _basis;
234 template<
typename LFS,
typename Data>
235 class DGFTreeVectorFunction
236 :
public GridFunctionBase<GridFunctionTraits<
237 typename LFS::Traits::GridView,
238 typename BasisInterfaceSwitch<
239 typename FiniteElementInterfaceSwitch<
240 typename LFS::ChildType::Traits::FiniteElement
243 TypeTree::StaticDegree<LFS>::value,
245 typename BasisInterfaceSwitch<
246 typename FiniteElementInterfaceSwitch<
247 typename LFS::ChildType::Traits::FiniteElement
250 TypeTree::StaticDegree<LFS>::value
253 DGFTreeVectorFunction<LFS,Data>
257 typedef BasisInterfaceSwitch<
258 typename FiniteElementInterfaceSwitch<
259 typename LFS::ChildType::Traits::FiniteElement
264 "Automatic conversion to vector-valued function only supported for scalar components");
266 typedef GridFunctionBase<
268 typename LFS::Traits::GridView,
270 TypeTree::StaticDegree<LFS>::value,
273 TypeTree::StaticDegree<LFS>::value
276 DGFTreeVectorFunction<LFS,Data>
282 typedef typename LFS::ChildType ChildLFS;
283 typedef typename ChildLFS::Traits::FiniteElement::Traits::LocalBasisType::Traits::RangeFieldType RF;
284 typedef typename ChildLFS::Traits::FiniteElement::Traits::LocalBasisType::Traits::RangeType RT;
286 DGFTreeVectorFunction (
const LFS& lfs,
const std::shared_ptr<Data>& data)
290 , _basis(lfs.maxSize())
293 void evaluate (
const typename Traits::ElementType& e,
294 const typename Traits::DomainType& x,
295 typename Traits::RangeType& y)
const
299 typedef FiniteElementInterfaceSwitch<
300 typename ChildLFS::Traits::FiniteElement
307 const ChildLFS& child_lfs = _lfs.child(k);
308 FESwitch::basis(child_lfs.finiteElement()).evaluateFunction(x,_basis);
310 for (std::size_t i = 0; i < child_lfs.size(); ++i)
311 y[k] += _data->_x_local(child_lfs,i) * _basis[i];
316 const typename Traits::GridViewType& gridView()
const
318 return _lfs.gridFunctionSpace().gridView();
321 const LFS& localFunctionSpace()
const
329 const std::shared_ptr<Data> _data;
330 mutable std::vector<typename BasisSwitch::Range> _basis;
335 class DefaultFunctionNameGenerator
340 template<
typename TreePath>
341 std::string operator()(std::string component_name, TreePath tp)
const
343 if (component_name.empty())
346 if (_prefix.empty() && _suffix.empty())
349 "You need to either name all GridFunctionSpaces "
350 "written to the VTK file or provide a prefix / suffix.");
353 std::stringstream name_stream;
355 if (!_prefix.empty())
356 name_stream << _prefix << _separator;
359 for (std::size_t i = 0; i < tp.size(); ++i)
360 name_stream << (i > 0 ? _separator :
"") << tp.element(i);
362 if (!_suffix.empty())
363 name_stream << _separator << _suffix;
364 return name_stream.str();
369 return _prefix + component_name + _suffix;
373 DefaultFunctionNameGenerator& prefix(std::string prefix)
379 DefaultFunctionNameGenerator& suffix(std::string suffix)
385 DefaultFunctionNameGenerator& separator(std::string separator)
387 _separator = separator;
391 DefaultFunctionNameGenerator(std::string prefix =
"",
392 std::string suffix =
"",
393 std::string separator =
"_")
396 , _separator(separator)
403 std::string _separator;
407 inline DefaultFunctionNameGenerator defaultNameScheme()
409 return DefaultFunctionNameGenerator();
413 template<
typename VTKWriter,
typename Data,
typename NameGenerator>
414 struct add_solution_to_vtk_writer_visitor
415 :
public TypeTree::DefaultVisitor
416 ,
public TypeTree::DynamicTraversal
420 template<
typename LFS,
typename Child,
typename TreePath>
424 static const bool value =
426 !std::is_convertible<
427 TypeTree::ImplementationTag<typename LFS::Traits::GridFunctionSpace>,
428 VectorGridFunctionSpaceTag
435 template<
typename DGF,
typename TreePath>
436 void add_to_vtk_writer(
const std::shared_ptr<DGF>& dgf, TreePath tp)
438 std::string name = name_generator(dgf->localFunctionSpace().gridFunctionSpace().name(),tp);
439 switch (dgf->dataSetType())
441 case DGF::Output::vertexData:
442 vtk_writer.addVertexData(std::make_shared<VTKGridFunctionAdapter<DGF> >(dgf,name.c_str()));
444 case DGF::Output::cellData:
445 vtk_writer.addCellData(std::make_shared<VTKGridFunctionAdapter<DGF> >(dgf,name.c_str()));
448 DUNE_THROW(NotImplemented,
"Unsupported data set type");
456 template<
typename LFS,
typename TreePath>
457 void add_vector_solution(
const LFS& lfs, TreePath tp, VectorGridFunctionSpaceTag tag)
459 add_to_vtk_writer(std::make_shared<DGFTreeVectorFunction<LFS,Data> >(lfs,data),tp);
466 template<
typename LFS,
typename TreePath>
467 void add_vector_solution(
const LFS& lfs, TreePath tp, GridFunctionSpaceTag tag)
483 template<
typename LFS,
typename TreePath>
484 typename std::enable_if<
486 typename LFS::Traits::GridFunctionSpace::Traits::GridView,
487 typename vtk_writer_traits<VTKWriter>::GridView
490 post(
const LFS& lfs, TreePath tp)
495 template<
typename LFS,
typename TreePath>
496 typename std::enable_if<
498 typename LFS::Traits::GridFunctionSpace::Traits::GridView,
499 typename vtk_writer_traits<VTKWriter>::GridView
502 leaf(
const LFS& lfs, TreePath tp)
507 template<
typename LFS,
typename TreePath>
508 typename std::enable_if<
510 typename LFS::Traits::GridFunctionSpace::Traits::GridView,
511 typename vtk_writer_traits<VTKWriter>::GridView
514 post(
const LFS& lfs, TreePath tp)
516 if (predicate(lfs, tp))
517 add_vector_solution(lfs,tp,TypeTree::ImplementationTag<typename LFS::Traits::GridFunctionSpace>());
521 template<
typename LFS,
typename TreePath>
522 typename std::enable_if<
524 typename LFS::Traits::GridFunctionSpace::Traits::GridView,
525 typename vtk_writer_traits<VTKWriter>::GridView
528 leaf(
const LFS& lfs, TreePath tp)
530 if (predicate(lfs, tp))
531 add_to_vtk_writer(std::make_shared<DGFTreeLeafFunction<LFS,Data> >(lfs,data),tp);
535 add_solution_to_vtk_writer_visitor(VTKWriter& vtk_writer_, std::shared_ptr<Data> data_,
const NameGenerator& name_generator_,
const typename Data::Predicate& predicate_)
536 : vtk_writer(vtk_writer_)
538 , name_generator(name_generator_)
539 , predicate(predicate_)
542 VTKWriter& vtk_writer;
543 std::shared_ptr<Data> data;
544 const NameGenerator& name_generator;
545 typename Data::Predicate predicate;
549 struct DefaultPredicate
551 template<
typename LFS,
typename TP>
552 bool operator()(
const LFS& lfs, TP tp)
const
558 template<
typename VTKWriter,
typename Data_>
559 struct OutputCollector
565 typedef typename Data::GridFunctionSpace GFS;
566 typedef typename Data::Vector Vector;
567 typedef typename Data::Predicate Predicate;
569 template<
typename NameGenerator>
570 OutputCollector& addSolution(
const NameGenerator& name_generator)
573 add_solution_to_vtk_writer_visitor<VTKWriter,Data,NameGenerator> visitor(_vtk_writer,_data,name_generator,_predicate);
578 template<
typename Factory,
typename TreePath>
579 OutputCollector& addCellFunction(Factory factory, TreePath tp, std::string name)
581 typedef typename std::remove_reference<
decltype(*factory.create(_data->_lfs.child(tp),_data))>::type DGF;
582 _vtk_writer.addCellData(std::make_shared<VTKGridFunctionAdapter<DGF> >(factory.create(_data->_lfs.child(tp),_data),name));
586 template<
template<
typename...>
class Function,
typename TreePath,
typename... Params>
587 OutputCollector& addCellFunction(TreePath tp, std::string name, Params&&... params)
589 using LFS = TypeTree::ChildForTreePath<typename Data::LFS,TreePath>;
590 typedef Function<LFS,Data,Params...> DGF;
591 _vtk_writer.addCellData(
592 std::make_shared<VTKGridFunctionAdapter<DGF> >(
593 std::make_shared<DGF>(
597 std::forward<Params>(params)...
604 template<
typename Factory,
typename TreePath>
605 OutputCollector& addVertexFunction(Factory factory, TreePath tp, std::string name)
607 typedef typename std::remove_reference<
decltype(*factory.create(_data->_lfs.child(tp),_data))>::type DGF;
608 _vtk_writer.addVertexData(std::make_shared<VTKGridFunctionAdapter<DGF> >(factory.create(_data->_lfs.child(tp),_data),name));
612 template<
template<
typename...>
class Function,
typename TreePath,
typename... Params>
613 OutputCollector& addVertexFunction(TreePath tp, std::string name, Params&&... params)
615 using LFS = TypeTree::ChildForTreePath<typename Data::LFS,TreePath>;
616 typedef Function<LFS,Data,Params...> DGF;
617 _vtk_writer.addVertexData(
618 std::make_shared<VTKGridFunctionAdapter<DGF> >(
619 std::make_shared<DGF>(
623 std::forward<Params>(params)...
630 OutputCollector(VTKWriter& vtk_writer,
const std::shared_ptr<Data>& data,
const Predicate& predicate = Predicate())
631 : _vtk_writer(vtk_writer)
633 , _predicate(predicate)
636 VTKWriter& _vtk_writer;
637 std::shared_ptr<Data> _data;
638 Predicate _predicate;
644 template<
typename VTKWriter,
647 typename NameGenerator = vtk::DefaultFunctionNameGenerator,
648 typename Predicate = vtk::DefaultPredicate>
649 vtk::OutputCollector<
651 vtk::DGFTreeCommonData<GFS,X,Predicate>
653 addSolutionToVTKWriter(VTKWriter& vtk_writer,
656 const NameGenerator& name_generator = vtk::defaultNameScheme(),
657 const Predicate& predicate = Predicate())
659 typedef vtk::DGFTreeCommonData<GFS,X,Predicate> Data;
661 vtk::OutputCollector<VTKWriter,Data> collector(vtk_writer, data, predicate);
662 collector.addSolution(name_generator);
667 template<
typename VTKWriter,
670 typename NameGenerator = vtk::DefaultFunctionNameGenerator,
671 typename Predicate = vtk::DefaultPredicate>
672 vtk::OutputCollector<
674 vtk::DGFTreeCommonData<GFS,X,Predicate>
676 addSolutionToVTKWriter(VTKWriter& vtk_writer,
677 std::shared_ptr<GFS> gfs,
678 std::shared_ptr<X> x,
679 const NameGenerator& name_generator = vtk::defaultNameScheme(),
680 const Predicate& predicate = Predicate())
682 typedef vtk::DGFTreeCommonData<GFS,X,Predicate> Data;
683 vtk::OutputCollector<VTKWriter,Data> collector(vtk_writer, std::make_shared<Data>(gfs,x),predicate);
684 collector.addSolution(name_generator);
vector space out of a tensor product of fields.
Definition: fvector.hh:96
IndexTypeImp IndexType
The type used for the indices.
Definition: indexidset.hh:90
leaf of a function tree
Definition: function.hh:302
T Traits
Export type traits.
Definition: function.hh:193
void evaluate(const typename Traits::ElementType &e, const typename Traits::DomainType &x, typename Traits::RangeType &y) const
Evaluate the GridFunction at given position.
Definition: function.hh:208
Output::DataSetType dataSetType() const
Return the data set type of this function.
Definition: function.hh:154
Helper class for common data of a DGFTree.
Definition: vtk.hh:77
A few common exception classes.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:71
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:79
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:213
Dune namespace.
Definition: alignedallocator.hh:14
shared_ptr< T > stackobject_to_shared_ptr(T &t)
Create a shared_ptr for a stack-allocated object.
Definition: shared_ptr.hh:75
This file implements the class shared_ptr (a reference counting pointer), for those systems that don'...
Switch for uniform treatment of local and global basis classes.
Definition: interfaceswitch.hh:132
static const std::size_t dimRange
export dimension of the values
Definition: interfaceswitch.hh:143
Basis::Traits::RangeField RangeField
export field type of the values
Definition: interfaceswitch.hh:141
Basis::Traits::Range Range
export vector type of the values
Definition: interfaceswitch.hh:145
Switch for uniform treatment of finite element with either the local or the global interface.
Definition: interfaceswitch.hh:27
traits class holding the function signature, same as in local function
Definition: function.hh:183
void post(T &&t, TreePath treePath) const
Method for postfix tree traversal.
Definition: visitor.hh:80
void leaf(T &&t, TreePath treePath) const
Method for leaf traversal.
Definition: visitor.hh:90
Helper classes to provide indices for geometrytypes for use in a vector.