5#ifndef _MOLECULARDYNAMICS_COUPLING_SOLVERS_NUMERICALSOLVER_H_
6#define _MOLECULARDYNAMICS_COUPLING_SOLVERS_NUMERICALSOLVER_H_
8#include "coupling/CouplingMDDefinitions.h"
9#include "tarch/la/Vector.h"
14#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
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"
46 NumericalSolver(
const double channelheight,
const double dx,
const double dt,
const double kinVisc,
const int plotEveryTimestep,
const std::string filestem,
53#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
63 for (
int d = 0; d < 3; d++) {
64 _vel[i * 3 + d] = (double)0.0;
122#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
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;
170 std::cout <<
"ERROR NumericalSolver::setMDBoundary(): globalNumber "
183 bool isMDCell =
true;
184 for (
int d = 0; d < 3; d++) {
185 isMDCell = isMDCell && (globalCoords[d] >
_offset[d] + (int)overlapStrip - 1) &&
226 int globalDomainSize = floor((channelheight + 0.5) / dx);
227 return globalDomainSize / processes[d];
235#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
236 constexpr int dim = 3;
237 unsigned int rank = IDXS.getRank();
248#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
251 MPI_Comm_rank(coupling::indexing::IndexingService<3>::getInstance().getComm(), &rank);
252 MPI_Comm_size(coupling::indexing::IndexingService<3>::getInstance().getComm(), &size);
255 std::cout <<
"ERROR NumericalSolver::determineParallelNeighbours(): Not "
256 "enough ranks available!"
286#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
331 int globalDomainSize = floor((channelheight + 0.5) / dx);
333#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
335 MPI_Comm_rank(coupling::indexing::IndexingService<3>::getInstance().getComm(), &rank);
339 if ((
unsigned int)rank > processes[0] * processes[1] * processes[2] - 1) {
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];
349 if (coords[d] < processes[d] - 1) {
350 return globalDomainSize / processes[d];
353 return globalDomainSize / processes[d] + globalDomainSize % processes[d];
361#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
363 std::cout <<
"ERROR NumericalSolver::get(i): i<0!" << std::endl;
367 std::cout <<
"ERROR NumericalSolver::get(i): i>max. Value!" << std::endl;
376 int get(
int x,
int y,
int z)
const {
377#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
379 std::cout <<
"ERROR NumericalSolver::get(x,y,z): x<0!" << std::endl;
383 std::cout <<
"ERROR NumericalSolver::get(x,y,z): x>max. Value!" << std::endl;
387 std::cout <<
"ERROR NumericalSolver::get(x,y,z): y<0!" << std::endl;
391 std::cout <<
"ERROR NumericalSolver::get(x,y,z): y>max. Value!" << std::endl;
395 std::cout <<
"ERROR NumericalSolver::get(x,y,z): z<0!" << std::endl;
399 std::cout <<
"ERROR NumericalSolver::get(x,y,z): z>max. Value!" << std::endl;
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;
415 if (y < 0 || y > lengthy + 1) {
416 std::cout <<
"ERROR NumericalSolver::getParBuf(...): y out of range!" << std::endl;
420 return x + (lengthx + 2) * y;
425#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
426 MPI_Comm_rank(coupling::indexing::IndexingService<3>::getInstance().getComm(), &rank);
428 std::stringstream ss;
430 if (_scen !=
nullptr) {
431 auto ts = _scen->getTimeIntegrationService();
433 if (ts->isPintEnabled())
434 ss <<
"_i" << ts->getInteration();
442 void plot(std::string filename)
const {
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;
455 std::stringstream flag, density, velocity;
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;
465 flag <<
"SCALARS flag float 1" << std::endl;
466 flag <<
"LOOKUP_TABLE default" << std::endl;
468 density << std::setprecision(12);
469 density <<
"SCALARS density float 1 " << std::endl;
470 density <<
"LOOKUP_TABLE default" << std::endl;
472 velocity << std::setprecision(12);
473 velocity <<
"VECTORS velocity float" << std::endl;
487 const int index =
get(x, y, z);
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;
496 file << flag.str() << std::endl << std::endl;
498 file << density.str() << std::endl;
500 file << velocity.str() << std::endl;
511#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
512 MPI_Comm_rank(coupling::indexing::IndexingService<3>::getInstance().getComm(), &rank);
576#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
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
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