OpenLB 1.8.1
Loading...
Searching...
No Matches
lbSolver.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2012-2021 Mathias J. Krause, Benjamin Förster,
4 * Julius Jessberger
5 * E-mail contact: info@openlb.net
6 * The most recent release of OpenLB can be downloaded at
7 * <http://www.openlb.net/>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23*/
24
25
26#ifndef LBSOLVER_HH
27#define LBSOLVER_HH
28
29
30#include "lbSolver.h"
31
32
33namespace olb {
34
35template<typename T, typename PARAMETERS, typename LATTICES>
37{
38 if (this->parameters(names::Output()).verbose) {
39 clout << "Start initialization" << std::endl;
40 }
41
42 this->prepareGeometry();
43 // Removes all not needed boundary voxels outside the surface
44 //this->geometry().clean(this->parameters(names::Output()).verbose);
45 // Removes all not needed boundary voxels inside the surface
46 this->geometry().innerClean(this->parameters(names::Output()).verbose);
47 geometry().checkForErrors(this->parameters(names::Output()).verbose);
48 if (this->parameters(names::Output()).verbose) {
49 geometry().getStatistics().print();
50 }
51
52 this->_isInitialized = true;
53
54 if (this->parameters(names::Output()).verbose) {
55 clout << "Finished initialization" << std::endl;
56 }
57}
58
59template<typename T, typename PARAMETERS, typename LATTICES>
61{
62 if (! this->_isInitialized) {
63 this->initialize();
64 }
65 build();
66 setInitialValues();
67}
68
69template<typename T, typename PARAMETERS, typename LATTICES>
71{
72 if (this->parameters(names::Output()).printLogConverter) {
73 writeLogConverter();
74 }
75
76 _timer = std::make_unique<util::Timer<BaseType<T>>>(
77 converter().getLatticeTime(this->parameters(names::Simulation()).maxTime),
78 _sGeometry->getStatistics().getNvoxel(),
79 1); // 1 for printing a short timer summary
80
81 if constexpr (isStationary){
82 for (unsigned i = 0; i < getNumberStationaryLattices(); ++i) {
83 _convergenceCheck[i] = std::make_unique<util::ValueTracer<T>>(
84 converter().getLatticeTime(this->parameters(names::Stationarity()).physInterval[i]),
85 this->parameters(names::Stationarity()).epsilon[i]);
86 }
87 }
88
89 _itBoundaryUpdate = util::max(
90 converter().getLatticeTime(this->parameters(names::Simulation()).physBoundaryValueUpdateTime),
91 (unsigned long) {1});
92 _itCheckStability = util::max(
93 converter().getLatticeTime(this->parameters(names::Simulation()).physTimeStabilityCheck),
94 (unsigned long) {1});
95
96 renewLattices();
97}
98
99template<typename T, typename PARAMETERS, typename LATTICES>
101{
102 if (this->parameters(names::Output()).verbose) {
103 clout << "Start prepareSimulation" << std::endl;
104 }
105
106 this->_iT = 0;
107
108 build();
109
110 setInitialValues();
111
112 meta::tuple_for_each(_sLattices, [](auto& lattice){
113 lattice->initialize();
114 lattice->getStatistics().reset();
115 lattice->getStatistics().initialize();
116 });
117
118
119 if constexpr (outputVTK) {
120 if (this->parameters(names::VisualizationVTK()).output != "off") {
121 prepareVTK();
122 }
123 }
124
125 if (this->parameters(names::Output()).verbose) {
126 clout << "Finished prepareSimulation" << std::endl;
127 clout << "Start collide-and-stream loop" << std::endl;
128 }
129 _timer->start();
130}
131
132
133template<typename T, typename PARAMETERS, typename LATTICES>
135{
136 if (iT % _itBoundaryUpdate == 0) {
137 setBoundaryValues(iT);
138 }
139
140 meta::tuple_for_each(_sLattices, [](auto& lattice) {
141 // TODO: dispose also communication of fields
142 lattice->communicate();
143 });
144
145
146 if constexpr (outputVTK) {
147 if ( this->parameters(names::VisualizationVTK()).printOutput == olb::parameters::OutputPlot<T>::pO_intervals
148 && iT % converter().getLatticeTime(this->parameters(names::VisualizationVTK()).saveTime) == 0 ) {
149 writeVTK(iT);
150 }
151 }
152 if constexpr (outputImages) {
154 && iT % converter().getLatticeTime(this->parameters(names::VisualizationImages()).saveTime) == 0 ) {
155 writeImages(iT);
156 }
157 }
158 if constexpr (outputGnuplot) {
160 && iT % converter().getLatticeTime(this->parameters(names::VisualizationGnuplot()).saveTime) == 0 ) {
161 writeGnuplot(iT);
162 }
163 }
164 if ( this->parameters(names::Output()).verbose
165 && iT % converter().getLatticeTime(this->parameters(names::Output()).logT) == 0) {
166 printLog(iT);
167 }
168 computeResults(iT);
169 getResults(iT);
170
171 meta::tuple_for_each(_sLattices, [](auto& lattice){
172 lattice->collideAndStream();
173 });
174
175 if (this->parameters(names::Simulation()).pressureFilter) {
176 // TODO: allow choosing the lattices here
177 std::get<0>(_sLattices)->stripeOffDensityOffset(std::get<0>(_sLattices)->getStatistics().getAverageRho() - T(1));
178 }
179
180 if constexpr (isStationary){
181 unsigned counter = 0;
182 using parameters_t = typename PARAMETERS::template value<names::Stationarity>;
183 parameters_t::stat_lattices::for_each( [&](auto Id) {
184 // using Name = typename decltype(Id)::type;
185 if (this->parameters(names::Stationarity()).convergenceType[counter] == parameters_t::MaxLatticeVelocity){
186 _convergenceCheck[counter]->takeValue( this->lattice(Id).getStatistics().getMaxU());
187 }
188 else if (this->parameters(names::Stationarity()).convergenceType[counter] == parameters_t::AverageEnergy){
189 _convergenceCheck[counter]->takeValue( this->lattice(Id).getStatistics().getAverageEnergy() );
190 }
191 else if (this->parameters(names::Stationarity()).convergenceType[counter] == parameters_t::AverageRho){
192 _convergenceCheck[counter]->takeValue( this->lattice(Id).getStatistics().getAverageRho());
193 }
194 else {
195 throw std::invalid_argument("Convergence type is not supported.\n");
196 }
197 counter++;
198 });
199 }
200
201 if (iT % _itCheckStability == 0) {
202 checkStability(iT);
203 }
204}
205
206template<typename T, typename PARAMETERS, typename LATTICES>
208{
209 meta::tuple_for_each(_sLattices, [](auto& lattice) {
210 // TODO: dispose also communication of fields...
211 lattice->communicate();
212 });
213
214 if ( this->parameters(names::Output()).verbose ) {
215 printLog(this->_iT);
216 }
217 if constexpr (outputVTK) {
218 if ( this->parameters(names::VisualizationVTK()).printOutput == olb::parameters::OutputPlot<T>::pO_final) {
219 writeVTK(this->_iT);
220 }
221 }
222 if constexpr (outputImages) {
223 if ( this->parameters(names::VisualizationImages()).printOutput == olb::parameters::OutputPlot<T>::pO_final) {
224 writeImages(this->_iT);
225 }
226 }
227 if constexpr (outputGnuplot) {
228 if ( this->parameters(names::VisualizationGnuplot()).printOutput == olb::parameters::OutputPlot<T>::pO_final) {
229 writeGnuplot(this->_iT);
230 }
231 }
232 getResults(this->_iT);
233
234 _timer->stop();
235 if (this->parameters(names::Output()).verbose) {
236 clout << "Finished collide-and-stream loop" << std::endl;
237 clout << "Start postprocessing" << std::endl;
238 }
239 computeResults();
240
241 if (this->parameters(names::Output()).verbose) {
242 _timer->printSummary();
243 }
244
245 // required to finish output tasks during use of gpu
246 meta::tuple_for_each(_sLattices, [](auto& lattice) {
247 lattice->setProcessingContext(ProcessingContext::Evaluation);
248 });
249
250 if (this->parameters(names::Output()).verbose) {
251 clout << "Finished postprocessing" << std::endl;
252 }
253}
254
255template<typename T, typename PARAMETERS, typename LATTICES>
257{
258 if (iT > this->converter().getLatticeTime(this->parameters(names::Simulation()).maxTime)){
259 return true;
260 }
261
262 if constexpr (isStationary){
263 if (std::all_of(_convergenceCheck.cbegin(), _convergenceCheck.cend(), [](auto& c){
264 return c->hasConverged();
265 } )) {
266 if (this->parameters(names::Output()).verbose) {
267 clout << "Simulation converged." << std::endl;
268 }
269 return true;
270 }
271 }
272
273 return false;
274}
275
276template<typename T, typename PARAMETERS, typename LATTICES>
278{
279 bool result = true;
280 meta::tuple_for_each(_sLattices, [&](auto& lattice){
281 if (lattice->getStatistics().getMaxU() > this->parameters(names::Simulation()).boundMaxU) {
282 clout << "PROBLEM uMax=" << lattice->getStatistics().getMaxU() << std::endl;
283 lattice->getStatistics().print(iT, converter().getPhysTime(iT));
284 if (this->parameters(names::Simulation()).exitMaxU) {
285 exit(1);
286 }
287 result = false;
288 }
289 });
290 return result;
291}
292
293template<typename T, typename PARAMETERS, typename LATTICES>
295{
296 meta::tuple_for_each(_sLattices, [&](auto& lattice){
297 using lattice_type = typename std::remove_reference_t<decltype(lattice)>::element_type;
298 lattice = std::make_shared<lattice_type>(geometry());
299 });
300
301 prepareLattices();
302}
303
304template<typename T, typename PARAMETERS, typename LATTICES>
306{
307 using OutputParameters_t = typename PARAMETERS::template value<names::Output>;
308 OutputParameters_t::printLatticeStatistics::for_each( [&](auto type){
309 lattice(type.get()).getStatistics().print(iT, converter().getPhysTime(iT));
310 } );
311
312 _timer->print(iT, this->parameters(names::Output()).timerPrintMode);
313}
314
315template<typename T, typename PARAMETERS, typename LATTICES>
317{
318 converter().print();
319 converter().write(this->parameters(names::Output()).name);
320}
321
322template<typename T, typename PARAMETERS, typename LATTICES>
324{
325 // write the geometric information. Since this does not depend on the
326 // lattice, we may w.l.o.g. work with the first lattice
327 auto& lattice = *std::get<0>(_sLattices);
328 using DESCRIPTOR = typename LATTICES::values_t::template get<0>;
329
330
331 SuperVTMwriter<T,dim> vtmWriter(this->parameters(names::VisualizationVTK()).filename);
332
334 SuperLatticeCuboid<T,DESCRIPTOR> cuboid(lattice);
335 SuperLatticeRank<T,DESCRIPTOR> rank(lattice);
336 vtmWriter.write( cuboid );
337 vtmWriter.write( rank );
338 vtmWriter.createMasterFile();
339}
340
341} // namespace olb
342
343#endif
LbSolver is a generic solver for Lattice-Boltzmann problems.
Definition lbSolver.h:132
void buildAndReturn()
Build geometry, lattice.
Definition lbSolver.hh:60
virtual void printLog(std::size_t iT) const
Definition lbSolver.hh:305
void prepareSimulation() override
Set up lattice and initialize fields.
Definition lbSolver.hh:100
void timeStep(std::size_t iT) override
Collide-and-stream + additional computations.
Definition lbSolver.hh:134
virtual void prepareVTK() const
Write geometric information for vtk output The default version writes geometry, cuboid,...
Definition lbSolver.hh:323
virtual void writeLogConverter() const
Definition lbSolver.hh:316
virtual bool checkStability(std::size_t iT)
check stability: maxU should be <= _boundMaxU for a stable simulation Returns true if this fulfilled
Definition lbSolver.hh:277
virtual bool exitCondition(std::size_t iT) const override
Condition, when to exit the time-stepping loop Returns true if the loop shall be continued.
Definition lbSolver.hh:256
void postSimulation() override
Evaluate results.
Definition lbSolver.hh:207
void initialize() override
Set up geometry.
Definition lbSolver.hh:36
void tuple_for_each(TUPLE &tuple, F &&f)
Apply F to each element of TUPLE.
Definition meta.h:373
Expr max(Expr a, Expr b)
Definition expr.cpp:245
Top level namespace for all of OpenLB.
std::conditional_t< DESCRIPTOR::d==2, SuperLatticeRank2D< T, DESCRIPTOR >, SuperLatticeRank3D< T, DESCRIPTOR > > SuperLatticeRank
Definition aliases.h:108
std::conditional_t< DIM==2, SuperVTMwriter2D< T, OUT_T, W >, SuperVTMwriter3D< T, OUT_T, W > > SuperVTMwriter
Definition aliases.h:78
void initialize(int *argc, char ***argv, bool multiOutput, bool verbose)
Initialize OpenLB.
Definition olbInit.cpp:49
std::conditional_t< DESCRIPTOR::d==2, SuperLatticeCuboid2D< T, DESCRIPTOR >, SuperLatticeCuboid3D< T, DESCRIPTOR > > SuperLatticeCuboid
Definition aliases.h:98
void writeVTK(SuperF2D< T, W > &f, int iT=0)
Write out functor F to VTK file (helper)