Dune-Fufem 2.12-git
Loading...
Searching...
No Matches
writebasis.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_WRITEBASIS_HH
8#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_WRITEBASIS_HH
9
10#include <type_traits>
11#include <variant>
12#include <string>
13#include <algorithm>
14
18
20
25
26#include <dune/vtk/vtkwriter.hh>
28
30
31namespace Dune::Fufem {
32
51 template<class Range=double, class Vector=std::monostate, class Basis>
52 void writeBasis(const Basis& basis, std::string name, int order = -1)
53 {
54 // Create a vector suitable to hold coefficients for the basis
55 auto vector = [&] {
57 return Dune::Functions::makeISTLVector<double>(basis.rootBasis().preBasis().containerDescriptor());
58 else
59 {
60 auto v = Vector();
63 return v;
64 }
65 }();
66 auto vectorBackend = Dune::Functions::istlVectorBackend(vector);
67
68 // Mark all DOFs of the subspace and deduce the appropriate order.
69 // Since there's no mechanism for deducing a bitvector so far,
70 // use a double vector to store flags.
71 auto inSubspace = vector;
72 auto inSubspaceBackend = Dune::Functions::istlVectorBackend(inSubspace);
73 auto localView = basis.localView();
74 for(const auto& element : Dune::elements(basis.gridView()))
75 {
76 localView.bind(element);
77 Dune::TypeTree::forEachLeafNode(localView.tree(), [&](auto&& node, auto&& treePath) {
78 for(auto i : Dune::range(node.size()))
79 inSubspaceBackend[localView.index(node.localIndex(i))] = 1;
80 if (order==-1)
81 order = std::max(order, int(node.finiteElement().localBasis().order()));
82 });
83 }
84
85 auto basisFunction = Dune::Functions::makeDiscreteGlobalBasisFunction<double>(basis, vectorBackend);
86 auto i_flat=0;
87 Dune::Fufem::recursiveForEachVectorEntry(vector, [&](auto&& vector_i, const auto& i)
88 {
89 if (inSubspaceBackend[i]) {
90 vectorBackend[i] = 1;
92 vtkWriter.addPointData(basisFunction, Dune::VTK::FieldInfo("basisfunction", Dune::VTK::FieldInfo::Type::scalar, 1));
93 vtkWriter.write(Dune::formatString(name, i_flat));
94 vectorBackend[i] = 0;
95 }
96 i_flat++;
97 });
98 }
99
121 template<class Range=double, class Vector=std::monostate, class Basis, class Constraints>
122 void writeBasis(const Basis& basis, std::string name, const Constraints& constraints, int order = -1)
123 {
124 // Create a vector suitable to hold coefficients for the basis
125 auto vector = [&] {
127 return Dune::Functions::makeISTLVector<double>(basis.rootBasis().preBasis().containerDescriptor());
128 else
129 {
130 auto v = Vector();
131 Dune::Functions::istlVectorBackend(v).resize(basis);
133 return v;
134 }
135 }();
136 auto vectorBackend = Dune::Functions::istlVectorBackend(vector);
137
138 // Mark all DOFs of the subspace and deduce the appropriate order.
139 // Since there's no mechanism for deducing a bitvector so far,
140 // use a double vector to store flags.
141 auto inSubspace = vector;
142 auto inSubspaceBackend = Dune::Functions::istlVectorBackend(inSubspace);
143 auto localView = basis.localView();
144 for(const auto& element : Dune::elements(basis.gridView()))
145 {
146 localView.bind(element);
147 Dune::TypeTree::forEachLeafNode(localView.tree(), [&](auto&& node, auto&& treePath) {
148 for(auto i : Dune::range(node.size()))
149 inSubspaceBackend[localView.index(node.localIndex(i))] = 1;
150 if (order==-1)
151 order = std::max(order, int(node.finiteElement().localBasis().order()));
152 });
153 }
154
155 auto basisFunction = Dune::Functions::makeDiscreteGlobalBasisFunction<double>(basis, vectorBackend);
156 auto i_flat=0;
157 Dune::Fufem::recursiveForEachVectorEntry(vector, [&](auto&& vector_i, const auto& i)
158 {
159 if (inSubspaceBackend[i]) {
160 vectorBackend = 0;
161 vectorBackend[i] = 1;
162 constraints.interpolate(vector);
164 vtkWriter.addPointData(basisFunction, Dune::VTK::FieldInfo("basisfunction", Dune::VTK::FieldInfo::Type::scalar, 1));
165 vtkWriter.write(Dune::formatString(name, i_flat));
166 }
167 i_flat++;
168 });
169 }
170
171
172} // end namespace Dune::Fufem
173
174#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_WRITEBASIS_HH
const char * name()
static std::string formatString(const std::string &s, const T &... args)
void forEachLeafNode(Tree &&tree, LeafFunc &&leafFunc)
T forward(T... args)
void writeBasis(const Basis &basis, std::string name, int order=-1)
Write basis functions as vtk-sequence.
Definition writebasis.hh:52
auto istlVectorBackend(Vector &v)
Definition dunefunctionsboundaryfunctionalassembler.hh:29