Line | Branch | Exec | Source |
---|---|---|---|
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 | // SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder | ||
5 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
6 | // | ||
7 | /*! | ||
8 | * \file | ||
9 | * \ingroup InputOutput | ||
10 | * \brief read from a file into a solution vector | ||
11 | */ | ||
12 | #ifndef DUMUX_IO_LOADSOLUTION_HH | ||
13 | #define DUMUX_IO_LOADSOLUTION_HH | ||
14 | |||
15 | #include <string> | ||
16 | #include <iostream> | ||
17 | #include <vector> | ||
18 | #include <unordered_set> | ||
19 | #include <unordered_map> | ||
20 | #include <type_traits> | ||
21 | #include <functional> | ||
22 | |||
23 | #include <dune/common/exceptions.hh> | ||
24 | #include <dune/common/indices.hh> | ||
25 | #include <dune/grid/common/partitionset.hh> | ||
26 | |||
27 | #include <dumux/common/parameters.hh> | ||
28 | #include <dumux/common/typetraits/isvalid.hh> | ||
29 | #include <dumux/common/typetraits/vector.hh> | ||
30 | #include <dumux/common/typetraits/state.hh> | ||
31 | #include <dumux/io/vtk/vtkreader.hh> | ||
32 | #include <dumux/discretization/method.hh> | ||
33 | #include <dumux/common/gridcapabilities.hh> | ||
34 | |||
35 | namespace Dumux { | ||
36 | |||
37 | /*! | ||
38 | * \ingroup InputOutput | ||
39 | * \brief a data handle to communicate the solution on ghosts and overlaps | ||
40 | * when reading from vtk file in parallel | ||
41 | */ | ||
42 | template <class Container, class EntityMapper, int codim> | ||
43 | 2 | class LoadSolutionDataHandle | |
44 | : public Dune::CommDataHandleIF< LoadSolutionDataHandle<Container, EntityMapper, codim>, | ||
45 | std::decay_t<decltype(std::declval<Container>()[0])> > | ||
46 | { | ||
47 | using FieldType = std::decay_t<decltype(std::declval<Container>()[0])>; | ||
48 | public: | ||
49 |
1/20✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
|
2 | LoadSolutionDataHandle(Container& container, |
50 | const EntityMapper& mapper) | ||
51 | 2 | : mapper_(mapper) | |
52 |
1/20✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
|
2 | , container_(container) |
53 | {} | ||
54 | |||
55 | ✗ | bool contains(int dim, int cd) const | |
56 | ✗ | { return cd == codim; } | |
57 | |||
58 | //! returns true if size per entity of given dim and codim is a constant | ||
59 | bool fixedSize(int dim, int cd) const | ||
60 | { return true; } | ||
61 | |||
62 | template<class EntityType> | ||
63 | std::size_t size (const EntityType &e) const | ||
64 | { return 1; } | ||
65 | |||
66 | template<class MessageBufferImp, class EntityType> | ||
67 | 32 | void gather(MessageBufferImp& buff, const EntityType& e) const | |
68 | { | ||
69 | 32 | const auto vIdx = mapper_.index(e); | |
70 | 32 | buff.write(container_[vIdx]); | |
71 | 32 | } | |
72 | |||
73 | template<class MessageBufferImp, class EntityType> | ||
74 | 32 | void scatter(MessageBufferImp& buff, const EntityType& e, std::size_t n) | |
75 | { | ||
76 | 32 | const auto vIdx = mapper_.index(e); | |
77 | 32 | FieldType tmp; | |
78 | 32 | buff.read(tmp); | |
79 | 32 | container_[vIdx] = tmp; | |
80 | 32 | } | |
81 | |||
82 | private: | ||
83 | EntityMapper mapper_; | ||
84 | Container& container_; | ||
85 | }; | ||
86 | |||
87 | /*! | ||
88 | * \ingroup InputOutput | ||
89 | * \brief read from a vtk file into a solution vector with primary variables without state | ||
90 | */ | ||
91 | template <class SolutionVector, class PvNameFunc, class GridGeometry> | ||
92 | 104 | auto loadSolutionFromVtkFile(SolutionVector& sol, | |
93 | const std::string fileName, | ||
94 | PvNameFunc&& targetPvNameFunc, | ||
95 | const GridGeometry& gridGeometry, | ||
96 | const VTKReader::DataType& dataType) | ||
97 | -> typename std::enable_if_t<!decltype(isValid(Detail::hasState())(sol[0]))::value, void> | ||
98 | { | ||
99 | 104 | VTKReader vtu(fileName); | |
100 | |||
101 | using PrimaryVariables = typename SolutionVector::block_type; | ||
102 | using Scalar = typename PrimaryVariables::field_type; | ||
103 | constexpr auto dim = GridGeometry::GridView::dimension; | ||
104 | const std::size_t targetSolutionSize = PrimaryVariables::dimension; | ||
105 | |||
106 | std::size_t matchingLoadedArrays = 0; | ||
107 |
2/2✓ Branch 0 taken 112 times.
✓ Branch 1 taken 54 times.
|
322 | for (std::size_t i = 0; i < targetSolutionSize; i++) |
108 |
4/6✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
✓ Branch 3 taken 112 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 111 times.
✓ Branch 7 taken 1 times.
|
436 | if (vtu.hasData(targetPvNameFunc(i,0), dataType)) |
109 | 216 | matchingLoadedArrays++; | |
110 | |||
111 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 24 times.
|
104 | if (matchingLoadedArrays < targetSolutionSize) |
112 | std::cout << "The loaded solution does not provide a data array for each of the primary variables. \n" | ||
113 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
2 | << "The target solution has "<< targetSolutionSize << " entries, " |
114 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
2 | << "whereas the loaded solution provides only " << matchingLoadedArrays << " data array(s). \n" |
115 | << "Make sure that the model concepts are compatible, " | ||
116 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2 | << "and be sure to provide initial conditions for the missing primary variables. \n"; |
117 | |||
118 |
3/4✓ Branch 0 taken 111 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 54 times.
|
594 | for (std::size_t targetPvIdx = 0; targetPvIdx < targetSolutionSize; ++targetPvIdx) |
119 | { | ||
120 | 218 | std::vector<Scalar> vec; | |
121 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
|
218 | const auto targetPvName = targetPvNameFunc(targetPvIdx, 0); |
122 | |||
123 |
3/4✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 111 times.
✓ Branch 4 taken 1 times.
|
220 | if (vtu.hasData(targetPvName, dataType)) |
124 |
2/4✓ Branch 1 taken 111 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 111 times.
|
432 | vec = vtu.readData<std::vector<Scalar>>(targetPvName, dataType); |
125 | else | ||
126 | { | ||
127 | std::cout << "The loaded solution does not have a field named \"" << targetPvName << "\". " | ||
128 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
2 | << "Make sure this field is filled using the initial method in the problem definition. \n"; |
129 | continue; | ||
130 | } | ||
131 | |||
132 |
2/2✓ Branch 0 taken 84 times.
✓ Branch 1 taken 27 times.
|
216 | if (dataType == VTKReader::DataType::cellData) |
133 | { | ||
134 | 164 | std::size_t i = 0; | |
135 |
2/12✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 3 taken 6240 times.
✗ Branch 6 not taken.
|
17876 | for (const auto& element : elements(gridGeometry.gridView(), Dune::Partitions::interior)) |
136 | { | ||
137 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
8856 | const auto eIdx = gridGeometry.elementMapper().index(element); |
138 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
8856 | sol[eIdx][targetPvIdx] = vec[i++]; |
139 | } | ||
140 | } | ||
141 | |||
142 | // for staggered face data (which is written out as VTK point data) we just read in the vector | ||
143 |
1/2✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
50 | else if (dataType == VTKReader::DataType::pointData && GridGeometry::discMethod == DiscretizationMethods::staggered) |
144 | { | ||
145 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
|
50 | if (sol.size() != vec.size()) |
146 | ✗ | DUNE_THROW(Dune::InvalidStateException, "Solution size (" << sol.size() << ") does not match input size (" << vec.size() << ")!"); | |
147 | |||
148 |
2/2✓ Branch 0 taken 1870 times.
✓ Branch 1 taken 25 times.
|
3790 | for (std::size_t i = 0; i < sol.size(); ++i) |
149 | 3740 | sol[i][targetPvIdx] = vec[i]; | |
150 | } | ||
151 | |||
152 | // structured grid vertex data | ||
153 |
3/6✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | else if (const auto extension = fileName.substr(fileName.find_last_of(".") + 1); extension == "vti" || extension == "pvti") |
154 | { | ||
155 | ✗ | std::size_t i = 0; | |
156 | ✗ | for (const auto& vertex : vertices(gridGeometry.gridView(), Dune::Partitions::interior + Dune::Partitions::border)) | |
157 | { | ||
158 | ✗ | const auto vIdx = gridGeometry.vertexMapper().index(vertex); | |
159 | ✗ | sol[vIdx][targetPvIdx] = vec[i++]; | |
160 | } | ||
161 | } | ||
162 | |||
163 | // unstructured grid vertex data | ||
164 | else | ||
165 | { | ||
166 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | std::size_t i = 0; |
167 |
3/6✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
|
2 | std::vector<bool> visited(gridGeometry.gridView().size(dim), false); |
168 |
2/11✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 162 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 6 not taken.
|
324 | for (const auto& element : elements(gridGeometry.gridView(), Dune::Partitions::interior)) |
169 | { | ||
170 |
2/5✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 0 taken 320 times.
|
480 | for (int vIdxLocal = 0; vIdxLocal < element.subEntities(dim); ++vIdxLocal) |
171 | { | ||
172 |
1/2✓ Branch 1 taken 320 times.
✗ Branch 2 not taken.
|
320 | const auto vIdxGlobal = gridGeometry.vertexMapper().subIndex(element, vIdxLocal, dim); |
173 |
2/2✓ Branch 0 taken 162 times.
✓ Branch 1 taken 158 times.
|
320 | if (!visited[vIdxGlobal]) |
174 | { | ||
175 | 162 | sol[vIdxGlobal][targetPvIdx] = vec[i++]; | |
176 | 162 | visited[vIdxGlobal] = true; | |
177 | } | ||
178 | } | ||
179 | } | ||
180 | 2 | } | |
181 | } | ||
182 | 104 | } | |
183 | |||
184 | /*! | ||
185 | * \ingroup InputOutput | ||
186 | * \brief read from a sequential file into a solution vector with primary variables with state | ||
187 | */ | ||
188 | template <class SolutionVector, class PvNameFunc, class GridGeometry> | ||
189 | 2 | auto loadSolutionFromVtkFile(SolutionVector& sol, | |
190 | const std::string fileName, | ||
191 | PvNameFunc&& targetPvNameFunc, | ||
192 | const GridGeometry& gridGeometry, | ||
193 | const VTKReader::DataType& dataType) | ||
194 | -> typename std::enable_if_t<decltype(isValid(Detail::hasState())(sol[0]))::value, void> | ||
195 | { | ||
196 | 2 | VTKReader vtu(fileName); | |
197 | // get states at each dof location | ||
198 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
4 | const auto stateAtDof = vtu.readData<std::vector<int>>("phase presence", dataType); |
199 | |||
200 | // determine all states that are present | ||
201 | 2 | std::unordered_set<int> states; | |
202 |
2/2✓ Branch 0 taken 656 times.
✓ Branch 1 taken 2 times.
|
658 | for (std::size_t i = 0; i < stateAtDof.size(); ++i) |
203 |
1/2✓ Branch 1 taken 656 times.
✗ Branch 2 not taken.
|
656 | states.insert(stateAtDof[i]); |
204 | |||
205 | using PrimaryVariables = typename SolutionVector::block_type; | ||
206 | using Scalar = typename PrimaryVariables::field_type; | ||
207 | 2 | const std::size_t targetSolutionSize = PrimaryVariables::dimension; | |
208 | |||
209 | 2 | std::unordered_set<std::string> matchingNames; | |
210 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
|
8 | for (std::size_t i = 0; i < targetSolutionSize; i++) |
211 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
|
18 | for (const auto& state : states) |
212 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
|
24 | if ( vtu.hasData(targetPvNameFunc(i,state), dataType)) |
213 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
|
24 | matchingNames.insert(targetPvNameFunc(i,state)); |
214 | |||
215 | 2 | const std::size_t matchingLoadedArrays = matchingNames.size() - (states.size()-1); | |
216 | |||
217 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (matchingLoadedArrays < targetSolutionSize) |
218 | std::cout << "The loaded solution does not provide a data array for each of the primary variables. \n" | ||
219 | ✗ | << "The target solution has "<< targetSolutionSize << " entries, " | |
220 | ✗ | << "whereas the loaded solution provides only " << matchingLoadedArrays << " data array(s). \n" | |
221 | << "Make sure that the model concepts are compatible, " | ||
222 | ✗ | << "and be sure to provide initial conditions for the missing primary variables. \n"; | |
223 | |||
224 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
|
8 | for (std::size_t targetPvIdx = 0; targetPvIdx < targetSolutionSize; ++targetPvIdx) |
225 | { | ||
226 | 6 | std::unordered_map<int, std::vector<Scalar>> data; | |
227 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
|
18 | for (const auto& state : states) |
228 | { | ||
229 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | const auto targetPvName = targetPvNameFunc(targetPvIdx, state); |
230 | |||
231 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
|
12 | if (vtu.hasData(targetPvName, dataType)) |
232 |
2/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
|
24 | data[state] = vtu.readData<std::vector<Scalar>>(targetPvName, dataType); |
233 | else | ||
234 | { | ||
235 | std::cout << "Loaded Solution does not have a field named \"" << targetPvName << "\". " | ||
236 | ✗ | << "Make sure this field is filled using the initial method in the problem definition. \n"; | |
237 | continue; | ||
238 | } | ||
239 | } | ||
240 | |||
241 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (dataType == VTKReader::DataType::cellData) |
242 | { | ||
243 | ✗ | std::size_t i = 0; | |
244 | ✗ | for (const auto& element : elements(gridGeometry.gridView(), Dune::Partitions::interior)) | |
245 | { | ||
246 | ✗ | const auto eIdx = gridGeometry.elementMapper().index(element); | |
247 | ✗ | const auto state = stateAtDof[i]; | |
248 | ✗ | sol[eIdx][targetPvIdx] = data[state][i++]; | |
249 | ✗ | sol[eIdx].setState(state); | |
250 | } | ||
251 | } | ||
252 | else | ||
253 | { | ||
254 | 6 | std::size_t i = 0; | |
255 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
6 | constexpr int dim = GridGeometry::GridView::dimension; |
256 |
3/6✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
|
6 | std::vector<bool> visited(gridGeometry.gridView().size(dim), false); |
257 |
2/4✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1574 times.
✗ Branch 5 not taken.
|
3148 | for (const auto& element : elements(gridGeometry.gridView(), Dune::Partitions::interior)) |
258 | { | ||
259 |
2/2✓ Branch 0 taken 6272 times.
✓ Branch 1 taken 1568 times.
|
7840 | for (int vIdxLocal = 0; vIdxLocal < element.subEntities(dim); ++vIdxLocal) |
260 | { | ||
261 |
1/2✓ Branch 1 taken 6272 times.
✗ Branch 2 not taken.
|
6272 | const auto vIdxGlobal = gridGeometry.vertexMapper().subIndex(element, vIdxLocal, dim); |
262 |
2/2✓ Branch 0 taken 1774 times.
✓ Branch 1 taken 4498 times.
|
6272 | if (!visited[vIdxGlobal]) |
263 | { | ||
264 |
1/2✓ Branch 1 taken 1774 times.
✗ Branch 2 not taken.
|
1774 | const auto state = stateAtDof[i]; |
265 | 1774 | sol[vIdxGlobal][targetPvIdx] = data[state][i++]; | |
266 | 1774 | sol[vIdxGlobal].setState(state); | |
267 | 1774 | visited[vIdxGlobal] = true; | |
268 | } | ||
269 | } | ||
270 | } | ||
271 | 6 | } | |
272 | } | ||
273 | 4 | } | |
274 | |||
275 | /*! | ||
276 | * \ingroup InputOutput | ||
277 | * \brief helper function to determine the primary variable names of a model with privar state | ||
278 | * \note use this as input for the load solution function | ||
279 | */ | ||
280 | template<class IOFields, class PrimaryVariables, class ModelTraits = void, class FluidSystem = void, class SolidSystem = void> | ||
281 | 2 | auto createPVNameFunction(const std::string& paramGroup = "") | |
282 | -> typename std::enable_if_t<decltype(isValid(Detail::hasState())(PrimaryVariables(0)))::value, std::function<std::string(int,int)>> | ||
283 | { | ||
284 |
1/4✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
6 | return [paramGroup](int pvIdx, int state = 0) |
285 | { | ||
286 | static auto numStates = (1 << ModelTraits::numFluidPhases()) - 1; | ||
287 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
72 | const auto paramNameWithState = "LoadSolution.PriVarNamesState" + std::to_string(state); |
288 | |||
289 |
4/12✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 36 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 36 times.
|
108 | if (hasParamInGroup(paramGroup, "LoadSolution.PriVarNames") && !hasParamInGroup(paramGroup, paramNameWithState)) |
290 | ✗ | DUNE_THROW(Dune::NotImplemented, "please provide LoadSolution.PriVarNamesState1..." << numStates | |
291 | << " or remove LoadSolution.PriVarNames to use the model's default primary variable names"); | ||
292 | |||
293 |
3/4✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 24 times.
|
72 | else if (hasParamInGroup(paramGroup, paramNameWithState)) |
294 | { | ||
295 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | const auto pvName = getParamFromGroup<std::vector<std::string>>(paramGroup, paramNameWithState); |
296 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | return pvName[pvIdx]; |
297 | 12 | } | |
298 | else | ||
299 |
1/2✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
|
24 | return IOFields::template primaryVariableName<ModelTraits, FluidSystem, SolidSystem>(pvIdx, state); |
300 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
40 | }; |
301 | } | ||
302 | |||
303 | /*! | ||
304 | * \ingroup InputOutput | ||
305 | * \brief helper function to determine the primary variable names of a model without state | ||
306 | * \note use this as input for the load solution function | ||
307 | */ | ||
308 | template<class IOFields, class PrimaryVariables, class ModelTraits = void, class FluidSystem = void, class SolidSystem = void> | ||
309 | 4 | auto createPVNameFunction(const std::string& paramGroup = "") | |
310 | -> typename std::enable_if_t<!decltype(isValid(Detail::hasState())(PrimaryVariables(0)))::value, std::function<std::string(int,int)>> | ||
311 | { | ||
312 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
8 | if (hasParamInGroup(paramGroup, "LoadSolution.PriVarNames")) |
313 | { | ||
314 | ✗ | const auto pvName = getParamFromGroup<std::vector<std::string>>(paramGroup, "LoadSolution.PriVarNames"); | |
315 | ✗ | return [n = std::move(pvName)](int pvIdx, int state = 0){ return n[pvIdx]; }; | |
316 | ✗ | } | |
317 | else | ||
318 | 16 | return [](int pvIdx, int state = 0){ return IOFields::template primaryVariableName<ModelTraits, FluidSystem, SolidSystem>(pvIdx, state); }; | |
319 | } | ||
320 | |||
321 | /*! | ||
322 | * \ingroup InputOutput | ||
323 | * \brief load a solution vector from file | ||
324 | * \note Supports the following file extensions: *.vtu *.vtp *.pvtu, *.pvtp | ||
325 | * \param sol the solution vector to read from file | ||
326 | * \param fileName the file name of the file to read from | ||
327 | * \param targetPvNameFunc a function with the signature std::string(int pvIdx) | ||
328 | * in case the primary variables have a state the signature is std::string(int pvIdx, int state) | ||
329 | * \param gridGeometry the grid geometry of the discretization method used | ||
330 | */ | ||
331 | template <class SolutionVector, class PvNameFunc, class GridGeometry> | ||
332 | 106 | void loadSolution(SolutionVector& sol, | |
333 | const std::string& fileName, | ||
334 | PvNameFunc&& targetPvNameFunc, | ||
335 | const GridGeometry& gridGeometry) | ||
336 | { | ||
337 | 106 | const auto extension = fileName.substr(fileName.find_last_of(".") + 1); | |
338 | 106 | auto dataType = GridGeometry::discMethod == DiscretizationMethods::box ? | |
339 | VTKReader::DataType::pointData : VTKReader::DataType::cellData; | ||
340 | |||
341 |
5/6✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 26 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
106 | if (extension == "vtu" || extension == "vtp" || extension == "vti") |
342 | { | ||
343 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 25 times.
|
100 | if (GridGeometry::discMethod == DiscretizationMethods::staggered && extension == "vtp") |
344 | 50 | dataType = VTKReader::DataType::pointData; | |
345 | |||
346 |
1/2✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
|
108 | loadSolutionFromVtkFile(sol, fileName, targetPvNameFunc, gridGeometry, dataType); |
347 | } | ||
348 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
2 | else if (extension == "pvtu" || extension == "pvtp" || extension == "pvti") |
349 | { | ||
350 | if (GridGeometry::discMethod == DiscretizationMethods::staggered) | ||
351 |
1/20✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
|
2 | DUNE_THROW(Dune::NotImplemented, "reading staggered solution from a parallel vtk file"); |
352 | |||
353 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | loadSolutionFromVtkFile(sol, fileName, targetPvNameFunc, gridGeometry, dataType); |
354 | } | ||
355 | else | ||
356 | ✗ | DUNE_THROW(Dune::NotImplemented, "loadSolution for file with extension " << extension); | |
357 | |||
358 | // communicate solution on ghost and overlap dofs | ||
359 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 54 times.
|
106 | if (gridGeometry.gridView().comm().size() > 1) |
360 | { | ||
361 | using GridView = typename GridGeometry::GridView; | ||
362 | ✗ | if (dataType == VTKReader::DataType::cellData) | |
363 | { | ||
364 | LoadSolutionDataHandle<SolutionVector, typename GridGeometry::ElementMapper, 0> | ||
365 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | dataHandle(sol, gridGeometry.elementMapper()); |
366 | |||
367 | if constexpr (Detail::canCommunicate<typename GridView::Traits::Grid, 0>) | ||
368 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | gridGeometry.gridView().communicate(dataHandle, |
369 | Dune::InteriorBorder_All_Interface, | ||
370 | Dune::ForwardCommunication); | ||
371 | else | ||
372 | DUNE_THROW(Dune::InvalidStateException, "Cannot call loadSolution on multiple processes for a grid that cannot communicate codim-" << 0 << "-entities."); | ||
373 | 2 | } | |
374 | else | ||
375 | { | ||
376 | LoadSolutionDataHandle<SolutionVector, typename GridGeometry::VertexMapper, GridView::dimension> | ||
377 | ✗ | dataHandle(sol, gridGeometry.vertexMapper()); | |
378 | |||
379 | if constexpr (Detail::canCommunicate<typename GridView::Traits::Grid, GridView::dimension>) | ||
380 | ✗ | gridGeometry.gridView().communicate(dataHandle, | |
381 | Dune::InteriorBorder_All_Interface, | ||
382 | Dune::ForwardCommunication); | ||
383 | else | ||
384 | DUNE_THROW(Dune::InvalidStateException, "Cannot call loadSolution on multiple processes for a grid that cannot communicate codim-" << GridView::dimension << "-entities."); | ||
385 | ✗ | } | |
386 | } | ||
387 | 106 | } | |
388 | } // end namespace Dumux | ||
389 | |||
390 | #endif | ||
391 |