MaMiCo 1.2
Loading...
Searching...
No Matches
NumericalSolver.h
1// Copyright (C) 2015 Technische Universitaet Muenchen
2// This file is part of the Mamico project. For conditions of distribution
3// and use, please see the copyright notice in Mamico's main folder, or at
4// www5.in.tum.de/mamico
5#ifndef _MOLECULARDYNAMICS_COUPLING_SOLVERS_NUMERICALSOLVER_H_
6#define _MOLECULARDYNAMICS_COUPLING_SOLVERS_NUMERICALSOLVER_H_
7
8#include "coupling/CouplingMDDefinitions.h"
9#include "tarch/la/Vector.h"
10#include <cmath>
11#include <fstream>
12#include <iomanip>
13#include <sstream>
14#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
15#include <mpi.h>
16#endif
17#include "coupling/datastructures/CouplingCell.h"
18#include "coupling/datastructures/FlexibleCellContainer.h"
19#include "coupling/indexing/IndexingService.h"
20#include "coupling/services/ParallelTimeIntegrationService.h"
21#include "coupling/solvers/CouetteSolver.h"
22namespace coupling {
23namespace solvers {
24class NumericalSolver;
25}
26} // namespace coupling
27
34public:
46 NumericalSolver(const double channelheight, const double dx, const double dt, const double kinVisc, const int plotEveryTimestep, const std::string filestem,
47 const tarch::la::Vector<3, unsigned int> processes, const Scenario* scen = nullptr)
48 : coupling::solvers::AbstractCouetteSolver<3>(), _channelheight(channelheight), _dx(dx), _dt(dt), _kinVisc(kinVisc), _processes(processes),
49 _plotEveryTimestep(plotEveryTimestep), _filestem(filestem), _scen(scen) {
50 _vel = new double[3 * (_domainSizeX + 2) * (_domainSizeY + 2) * (_domainSizeZ + 2)];
51 _density = new double[(_domainSizeX + 2) * (_domainSizeY + 2) * (_domainSizeZ + 2)];
52 _flag = new Flag[(_domainSizeX + 2) * (_domainSizeY + 2) * (_domainSizeZ + 2)];
53#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
54 _sendBufferX = new double[5 * (_domainSizeY + 2) * (_domainSizeZ + 2)];
55 _recvBufferX = new double[5 * (_domainSizeY + 2) * (_domainSizeZ + 2)];
56 _sendBufferY = new double[5 * (_domainSizeX + 2) * (_domainSizeZ + 2)];
57 _recvBufferY = new double[5 * (_domainSizeX + 2) * (_domainSizeZ + 2)];
58 _sendBufferZ = new double[5 * (_domainSizeX + 2) * (_domainSizeY + 2)];
59 _recvBufferZ = new double[5 * (_domainSizeX + 2) * (_domainSizeY + 2)];
60#endif
61 // zero velocity, unit density; flags are set to FLUID
62 for (int i = 0; i < (_domainSizeX + 2) * (_domainSizeY + 2) * (_domainSizeZ + 2); i++) {
63 for (int d = 0; d < 3; d++) {
64 _vel[i * 3 + d] = (double)0.0;
65 }
66 _density[i] = 1.0;
67 _flag[i] = FLUID;
68 }
69 // determine parallel neighbours
71 // correct boundary flags based on physical description (Couette scenario)
72 // bottom - moving wall
73 for (int i = 0; i < (_domainSizeX + 2) * (_domainSizeY + 2); i++) {
74 _flag[i] = MOVING_WALL;
75 }
76 // top - noslip
77 for (int i = (_domainSizeX + 2) * (_domainSizeY + 2) * (_domainSizeZ + 1); i < (_domainSizeX + 2) * (_domainSizeY + 2) * (_domainSizeZ + 2); i++) {
78 _flag[i] = NO_SLIP;
79 }
80 // front - periodic
81 for (int z = 1; z < _domainSizeZ + 1; z++) {
82 for (int x = 0; x < _domainSizeX + 2; x++) {
83 _flag[get(x, 0, z)] = PERIODIC;
84 }
85 }
86 // back - periodic
87 for (int z = 1; z < _domainSizeZ + 1; z++) {
88 for (int x = 0; x < _domainSizeX + 2; x++) {
89 _flag[get(x, _domainSizeY + 1, z)] = PERIODIC;
90 }
91 }
92 // left - periodic
93 for (int z = 1; z < _domainSizeZ + 1; z++) {
94 for (int y = 1; y < _domainSizeY + 1; y++) {
95 _flag[get(0, y, z)] = PERIODIC;
96 }
97 }
98 for (int z = 1; z < _domainSizeZ + 1; z++) {
99 for (int y = 1; y < _domainSizeY + 1; y++) {
100 _flag[get(_domainSizeX + 1, y, z)] = PERIODIC;
101 }
102 }
103 // correct boundary flags in case of MPI-parallel simulations (Couette
104 // scenario)
106 }
107
110 if (_vel != NULL) {
111 delete[] _vel;
112 _vel = NULL;
113 }
114 if (_density != NULL) {
115 delete[] _density;
116 _density = NULL;
117 }
118 if (_flag != NULL) {
119 delete[] _flag;
120 _flag = NULL;
121 }
122#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
123 if (_sendBufferX != NULL) {
124 delete[] _sendBufferX;
125 _sendBufferX = NULL;
126 }
127 if (_sendBufferY != NULL) {
128 delete[] _sendBufferY;
129 _sendBufferY = NULL;
130 }
131 if (_sendBufferZ != NULL) {
132 delete[] _sendBufferZ;
133 _sendBufferZ = NULL;
134 }
135 if (_recvBufferX != NULL) {
136 delete[] _recvBufferX;
137 _recvBufferX = NULL;
138 }
139 if (_recvBufferY != NULL) {
140 delete[] _recvBufferY;
141 _recvBufferY = NULL;
142 }
143 if (_recvBufferZ != NULL) {
144 delete[] _recvBufferZ;
145 _recvBufferZ = NULL;
146 }
147#endif
148 }
149
157 void setMDBoundary(tarch::la::Vector<3, double> mdDomainOffset, tarch::la::Vector<3, double> mdDomainSize, unsigned int overlapStrip) {
158 if (skipRank()) {
159 return;
160 }
161
162 for (int d = 0; d < 3; d++) {
163 _offset[d] = (floor(mdDomainOffset[d] / _dx + 0.5));
164 if (fabs(_offset[d] * _dx - mdDomainOffset[d]) / _dx > 1.0e-8) {
165 std::cout << "ERROR NumericalSolver::setMDBoundary(): offset does not match!" << std::endl;
166 exit(EXIT_FAILURE);
167 }
168 _globalNumberCouplingCells[d] = (floor(mdDomainSize[d] / _dx + 0.5));
169 if (fabs(_globalNumberCouplingCells[d] * _dx - mdDomainSize[d]) / _dx > 1.0e-8) {
170 std::cout << "ERROR NumericalSolver::setMDBoundary(): globalNumber "
171 "does not match!"
172 << std::endl;
173 exit(EXIT_FAILURE);
174 }
175 }
176 // flag local domain
177 for (int z = 0; z < _domainSizeZ + 2; z++) {
178 for (int y = 0; y < _domainSizeY + 2; y++) {
179 for (int x = 0; x < _domainSizeX + 2; x++) {
180 // determine global cell coordinates of the process-local (sub)domain
181 tarch::la::Vector<3, int> globalCoords(x - 1 + _coords[0] * _avgDomainSizeX, y - 1 + _coords[1] * _avgDomainSizeY,
182 z - 1 + _coords[2] * _avgDomainSizeZ);
183 bool isMDCell = true;
184 for (int d = 0; d < 3; d++) {
185 isMDCell = isMDCell && (globalCoords[d] > _offset[d] + (int)overlapStrip - 1) &&
186 (globalCoords[d] < _offset[d] + _globalNumberCouplingCells[d] - (int)overlapStrip);
187 }
188 if (isMDCell) {
189 _flag[get(x, y, z)] = MD_BOUNDARY;
190 }
191 }
192 }
193 }
194 }
195
201
205
212
216 virtual double getDensity(tarch::la::Vector<3, double> pos) const = 0;
217
220 virtual void setWallVelocity(const tarch::la::Vector<3, double> wallVelocity) = 0;
221
225 static int getAvgDomainSize(double channelheight, double dx, tarch::la::Vector<3, unsigned int> processes, int d) {
226 int globalDomainSize = floor((channelheight + 0.5) / dx);
227 return globalDomainSize / processes[d];
228 }
229
230private:
235#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
236 constexpr int dim = 3;
237 unsigned int rank = IDXS.getRank();
238 // determine rank coordinates
239 coords[2] = rank / (_processes[0] * _processes[1]);
240 coords[1] = (rank - coords[2] * _processes[0] * _processes[1]) / _processes[0];
241 coords[0] = rank - coords[2] * _processes[0] * _processes[1] - coords[1] * _processes[0];
242#endif
243 return coords;
244 }
245
248#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
249 int rank;
250 int size;
251 MPI_Comm_rank(coupling::indexing::IndexingService<3>::getInstance().getComm(), &rank);
252 MPI_Comm_size(coupling::indexing::IndexingService<3>::getInstance().getComm(), &size);
253 // check if enough ranks are available
254 if (_processes[0] * _processes[1] * _processes[2] > (unsigned int)size) {
255 std::cout << "ERROR NumericalSolver::determineParallelNeighbours(): Not "
256 "enough ranks available!"
257 << std::endl;
258 exit(EXIT_FAILURE);
259 }
260 // neighbour dependencies based on Couette problem
261 // left,right: periodic
262 _parallelNeighbours[LEFT] = ((_coords[0] + _processes[0] - 1) % _processes[0]) + _processes[0] * (_coords[1] + _processes[1] * _coords[2]);
263 _parallelNeighbours[RIGHT] = ((_coords[0] + _processes[0] + 1) % _processes[0]) + _processes[0] * (_coords[1] + _processes[1] * _coords[2]);
264 // back,front: periodic
265 _parallelNeighbours[FRONT] = _coords[0] + _processes[0] * (((_coords[1] + _processes[1] - 1) % _processes[1]) + _processes[1] * _coords[2]);
266 _parallelNeighbours[BACK] = _coords[0] + _processes[0] * (((_coords[1] + _processes[1] + 1) % _processes[1]) + _processes[1] * _coords[2]);
267 // top: either neighbour or MPI_PROC_NULL
268 if (_coords[2] == _processes[2] - 1) {
269 _parallelNeighbours[TOP] = MPI_PROC_NULL;
270 } else {
271 _parallelNeighbours[TOP] = _coords[0] + _processes[0] * (_coords[1] + _processes[1] * (_coords[2] + 1));
272 }
273 // bottom either neighbour or MPI_PROC_NULL
274 if (_coords[2] == 0) {
275 _parallelNeighbours[BOTTOM] = MPI_PROC_NULL;
276 } else {
277 _parallelNeighbours[BOTTOM] = _coords[0] + _processes[0] * (_coords[1] + _processes[1] * (_coords[2] - 1));
278 }
279// std::cout << "Parallel neighbours for rank " << rank << ": " <<
280// _parallelNeighbours << std::endl;
281#endif
282 }
283
286#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
287 // bottom - moving wall
288 if (_coords[2] != 0) {
289 for (int i = 0; i < (_domainSizeX + 2) * (_domainSizeY + 2); i++) {
291 }
292 }
293 // top - noslip
294 if (_coords[2] != _processes[2] - 1) {
295 for (int i = (_domainSizeX + 2) * (_domainSizeY + 2) * (_domainSizeZ + 1); i < (_domainSizeX + 2) * (_domainSizeY + 2) * (_domainSizeZ + 2); i++) {
297 }
298 }
299 // for all other boundaries front,back,left,right, we use parallel
300 // boundaries. If we send from one processes to itself, this is still the
301 // same as periodic conditions front - periodic
302 for (int z = 1; z < _domainSizeZ + 1; z++) {
303 for (int x = 0; x < _domainSizeX + 2; x++) {
304 _flag[get(x, 0, z)] = PARALLEL_BOUNDARY;
305 }
306 }
307 // back - periodic
308 for (int z = 1; z < _domainSizeZ + 1; z++) {
309 for (int x = 0; x < _domainSizeX + 2; x++) {
311 }
312 }
313 // left - periodic
314 for (int z = 1; z < _domainSizeZ + 1; z++) {
315 for (int y = 1; y < _domainSizeY + 1; y++) {
316 _flag[get(0, y, z)] = PARALLEL_BOUNDARY;
317 }
318 }
319 for (int z = 1; z < _domainSizeZ + 1; z++) {
320 for (int y = 1; y < _domainSizeY + 1; y++) {
322 }
323 }
324#endif // COUPLING_MD_PARALLEL
325 }
326
330 int getDomainSize(double channelheight, double dx, tarch::la::Vector<3, unsigned int> processes, int d) const {
331 int globalDomainSize = floor((channelheight + 0.5) / dx);
333#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
334 int rank;
335 MPI_Comm_rank(coupling::indexing::IndexingService<3>::getInstance().getComm(), &rank);
336 // if this rank is outside the range given by processes: return 0
337 // -> cannot use method skipRank() here, since _processes may not be
338 // initialized yet!
339 if ((unsigned int)rank > processes[0] * processes[1] * processes[2] - 1) {
340 return 0;
341 }
342 // determine rank coordinates
343 coords[2] = ((unsigned int)rank) / (processes[0] * processes[1]);
344 coords[1] = (((unsigned int)rank) - coords[2] * processes[0] * processes[1]) / processes[0];
345 coords[0] = ((unsigned int)rank) - coords[2] * processes[0] * processes[1] - coords[1] * processes[0];
346#endif
347 // if this is not the last process along this direction: just return avg.
348 // number of cells
349 if (coords[d] < processes[d] - 1) {
350 return globalDomainSize / processes[d];
351 // otherwise: add the cells that have not been distributed yet
352 } else {
353 return globalDomainSize / processes[d] + globalDomainSize % processes[d];
354 }
355 }
356
357protected:
360 int get(int i) const {
361#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
362 if (i < 0) {
363 std::cout << "ERROR NumericalSolver::get(i): i<0!" << std::endl;
364 exit(EXIT_FAILURE);
365 }
366 if (i > (_domainSizeX + 2) * (_domainSizeY + 2) * (_domainSizeZ + 2)) {
367 std::cout << "ERROR NumericalSolver::get(i): i>max. Value!" << std::endl;
368 exit(EXIT_FAILURE);
369 }
370#endif
371 return i;
372 }
373
376 int get(int x, int y, int z) const {
377#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
378 if (x < 0) {
379 std::cout << "ERROR NumericalSolver::get(x,y,z): x<0!" << std::endl;
380 exit(EXIT_FAILURE);
381 }
382 if (x > _domainSizeX + 1) {
383 std::cout << "ERROR NumericalSolver::get(x,y,z): x>max. Value!" << std::endl;
384 exit(EXIT_FAILURE);
385 }
386 if (y < 0) {
387 std::cout << "ERROR NumericalSolver::get(x,y,z): y<0!" << std::endl;
388 exit(EXIT_FAILURE);
389 }
390 if (y > _domainSizeY + 1) {
391 std::cout << "ERROR NumericalSolver::get(x,y,z): y>max. Value!" << std::endl;
392 exit(EXIT_FAILURE);
393 }
394 if (z < 0) {
395 std::cout << "ERROR NumericalSolver::get(x,y,z): z<0!" << std::endl;
396 exit(EXIT_FAILURE);
397 }
398 if (z > _domainSizeZ + 1) {
399 std::cout << "ERROR NumericalSolver::get(x,y,z): z>max. Value!" << std::endl;
400 exit(EXIT_FAILURE);
401 }
402#endif
403 return x + (_domainSizeX + 2) * (y + (_domainSizeY + 2) * z);
404 }
405
409 int getParBuf(int x, int y, int lengthx, int lengthy) const {
410#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
411 if (x < 0 || x > lengthx + 1) {
412 std::cout << "ERROR NumericalSolver::getParBuf(...): x out of range!" << std::endl;
413 exit(EXIT_FAILURE);
414 }
415 if (y < 0 || y > lengthy + 1) {
416 std::cout << "ERROR NumericalSolver::getParBuf(...): y out of range!" << std::endl;
417 exit(EXIT_FAILURE);
418 }
419#endif
420 return x + (lengthx + 2) * y;
421 }
422
423 void plot() const {
424 int rank = 0; // rank in MPI-parallel simulations
425#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
426 MPI_Comm_rank(coupling::indexing::IndexingService<3>::getInstance().getComm(), &rank);
427#endif
428 std::stringstream ss;
429 ss << _filestem << "_r" << rank << "_c" << _counter;
430 if (_scen != nullptr) {
431 auto ts = _scen->getTimeIntegrationService();
432 if (ts != nullptr) {
433 if (ts->isPintEnabled())
434 ss << "_i" << ts->getInteration();
435 }
436 }
437 ss << ".vtk";
438 plot(ss.str());
439 }
440
442 void plot(std::string filename) const {
443 // only plot output if this is the correct timestep
444 if (_plotEveryTimestep < 1) {
445 return;
446 }
447 if (_counter % _plotEveryTimestep != 0) {
448 return;
449 }
450 std::ofstream file(filename.c_str());
451 if (!file.is_open()) {
452 std::cout << "ERROR NumericalSolver::plot(): Could not open file " << filename << "!" << std::endl;
453 exit(EXIT_FAILURE);
454 }
455 std::stringstream flag, density, velocity;
456
457 file << "# vtk DataFile Version 2.0" << std::endl;
458 file << "MaMiCo NumericalSolver" << std::endl;
459 file << "ASCII" << std::endl << std::endl;
460 file << "DATASET STRUCTURED_GRID" << std::endl;
461 file << "DIMENSIONS " << _domainSizeX + 3 << " " << _domainSizeY + 3 << " " << _domainSizeZ + 3 << std::endl; // everything +1 cause of change in index
462 file << "POINTS " << (_domainSizeX + 3) * (_domainSizeY + 3) * (_domainSizeZ + 3) << " float" << std::endl;
463
464 flag << "CELL_DATA " << (_domainSizeX + 2) * (_domainSizeY + 2) * (_domainSizeZ + 2) << std::endl;
465 flag << "SCALARS flag float 1" << std::endl;
466 flag << "LOOKUP_TABLE default" << std::endl;
467
468 density << std::setprecision(12);
469 density << "SCALARS density float 1 " << std::endl;
470 density << "LOOKUP_TABLE default" << std::endl;
471
472 velocity << std::setprecision(12);
473 velocity << "VECTORS velocity float" << std::endl;
474 // loop over domain (incl. boundary) and write point coordinates
475 for (int z = -1; z < _domainSizeZ + 2; z++) {
476 for (int y = -1; y < _domainSizeY + 2; y++) {
477 for (int x = -1; x < _domainSizeX + 2; x++) {
478 file << ((int)(_coords[0] * _avgDomainSizeX) + x) * _dx << " " << ((int)(_coords[1] * _avgDomainSizeY) + y) * _dx << " "
479 << ((int)(_coords[2] * _avgDomainSizeZ) + z) * _dx << std::endl;
480 }
481 }
482 }
483 // loop over domain (incl. boundary)
484 for (int z = 0; z < _domainSizeZ + 1 + 1; z++) {
485 for (int y = 0; y < _domainSizeY + 1 + 1; y++) {
486 for (int x = 0; x < _domainSizeX + 1 + 1; x++) { // CHANGE: start index used to be one
487 const int index = get(x, y, z);
488 // write information to streams
489 flag << _flag[index] << std::endl;
490 density << _density[index] << std::endl;
491 velocity << _vel[3 * index] << " " << _vel[3 * index + 1] << " " << _vel[3 * index + 2] << std::endl;
492 }
493 }
494 }
495 file << std::endl;
496 file << flag.str() << std::endl << std::endl;
497 flag.str("");
498 file << density.str() << std::endl;
499 density.str("");
500 file << velocity.str() << std::endl;
501 velocity.str("");
502 file.close();
503 }
504
509 bool skipRank() const {
510 int rank = 0;
511#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
512 MPI_Comm_rank(coupling::indexing::IndexingService<3>::getInstance().getComm(), &rank);
513#endif
514 return ((unsigned int)rank > _processes[0] * _processes[1] * _processes[2] - 1);
515 }
516
528
530 enum NbFlag {
531 LEFT = 0,
532 RIGHT = 1,
533 BACK = 2,
534 FRONT = 3,
535 BOTTOM = 4,
536 TOP = 5
537 };
538
539 const double _channelheight; //
541 const double _dx;
543 const double _dt;
545 const double _kinVisc;
552 const std::string _filestem;
569 int _counter{0};
571 double* _vel{NULL};
573 double* _density{NULL};
575 Flag* _flag{NULL};
576#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
578 double* _sendBufferX{NULL};
580 double* _recvBufferX{NULL};
582 double* _sendBufferY{NULL};
584 double* _recvBufferY{NULL};
586 double* _sendBufferZ{NULL};
588 double* _recvBufferZ{NULL};
589#endif
591 const int _xO{_domainSizeX + 2};
593 const int _yO{(_domainSizeX + 2) * (_domainSizeY + 2)};
600 const Scenario* _scen;
601};
602
603#endif // _MOLECULARDYNAMICS_COUPLING_SOLVERS_NUMERICALSOLVER_H_
Definition Scenario.h:15
provides access to coupling cells, which may belong to different indexing domains
Definition FlexibleCellContainer.h:30
interface for continuum/macro fluid solvers for the Couette scenario
Definition CouetteSolver.h:19
is a virtual base class for the interface for a numerical fluid solver for the Couette scenario
Definition NumericalSolver.h:33
const int _domainSizeX
domain size in x-direction
Definition NumericalSolver.h:554
double * _recvBufferY
buffer to receive data from from front/back neighbour
Definition NumericalSolver.h:584
double * _sendBufferX
buffer to send data from left/right to right/left neighbour
Definition NumericalSolver.h:578
int get(int x, int y, int z) const
returns linearized index and performs checks in debug mode
Definition NumericalSolver.h:376
const double _channelheight
the height and width of the channel in z and y direction
Definition NumericalSolver.h:539
const double _kinVisc
kinematic viscosity of the fluid
Definition NumericalSolver.h:545
tarch::la::Vector< 3, unsigned int > getNumberProcesses() const
returns the number of process, regards parallel runs
Definition NumericalSolver.h:204
virtual void setWallVelocity(const tarch::la::Vector< 3, double > wallVelocity)=0
changes the velocity at the moving wall (z=0)
int _counter
time step counter
Definition NumericalSolver.h:569
int get(int i) const
returns i and performs checks in debug mode
Definition NumericalSolver.h:360
const int _yO
offset for z-direction
Definition NumericalSolver.h:593
double * _recvBufferZ
buffer to receive data from from top/buttom neighbour
Definition NumericalSolver.h:588
const int _avgDomainSizeZ
avg. domain size in MPI-parallel simulation in z-direction
Definition NumericalSolver.h:564
void plot(std::string filename) const
create vtk plot if required
Definition NumericalSolver.h:442
int getParBuf(int x, int y, int lengthx, int lengthy) const
returns index in 2D parallel buffer with buffer dimensions lengthx+2,lengthy+2. Performs checks in de...
Definition NumericalSolver.h:409
double * _sendBufferY
buffer to send data from front/back to front/back neighbour
Definition NumericalSolver.h:582
const int _xO
offset for y-direction (lexicographic grid ordering)
Definition NumericalSolver.h:591
double * _sendBufferZ
buffer to send data from top/buttom to top/buttom neighbour
Definition NumericalSolver.h:586
void setParallelBoundaryFlags()
sets parallel boundary flags according to Couette scenario
Definition NumericalSolver.h:285
void setMDBoundary(tarch::la::Vector< 3, double > mdDomainOffset, tarch::la::Vector< 3, double > mdDomainSize, unsigned int overlapStrip)
flags the domain boundary cells.
Definition NumericalSolver.h:157
NumericalSolver(const double channelheight, const double dx, const double dt, const double kinVisc, const int plotEveryTimestep, const std::string filestem, const tarch::la::Vector< 3, unsigned int > processes, const Scenario *scen=nullptr)
a simple constructor
Definition NumericalSolver.h:46
tarch::la::Vector< 3, unsigned int > getProcessCoordinates() const
determines the process coordinates
Definition NumericalSolver.h:233
Flag * _flag
flag field
Definition NumericalSolver.h:575
const int _avgDomainSizeY
avg. domain size in MPI-parallel simulation in y-direction
Definition NumericalSolver.h:562
void determineParallelNeighbours()
determines the neighbour relation between the processes
Definition NumericalSolver.h:247
const tarch::la::Vector< 3, unsigned int > _coords
coordinates of this process (=1,1,1, unless parallel run of the solver )
Definition NumericalSolver.h:567
const int _domainSizeY
domain size in y-direction
Definition NumericalSolver.h:556
const double _dt
time step
Definition NumericalSolver.h:543
tarch::la::Vector< 3, unsigned int > getAvgNumberLBCells() const
returns the average number of cells on each process
Definition NumericalSolver.h:208
tarch::la::Vector< 3, unsigned int > _processes
domain decomposition on MPI rank basis; total number is given by multipling all entries
Definition NumericalSolver.h:548
double * _density
density field
Definition NumericalSolver.h:573
tarch::la::Vector< 6, int > _parallelNeighbours
neighbour ranks
Definition NumericalSolver.h:595
const std::string _filestem
file stem for vtk plot
Definition NumericalSolver.h:552
NbFlag
The flags are used on parallel boundaries to define in which direction the boundary goes.
Definition NumericalSolver.h:530
@ LEFT
a parallel boundary to the left
Definition NumericalSolver.h:531
@ RIGHT
a parallel boundary to the right
Definition NumericalSolver.h:532
@ BOTTOM
a parallel boundary to the bottom
Definition NumericalSolver.h:535
@ FRONT
a parallel boundary to the front
Definition NumericalSolver.h:534
@ TOP
a parallel boundary to the top
Definition NumericalSolver.h:536
@ BACK
a parallel boundary to the back
Definition NumericalSolver.h:533
static int getAvgDomainSize(double channelheight, double dx, tarch::la::Vector< 3, unsigned int > processes, int d)
Definition NumericalSolver.h:225
Flag
for every cell exists a flag entry, upon this is defined how the cell is handled
Definition NumericalSolver.h:519
@ MD_BOUNDARY
a cell on the boundary to md
Definition NumericalSolver.h:524
@ PERIODIC
a cell on a periodic boundary
Definition NumericalSolver.h:523
@ PARALLEL_BOUNDARY
a cell on a inner boundary of a splitted domain in a parallel run
Definition NumericalSolver.h:525
@ NO_SLIP
a cell on the no slip (non-moving) wall
Definition NumericalSolver.h:521
@ FLUID
a normal fluid cell
Definition NumericalSolver.h:520
@ MOVING_WALL
a cell on the moving wall
Definition NumericalSolver.h:522
virtual void setMDBoundaryValues(coupling::datastructures::FlexibleCellContainer< 3 > &md2macroBuffer)=0
applies the values received from the MD-solver within the conntinuum solver
int getDomainSize(double channelheight, double dx, tarch::la::Vector< 3, unsigned int > processes, int d) const
determines the local domain size on this rank where channelheight is the domain length in direction d...
Definition NumericalSolver.h:330
const int _plotEveryTimestep
number of time steps between vtk plots
Definition NumericalSolver.h:550
double * _vel
velocity field
Definition NumericalSolver.h:571
virtual double getDensity(tarch::la::Vector< 3, double > pos) const =0
returns the density for a given position
const int _avgDomainSizeX
avg. domain size in MPI-parallel simulation in x-direction
Definition NumericalSolver.h:560
bool skipRank() const
returns true, if this rank is not of relevance for the LB simulation
Definition NumericalSolver.h:509
double * _recvBufferX
buffer to receive data from from left/right neighbour
Definition NumericalSolver.h:580
tarch::la::Vector< 3, int > _globalNumberCouplingCells
the total number of coupling cells of the coupled simulation
Definition NumericalSolver.h:599
tarch::la::Vector< 3, int > _offset
offset of the md domain
Definition NumericalSolver.h:597
virtual ~NumericalSolver()
a simple destructor
Definition NumericalSolver.h:109
const double _dx
mesh size, dx=dy=dz
Definition NumericalSolver.h:541
const int _domainSizeZ
domain size in z-direction
Definition NumericalSolver.h:558
Definition Vector.h:24
all numerical solvers are defined in the namespace, and their interfaces
Definition CouetteSolver.h:14
everything necessary for coupling operations, is defined in here
Definition AdditiveMomentumInsertion.h:15