40    using GridGeometry = 
typename GridVariables::GridGeometry;
 
   41    using GridView = 
typename GridGeometry::GridView;
 
   42    using Scalar = 
typename GridVariables::Scalar;
 
   43    using FaceVariables = 
typename GridVariables::GridFaceVariables::FaceVariables;
 
   44    using FVElementGeometry = 
typename GridGeometry::LocalView;
 
   45    using SubControlVolumeFace = 
typename FVElementGeometry::SubControlVolumeFace;
 
   47    using Element = 
typename GridView::template Codim<0>::Entity;
 
   48    using GlobalPosition = 
typename Element::Geometry::GlobalCoordinate;
 
   50    struct FaceVarScalarDataInfo { std::function<Scalar(
const FaceVariables&)> get; std::string 
name; };
 
   51    struct FaceVarVectorDataInfo { std::function<GlobalPosition(
const SubControlVolumeFace& scvf, 
const FaceVariables&)> get; std::string 
name; };
 
   53    struct FaceFieldScalarDataInfo
 
   55        FaceFieldScalarDataInfo(
const std::vector<Scalar>& f, 
const std::string& n) : data(f), 
name(n) {}
 
   56        const std::vector<Scalar>& data;
 
   57        const std::string 
name;
 
   60    struct FaceFieldVectorDataInfo
 
   62        FaceFieldVectorDataInfo(
const std::vector<GlobalPosition>& f, 
const std::string& n) : data(f), 
name(n) {}
 
   63        const std::vector<GlobalPosition>& data;
 
   64        const std::string 
name;
 
   72                             const std::string& 
name,
 
   74                             Dune::VTK::DataMode dm = Dune::VTK::conforming,
 
   78    , sequenceWriter_(faceWriter_, 
name + 
"-face", 
"",
"",
 
   83        static_assert(std::is_same<Sol, SolutionVector>::value, 
"Make sure that sol has the same type as SolutionVector." 
   84                                                                "Use StaggeredVtkOutputModule<GridVariables, decltype(sol)> when calling the constructor.");
 
   89        coordinatesInitialized_ = 
false;
 
 
  102        if (v.size() == this->gridGeometry().gridView().size(1))
 
  103            faceFieldScalarDataInfo_.emplace_back(v, 
name);
 
  105            DUNE_THROW(Dune::RangeError, 
"Size mismatch of added field!");
 
 
  113        if (v.size() == this->gridGeometry().gridView().size(1))
 
  114            faceFieldVectorDataInfo_.emplace_back(v, 
name);
 
  116            DUNE_THROW(Dune::RangeError, 
"Size mismatch of added field!");
 
 
  124        faceVarScalarDataInfo_.push_back(FaceVarScalarDataInfo{f, 
name});
 
 
  130    void addFaceVariable(std::function<GlobalPosition(
const SubControlVolumeFace& scvf, 
const FaceVariables&)>&& f, 
const std::string& 
name)
 
  132        faceVarVectorDataInfo_.push_back(FaceVarVectorDataInfo{f, 
name});
 
 
  138    void write(
double time, Dune::VTK::OutputType type = Dune::VTK::ascii)
 
  142            getFaceDataAndWrite_(time);
 
 
  149    void updateCoordinates_()
 
  151        coordinates_.resize(this->
gridGeometry().numFaceDofs());
 
  152        for(
auto&& facet : facets(this->
gridGeometry().gridView()))
 
  154            const int dofIdxGlobal = this->
gridGeometry().gridView().indexSet().index(facet);
 
  155            coordinates_[dofIdxGlobal] = facet.geometry().center();
 
  157        coordinatesInitialized_ = 
true;
 
  162    void getFaceDataAndWrite_(
const Scalar time)
 
  164        const auto numPoints = this->
gridGeometry().numFaceDofs();
 
  167        std::vector<bool> dofVisited(numPoints, 
false);
 
  170        if(!coordinatesInitialized_)
 
  171            updateCoordinates_();
 
  174        std::vector<std::vector<Scalar>> faceVarScalarData;
 
  175        std::vector<std::vector<GlobalPosition>> faceVarVectorData;
 
  177        if(!faceVarScalarDataInfo_.empty())
 
  178            faceVarScalarData.resize(faceVarScalarDataInfo_.size(), std::vector<Scalar>(numPoints));
 
  180        if(!faceVarVectorDataInfo_.empty())
 
  181            faceVarVectorData.resize(faceVarVectorDataInfo_.size(), std::vector<GlobalPosition>(numPoints));
 
  185        for (
const auto& element : elements(this->
gridGeometry().gridView(), Dune::Partitions::interior))
 
  187            if (!faceVarScalarDataInfo_.empty() || !faceVarVectorDataInfo_.empty())
 
  189                fvGeometry.bind(element);
 
  190                elemFaceVars.bindElement(element, fvGeometry, this->
sol());
 
  192                for (
auto&& scvf : scvfs(fvGeometry))
 
  194                    const auto dofIdxGlobal = scvf.dofIndex();
 
  195                    if(dofVisited[dofIdxGlobal])
 
  198                    dofVisited[dofIdxGlobal] = 
true;
 
  200                    const auto& faceVars = elemFaceVars[scvf];
 
  203                    for (std::size_t i = 0; i < faceVarScalarDataInfo_.size(); ++i)
 
  204                        faceVarScalarData[i][dofIdxGlobal] = faceVarScalarDataInfo_[i].get(faceVars);
 
  207                    for (std::size_t i = 0; i < faceVarVectorDataInfo_.size(); ++i)
 
  208                            faceVarVectorData[i][dofIdxGlobal] = faceVarVectorDataInfo_[i].get(scvf, faceVars);
 
  214        if(!faceVarScalarDataInfo_.empty())
 
  215            for (std::size_t i = 0; i < faceVarScalarDataInfo_.size(); ++i)
 
  216                faceWriter_->addPointData(faceVarScalarData[i], faceVarScalarDataInfo_[i].name);
 
  218        if(!faceVarVectorDataInfo_.empty())
 
  219            for (std::size_t i = 0; i < faceVarVectorDataInfo_.size(); ++i)
 
  220                faceWriter_->addPointData(faceVarVectorData[i], faceVarVectorDataInfo_[i].name);
 
  223        for(
const auto& field: faceFieldScalarDataInfo_)
 
  224            faceWriter_->addPointData(field.data, field.name);
 
  226        for(
const auto& field: faceFieldVectorDataInfo_)
 
  227            faceWriter_->addPointData(field.data, field.name);
 
  230        sequenceWriter_.write(time);
 
  233        coordinates_.clear();
 
  234        coordinates_.shrink_to_fit();
 
  235        coordinatesInitialized_ = 
false;
 
  239    std::shared_ptr<PointCloudVtkWriter<Scalar, GlobalPosition>> faceWriter_;
 
  241    VTKSequenceWriter<PointCloudVtkWriter<Scalar, GlobalPosition>> sequenceWriter_;
 
  245    std::vector<GlobalPosition> coordinates_;
 
  246    bool coordinatesInitialized_;
 
  248    std::vector<FaceVarScalarDataInfo> faceVarScalarDataInfo_;
 
  249    std::vector<FaceVarVectorDataInfo> faceVarVectorDataInfo_;
 
  251    std::vector<FaceFieldScalarDataInfo> faceFieldScalarDataInfo_;
 
  252    std::vector<FaceFieldVectorDataInfo> faceFieldVectorDataInfo_;