MaMiCo 1.2
Loading...
Searching...
No Matches
FDCouetteSolver.h
1#ifndef _MOLECULARDYNAMICS_COUPLING_SOLVERS_FINITEDIFFERENCE_H_
2#define _MOLECULARDYNAMICS_COUPLING_SOLVERS_FINITEDIFFERENCE_H_
3
4#include "coupling/solvers/NumericalSolver.h"
5#include "tarch/la/Vector.h"
6#include <cmath>
7
8namespace coupling {
9namespace solvers {
11}
12} // namespace coupling
13
21public:
36 FiniteDifferenceSolver(const double channelheight, tarch::la::Vector<3, double> wallVelocity, const double kinVisc, const double dx, const double dt,
37 const int plotEveryTimestep, const std::string filestem, const tarch::la::Vector<3, unsigned int> processes,
38 const unsigned int numThreads = 1)
39 : coupling::solvers::NumericalSolver(channelheight, dx, dt, kinVisc, plotEveryTimestep, filestem, processes), _omega(dt * kinVisc / (dx * dx)),
40 _wallVelocity(wallVelocity) {
41 if (_processes[0] > 1 || _processes[1] > 1 || _processes[2] > 1) {
42 _processes[0] = 1;
43 _processes[1] = 1;
44 _processes[2] = 1;
45 std::cout << "The FiniteDifferenceSolver was requested in a parallel manner. It will be run sequentially, since it doesn't support parallel runs. "
46 << std::endl;
47 }
48 // return if required
49 if (skipRank()) {
50 return;
51 }
52 _velold = new double[3 * (_domainSizeX + 2) * (_domainSizeY + 2) * (_domainSizeZ + 2)];
53#if defined(_OPENMP)
54 omp_set_num_threads(numThreads);
55#endif
56#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
57 std::cout << "Domain size=" << _domainSizeX << "," << _domainSizeY << "," << _domainSizeZ << std::endl;
58 std::cout << "tau=" << 1.0 / _omega << std::endl;
59 std::cout << "wallVelocity=" << _wallVelocity << std::endl;
60 for (int z = 0; z < _domainSizeZ + 2; z++) {
61 for (int y = 0; y < _domainSizeY + 2; y++) {
62 for (int x = 0; x < _domainSizeX + 2; x++) {
63 std::cout << x << "," << y << "," << z << "FLAG=" << _flag[get(x, y, z)] << std::endl;
64 }
65 }
66 }
67#endif
68 // check pointers
69 if ((!_vel) || (!_density) || (!_flag)) {
70 std::cout << "ERROR FiniteDifferenceSolver: nullptr!" << std::endl;
71 exit(EXIT_FAILURE);
72 }
73 }
74
77 if (_velold) {
78 delete[] _velold;
79 _velold = nullptr;
80 }
81 }
82
85 void advance(double dt) override {
86 if (skipRank()) {
87 return;
88 }
89 const int timesteps = floor(dt / _dt + 0.5);
90 if (fabs(timesteps * _dt - dt) / _dt > 1.0e-8) {
91 std::cout << "ERROR FiniteDifferenceSolver::advance(): time steps and dt do not match!" << std::endl;
92 exit(EXIT_FAILURE);
93 }
94 for (int i = 0; i < timesteps; i++) {
96 update();
97 plot();
98 _counter++;
99 }
100 }
101
107#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
108 if ((pos[0] < domainOffset[0]) || (pos[0] > domainOffset[0] + _domainSizeX * _dx) || (pos[1] < domainOffset[1]) ||
109 (pos[1] > domainOffset[1] + _domainSizeY * _dx) || (pos[2] < domainOffset[2]) || (pos[2] > domainOffset[2] + _domainSizeZ * _dx)) {
110 std::cout << "ERROR FiniteDifferenceSolver::getVelocity(): Position " << pos << " out of range!" << std::endl;
111 exit(EXIT_FAILURE);
112 }
113#endif
114 // compute index for respective cell (_dx+... for ghost cells); use coords
115 // to store local cell coordinates
117 for (unsigned int d = 0; d < 3; d++) {
118 coords[d] = (unsigned int)((_dx + pos[d] - domainOffset[d]) / _dx);
119 }
120 const int index = get(coords[0], coords[1], coords[2]);
122 // extract velocity
123 for (int d = 0; d < 3; d++) {
124 vel[d] = _vel[3 * index + d];
125 }
126 return vel;
127 }
128
131 virtual void setWallVelocity(const tarch::la::Vector<3, double> wallVelocity) override { _wallVelocity = wallVelocity; }
132
136 double getDensity(tarch::la::Vector<3, double> pos) const override {
139#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
140 if ((pos[0] < domainOffset[0]) || (pos[0] > domainOffset[0] + _domainSizeX * _dx) || (pos[1] < domainOffset[1]) ||
141 (pos[1] > domainOffset[1] + _domainSizeY * _dx) || (pos[2] < domainOffset[2]) || (pos[2] > domainOffset[2] + _domainSizeZ * _dx)) {
142 std::cout << "ERROR FiniteDifferenceSolver::getDensity(): Position " << pos << " out of range!" << std::endl;
143 exit(EXIT_FAILURE);
144 }
145#endif
146 for (unsigned int d = 0; d < 3; d++) {
147 coords[d] = (unsigned int)((_dx + pos[d] - domainOffset[d]) / _dx);
148 }
149 const int index = get(coords[0], coords[1], coords[2]);
150 return _density[index];
151 }
152
158
160 if (skipRank()) {
161 return;
162 }
163#pragma omp parallel for
164 for (auto pair : md2macroBuffer) {
165 I01 idx;
167 std::tie(couplingCell, idx) = pair;
168 // determine cell index of this cell in continuum domain
169 tarch::la::Vector<3, unsigned int> globalCellCoords{I01{idx}.get()};
170 globalCellCoords[0] = (globalCellCoords[0] + _offset[0]) - _coords[0] * _avgDomainSizeX;
171 globalCellCoords[1] = (globalCellCoords[1] + _offset[1]) - _coords[1] * _avgDomainSizeY;
172 globalCellCoords[2] = (globalCellCoords[2] + _offset[2]) - _coords[2] * _avgDomainSizeZ;
173#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
174 std::cout << "Process coords: " << _coords << ": GlobalCellCoords for index ";
175 std::cout << I01{idx} << ": " << globalCellCoords << std::endl;
176#endif
177 const int index = get(globalCellCoords[0], globalCellCoords[1], globalCellCoords[2]);
178#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
179 if (_flag[index] != MD_BOUNDARY) {
180 std::cout << "ERROR FiniteDifferenceSolver::setMDBoundaryValues(): Cell " << index << " is no MD boundary cell!" << std::endl;
181 exit(EXIT_FAILURE);
182 }
183#endif
184 // set velocity value in MD boundary cell (before streaming); the boundary velocities are interpolated between the neighbouring and this cell. This
185 // interpolation is valid for FLUID-MD_BOUNDARY neighbouring relations only. determine local velocity received from MaMiCo and convert it to LB units;
186 // store the velocity in _vel
187 tarch::la::Vector<3, double> localVel((1.0 / couplingCell->getMacroscopicMass()) * couplingCell->getMacroscopicMomentum());
188 for (unsigned int d = 0; d < 3; d++) {
189 _vel[3 * index + d] = localVel[d];
190 }
191 }
192 }
193
194private:
201#pragma omp parallel for
202 for (int i = 0; i < _yO; i++) {
203 _vel[3 * i] = 2 * _wallVelocity[0] - _vel[3 * (i + _yO)];
204 }
205 }
206
208 void update() {
209 double* swap = _velold;
210 _velold = _vel;
211 _vel = swap;
212#pragma omp parallel for
213 for (int i = _yO; i < (_domainSizeX + 2) * (_domainSizeY + 2) * (_domainSizeZ + 2) - _yO; i++) {
214 if (_flag[i] == FLUID) {
215 _vel[3 * i] = _omega * (_velold[3 * (i - _yO)] - 2 * _velold[3 * i] + _velold[3 * (i + _yO)]) + _velold[3 * i];
216 }
217 }
218 }
219
221 const double _omega;
225 double* _velold{nullptr};
226};
227#endif
defines the cell type with cell-averaged quantities only (no linked cells).
Definition CouplingCell.h:29
const tarch::la::Vector< dim, double > & getMacroscopicMomentum() const
Definition CouplingCell.h:64
const double & getMacroscopicMass() const
Definition CouplingCell.h:58
provides access to coupling cells, which may belong to different indexing domains
Definition FlexibleCellContainer.h:30
implements a simple one-dimensional finite-diffference solver for the Couette flow.
Definition FDCouetteSolver.h:20
void setBeyondWall()
updates the velocities at boundaries
Definition FDCouetteSolver.h:200
virtual void setWallVelocity(const tarch::la::Vector< 3, double > wallVelocity) override
changes the velocity at the moving wall (z=0)
Definition FDCouetteSolver.h:131
double * _velold
the velocity field from the last time step
Definition FDCouetteSolver.h:225
const double _omega
factor for the finite difference stencil = dt*kinVisc/(dx*dx)
Definition FDCouetteSolver.h:221
void setMDBoundaryValues(coupling::datastructures::FlexibleCellContainer< 3 > &md2macroBuffer) override
applies the values received from the MD-solver within the conntinuum solver
Definition FDCouetteSolver.h:159
FiniteDifferenceSolver(const double channelheight, tarch::la::Vector< 3, double > wallVelocity, const double kinVisc, const double dx, const double dt, const int plotEveryTimestep, const std::string filestem, const tarch::la::Vector< 3, unsigned int > processes, const unsigned int numThreads=1)
a simple constructor
Definition FDCouetteSolver.h:36
tarch::la::Vector< 3, double > _wallVelocity
velocity of moving wall of Couette flow
Definition FDCouetteSolver.h:223
~FiniteDifferenceSolver()
a simple destructor
Definition FDCouetteSolver.h:76
void advance(double dt) override
advances one time step dt in time and triggers vtk plot if required
Definition FDCouetteSolver.h:85
tarch::la::Vector< 3, double > getVelocity(tarch::la::Vector< 3, double > pos) const override
gets the velocity at a given position
Definition FDCouetteSolver.h:105
void update()
update the velocity in the cells which are flagged as FLUID
Definition FDCouetteSolver.h:208
double getDensity(tarch::la::Vector< 3, double > pos) const override
returns density at a certain position
Definition FDCouetteSolver.h:136
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
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
const int _avgDomainSizeZ
avg. domain size in MPI-parallel simulation in z-direction
Definition NumericalSolver.h:564
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
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
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 > _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
@ MD_BOUNDARY
a cell on the boundary to md
Definition NumericalSolver.h:524
@ FLUID
a normal fluid cell
Definition NumericalSolver.h:520
double * _vel
velocity field
Definition NumericalSolver.h:571
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
tarch::la::Vector< 3, int > _offset
offset of the md domain
Definition NumericalSolver.h:597
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