MaMiCo 1.2
Loading...
Searching...
No Matches
VelocityGradientRelaxationMapping.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_CELLMAPPINGS_VELOCITYGRADIENTRELAXATIONMAPPING_H_
6#define _MOLECULARDYNAMICS_COUPLING_CELLMAPPINGS_VELOCITYGRADIENTRELAXATIONMAPPING_H_
7
8#include "coupling/CouplingMDDefinitions.h"
9#include "coupling/datastructures/CouplingCell.h"
10#include "coupling/indexing/IndexingService.h"
11#include "coupling/interface/MDSolverInterface.h"
12#include "coupling/interface/Molecule.h"
13#include "tarch/la/Matrix.h"
14#include <iostream>
15
16namespace coupling {
17namespace cellmappings {
18template <class LinkedCell, unsigned int dim> class VelocityGradientRelaxationMapping;
19template <class LinkedCell, unsigned int dim> class VelocityGradientRelaxationTopOnlyMapping;
20} // namespace cellmappings
21} // namespace coupling
22
38template <class LinkedCell, unsigned int dim> class coupling::cellmappings::VelocityGradientRelaxationMapping {
39public:
49 VelocityGradientRelaxationMapping(const double& velocityRelaxationFactor, const tarch::la::Vector<dim, double>& currentVelocity, const I02& cellIndex,
52 : _mdSolverInterface(mdSolverInterface), _couplingCells(couplingCells), _velocityRelaxationFactor(velocityRelaxationFactor),
54 _outerLowerLeft(getOuterLowerLeftCorner()), _outerUpperRight(getOuterUpperRightCorner()), _cellIdx(cellIndex),
55 _ignoreThisCell(ignoreThisCell(cellIndex)) {}
56
59
63
67
74 void handleCell(LinkedCell& cell) {
75 // if this coupling cell is not interesting, skip it immediately
76 if (_ignoreThisCell) {
77 return;
78 }
79
80 // std::cout << "Handle VelocityGradientRelaxation in cell " <<
81 // I03{_cellIdx}.get() << "=" << _cellIdx <<
82 // std::endl;
83 coupling::interface::MoleculeIterator<LinkedCell, dim>* it = _mdSolverInterface->getMoleculeIterator(cell);
84 it->begin();
85 while (it->continueIteration()) {
88 const tarch::la::Vector<dim, double> position(wrapper.getPosition());
89#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
90 std::cout << "VelocityGradientRelaxationMapping: Process cell " << _cellIdx << ", molecule " << position << std::endl;
91#endif
92 if (relaxMolecule(position)) {
93 tarch::la::Vector<dim, double> normalisedPosition(0.0);
94 bool secondCake = false;
95 // index of coupling cell values that are involved in interpolation
96 // process
97 I02 couplingCellIndex[10];
98 // determine cell indices and the "correct cake" for interpolation
99 createCouplingCellIndex4SecondOrderInterpolation(position, normalisedPosition, secondCake, couplingCellIndex);
100
101 tarch::la::Vector<dim, double> newVelocity(0.0);
102 tarch::la::Vector<dim, double> oldVelocity(0.0);
103
104 // get newVelocity (microscopicMomentum) with second-order interpolation
105 interpolateVelocitySecondOrder(couplingCellIndex, normalisedPosition, secondCake, newVelocity);
106 // get current velocity directly from coupling cell
107 oldVelocity = _couplingCells[_cellIdx.get()].getCurrentVelocity();
108
109 velocity += _velocityRelaxationFactor * (newVelocity - oldVelocity);
110 wrapper.setVelocity(velocity);
111
112#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
113 for (unsigned int d = 0; d < dim; d++) {
114 if (normalisedPosition[d] > 2.0) {
115 std::cout << "ERROR cellmappings::VelocityGradientRelaxationMapping: "
116 "normalisedPosition>2.0! "
117 << "Local vector index=" << I03{_cellIdx} << " , global vector index=" << I01{_cellIdx} << ", currentLocalCellIndex=" << _cellIdx
118 << ", Norm. position=" << normalisedPosition << ", Actual position=" << position << std::endl;
119 for (unsigned int i = 0; i < 10; i++) {
120 std::cout << couplingCellIndex[i] << " ";
121 }
122 std::cout << std::endl;
123 exit(EXIT_FAILURE);
124 }
125 if (normalisedPosition[d] < 0.0) {
126 std::cout << "ERROR cellmappings::VelocityGradientRelaxationMapping: "
127 "normalisedPosition<0.0! "
128 << I03{_cellIdx} << " ," << normalisedPosition << std::endl;
129 for (unsigned int i = 0; i < 10; i++) {
130 std::cout << couplingCellIndex[i] << " ";
131 }
132 std::cout << std::endl;
133 exit(EXIT_FAILURE);
134 }
135 }
136 if ((tarch::la::dot(newVelocity, newVelocity) > 1000.0) || (tarch::la::dot(oldVelocity, oldVelocity) > 1000.0)) {
137 for (unsigned int i = 0; i < 10; i++) {
138 std::cout << couplingCellIndex[i] << " ";
139 }
140 std::cout << std::endl;
141 std::cout << "ERROR: velocity to high! " << oldVelocity << " " << newVelocity << " " << I03{_cellIdx} << std::endl;
142 exit(EXIT_FAILURE);
143 }
144#endif
145 }
146 it->next();
147 }
148 delete it;
149 }
150
151protected:
158 virtual bool relaxMolecule(const tarch::la::Vector<dim, double>& position) const {
159 // check if molecule is in the respective boundary strip
160 bool isInsideOuter = true;
161 bool isOutsideInner = false;
162 for (unsigned int d = 0; d < dim; d++) {
163 isInsideOuter = isInsideOuter && (position[d] > _outerLowerLeft[d]) && (position[d] < _outerUpperRight[d]);
164 isOutsideInner = isOutsideInner || (position[d] < _innerLowerLeft[d]) || (position[d] > _innerUpperRight[d]);
165 }
166 return isInsideOuter && isOutsideInner;
167 }
168
174 bool ignoreThisCell(const I02& idx) const {
175 const tarch::la::Vector<dim, unsigned int> globalIndex{I01{idx}.get()};
176 bool innerCell = true;
177 for (unsigned int d = 0; d < dim; d++) {
178 innerCell = innerCell && ((globalIndex[d] > 2) && (globalIndex[d] < I01::numberCellsInDomain[d] - 3));
179 }
180 return innerCell;
181 }
182
189
192 const tarch::la::Vector<dim, double> _innerUpperRight;
193 const tarch::la::Vector<dim, double> _outerLowerLeft;
194 const tarch::la::Vector<dim, double> _outerUpperRight;
195
196 I02 _cellIdx;
199
200private:
204 tarch::la::Vector<dim, double> getInnerLowerLeftCorner() const { return IDXS.getGlobalMDDomainOffset() + 1.5 * IDXS.getCouplingCellSize(); }
209 return IDXS.getGlobalMDDomainOffset() + IDXS.getGlobalMDDomainSize() - 1.5 * IDXS.getCouplingCellSize();
210 }
211
214 tarch::la::Vector<dim, double> getOuterLowerLeftCorner() const { return IDXS.getGlobalMDDomainOffset() + 0.5 * IDXS.getCouplingCellSize(); }
219 return IDXS.getGlobalMDDomainOffset() + IDXS.getGlobalMDDomainSize() - 0.5 * IDXS.getCouplingCellSize();
220 }
221
229 bool& secondCake, I02* res) const {
230 // compute lower left cell index and normalised position;
231 // the normalised position is chosen such that the origin (0,0...,0)
232 // coincides with the lower left... coupling cell's midpoint
233
234 tarch::la::Vector<dim, double> cellMidpoint = _cellIdx.getCellMidPoint();
235 auto cellSize = IDXS.getCouplingCellSize();
236 tarch::la::Vector<dim, unsigned int> globalCellIndex{I01{_cellIdx}.get()};
237 tarch::la::Vector<dim, unsigned int> lowerLeftCellIndex{I03{_cellIdx}.get()};
238
239 // determine cell mid point and normalised position in this loop
240 for (unsigned int d = 0; d < dim; d++) {
241 // determine mid point of current coupling cell
242
243#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
244 if ((position[d] < cellMidpoint[d] - 0.5 * cellSize[d]) || (position[d] > cellMidpoint[d] + 0.5 * cellSize[d])) {
245 std::cout << "ERROR "
246 "VelocityGradientRelaxationMapping::"
247 "createCouplingCellIndex4SecondOrderInterpolation: "
248 "Input position "
249 << position;
250 std::cout << " out of range of cell " << globalCellIndex << "!" << std::endl;
251 exit(EXIT_FAILURE);
252 }
253#endif
254
255 // put lowerLeftCellIndex such that it's right below the position
256 if (position[d] < cellMidpoint[d]) {
257 lowerLeftCellIndex[d]--;
258 globalCellIndex[d]--;
259 }
260 // if this is on the left/ lower boundary, but still to far up, reduce
261 // height
262 if (lowerLeftCellIndex[d] == 1) {
263 lowerLeftCellIndex[d]--;
264 globalCellIndex[d]--;
265 } else if (lowerLeftCellIndex[d] == I03::numberCellsInDomain[d] - 2) {
266 lowerLeftCellIndex[d]--;
267 globalCellIndex[d]--;
268 }
269
270 // determine normalised position
271 normalisedPosition[d] = (position[d] - (IDXS.getGlobalMDDomainOffset()[d] - 0.5 * cellSize[d]) - globalCellIndex[d] * cellSize[d]) / cellSize[d];
272 }
273 unsigned int lowerLeftIndex = I02{I03{tarch::la::Vector<3, int>{lowerLeftCellIndex}}}.get();
274
275 if (dim == 2) {
276 std::cout << "Not implemented correctly yet!" << std::endl;
277 exit(EXIT_FAILURE);
278 } else if (dim == 3) {
279 const unsigned int localNumberCells01 = I03::numberCellsInDomain[0] * I03::numberCellsInDomain[1];
280 const unsigned int localNumber2Cells0 = 2 * I03::numberCellsInDomain[0];
281 const unsigned int localNumber2Cells01Plus2Cells0 = 2 * localNumberCells01 + 2 * I03::numberCellsInDomain[0];
282
284 normal[0] = 1.0;
285 normal[1] = 1.0;
286 normal[2] = 0.0;
287 tarch::la::Vector<dim, double> relPos(normalisedPosition);
288 relPos[0] -= 2.0;
289
290 // THE CAKE IS A LIE
291
292 // first cake:
293 if (tarch::la::dot(relPos, normal) < 0.0) {
294 secondCake = false;
295 res[0] = I02{lowerLeftIndex};
296 res[1] = I02{lowerLeftIndex + 1};
297 res[2] = I02{lowerLeftIndex + 2};
298 res[3] = I02{lowerLeftIndex + I03::numberCellsInDomain[0]};
299 res[4] = I02{lowerLeftIndex + localNumber2Cells0};
300 res[5] = I02{lowerLeftIndex + localNumberCells01};
301 res[6] = I02{lowerLeftIndex + localNumberCells01 + I03::numberCellsInDomain[0] + 1};
302 res[7] = I02{lowerLeftIndex + 2 * localNumberCells01};
303 res[8] = I02{lowerLeftIndex + 2 * localNumberCells01 + 2};
304 res[9] = I02{lowerLeftIndex + localNumber2Cells01Plus2Cells0};
305 // second cake
306 } else {
307 secondCake = true;
308 res[0] = I02{lowerLeftIndex + 2};
309 res[1] = I02{lowerLeftIndex + I03::numberCellsInDomain[0] + 2};
310 res[2] = I02{lowerLeftIndex + localNumber2Cells0};
311 res[3] = I02{lowerLeftIndex + localNumber2Cells0 + 1};
312 res[4] = I02{lowerLeftIndex + localNumber2Cells0 + 2};
313 res[5] = I02{lowerLeftIndex + localNumberCells01 + I03::numberCellsInDomain[0] + 1};
314 res[6] = I02{lowerLeftIndex + localNumberCells01 + 2 * I03::numberCellsInDomain[0] + 2};
315 res[7] = I02{lowerLeftIndex + 2 * localNumberCells01 + 2};
316 res[8] = I02{lowerLeftIndex + localNumber2Cells01Plus2Cells0};
317 res[9] = I02{lowerLeftIndex + localNumber2Cells01Plus2Cells0 + 2};
318 }
319 } else {
320 std::cout << "ERROR createCouplingCellIndex4Interpolation(position): "
321 "only 2D/3D supported!"
322 << std::endl;
323 exit(EXIT_FAILURE);
324 }
325 }
326
334 void interpolateVelocitySecondOrder(I02* cellIndex, const tarch::la::Vector<dim, double>& normalisedPosition, const bool& secondCake,
335 tarch::la::Vector<dim, double>& newVelocity) const {
336 if (dim == 2) {
337 // TODO
338 } else if (dim == 3) {
339 // compute interpolation coefficients
340 tarch::la::Vector<dim, double> coefficients[10];
342
343 // extract velocities from cells
344 for (int i = 0; i < 10; i++) {
345 velocity[i] = _couplingCells[cellIndex[i].get()].getMicroscopicMomentum();
346 }
347
348 if (secondCake) {
349 const tarch::la::Vector<dim, double> v78 = velocity[7] + velocity[8];
350 coefficients[0] =
351 2.0 * (velocity[0] + velocity[2] + velocity[9]) + 4.0 * (velocity[5] - velocity[1] - velocity[6] - velocity[3]) + 5.0 * velocity[4] - v78;
352 coefficients[1] =
353 0.5 * (v78 - velocity[0]) + 2.0 * (velocity[1] - velocity[2] - velocity[5] + velocity[6]) + 4.0 * velocity[3] - 3.5 * velocity[4] - velocity[9];
354 coefficients[2] =
355 2.0 * (velocity[3] - velocity[0] - velocity[5] + velocity[6]) + 4.0 * velocity[1] - 3.5 * velocity[4] + 0.5 * (v78 - velocity[2]) - velocity[9];
356 coefficients[3] = 0.5 * (v78 - velocity[0] - velocity[2] - velocity[4]) + 2.0 * velocity[6] - 1.5 * velocity[9];
357 coefficients[4] = 0.5 * (velocity[2] + velocity[4]) - velocity[3];
358 coefficients[5] = 0.5 * (velocity[0] + velocity[4]) - velocity[1];
359 coefficients[6] = 0.5 * (velocity[4] + velocity[9]) - velocity[6];
360 coefficients[7] =
361 0.25 * (velocity[0] + velocity[2] - v78) - velocity[1] - velocity[3] + 1.5 * velocity[4] + velocity[5] - velocity[6] + 0.5 * velocity[9];
362 coefficients[8] = 0.25 * (velocity[2] - velocity[4] - velocity[8] + velocity[9]);
363 coefficients[9] = 0.25 * (velocity[0] - velocity[4] - velocity[7] + velocity[9]);
364 } else {
365 const tarch::la::Vector<dim, double> minus15V0 = -1.5 * velocity[0];
366 coefficients[0] = velocity[0];
367 coefficients[1] = minus15V0 + 2.0 * velocity[1] - 0.5 * velocity[2];
368 coefficients[2] = minus15V0 + 2.0 * velocity[3] - 0.5 * velocity[4];
369 coefficients[3] = minus15V0 + 2.0 * velocity[5] - 0.5 * velocity[7];
370 coefficients[4] = 0.5 * (velocity[0] + velocity[2]) - velocity[1];
371 coefficients[5] = 0.5 * (velocity[0] + velocity[4]) - velocity[3];
372 coefficients[6] = 0.5 * (velocity[0] + velocity[7]) - velocity[5];
373 coefficients[7] = 1.5 * velocity[0] + velocity[6] - velocity[1] - velocity[3] - velocity[5] + 0.5 * velocity[7] +
374 0.25 * (velocity[2] + velocity[4] - velocity[8] - velocity[9]);
375 coefficients[8] = 0.25 * (velocity[0] - velocity[2] - velocity[7] + velocity[8]);
376 coefficients[9] = 0.25 * (velocity[0] - velocity[4] - velocity[7] + velocity[9]);
377 }
378
379 // evaluate polynomial
380 const tarch::la::Vector<dim, double> contribution0 =
381 normalisedPosition[0] *
382 (coefficients[1] + coefficients[4] * normalisedPosition[0] + coefficients[7] * normalisedPosition[1] + coefficients[8] * normalisedPosition[2]);
383 const tarch::la::Vector<dim, double> contribution1 =
384 normalisedPosition[1] * (coefficients[2] + coefficients[5] * normalisedPosition[1] + coefficients[9] * normalisedPosition[2]);
385 const tarch::la::Vector<dim, double> contribution2 = normalisedPosition[2] * (coefficients[3] + coefficients[6] * normalisedPosition[2]);
386
387 newVelocity = coefficients[0] + contribution0 + contribution1 + contribution2;
388 }
389 }
390};
391
405template <class LinkedCell, unsigned int dim>
407public:
423 VelocityGradientRelaxationTopOnlyMapping(const double& velocityRelaxationFactor, const tarch::la::Vector<dim, double>& currentVelocity, const I02& cellIndex,
426 : coupling::cellmappings::VelocityGradientRelaxationMapping<LinkedCell, dim>(velocityRelaxationFactor, currentVelocity, cellIndex, mdSolverInterface,
427 couplingCells) {
428
429 // the following snippet is basically a replacement of the method
430 // ignoreThisCell(). Since this function is called in the constructor of the
431 // based class, we cannot overwrite it; hence, we solve it by overwriting
432 // the respective variable from within this constructor (called after base
433 // object is constructed)
435 (I01{cellIndex}.get()[dim - 1] < (int)(I01::numberCellsInDomain[dim - 1]) - 3);
436 }
437
438protected:
445 virtual bool relaxMolecule(const tarch::la::Vector<dim, double>& position) const {
446 // check if molecule is in the respective boundary strip (only upper part is
447 // considered)
448 return (position[dim - 1] > coupling::cellmappings::VelocityGradientRelaxationMapping<LinkedCell, dim>::_innerUpperRight[dim - 1]) &&
449 (position[dim - 1] < coupling::cellmappings::VelocityGradientRelaxationMapping<LinkedCell, dim>::_outerUpperRight[dim - 1]);
450 }
451};
452
453#endif // _MOLECULARDYNAMICS_COUPLING_CELLMAPPINGS_VELOCITYGRADIENTRELAXATIONMAPPING_H_
This class relaxes velocities of molecules towards an interpolated avergaged velocity value.
Definition VelocityGradientRelaxationMapping.h:38
virtual ~VelocityGradientRelaxationMapping()
Definition VelocityGradientRelaxationMapping.h:58
bool _ignoreThisCell
Definition VelocityGradientRelaxationMapping.h:198
tarch::la::Vector< dim, double > getInnerLowerLeftCorner() const
Definition VelocityGradientRelaxationMapping.h:204
void endCellIteration()
Definition VelocityGradientRelaxationMapping.h:66
tarch::la::Vector< dim, double > getOuterUpperRightCorner() const
Definition VelocityGradientRelaxationMapping.h:218
VelocityGradientRelaxationMapping(const double &velocityRelaxationFactor, const tarch::la::Vector< dim, double > &currentVelocity, const I02 &cellIndex, coupling::interface::MDSolverInterface< LinkedCell, dim > *const mdSolverInterface, const coupling::datastructures::CouplingCellWithLinkedCells< LinkedCell, dim > *const couplingCells)
Definition VelocityGradientRelaxationMapping.h:49
void beginCellIteration()
Definition VelocityGradientRelaxationMapping.h:62
virtual bool relaxMolecule(const tarch::la::Vector< dim, double > &position) const
Definition VelocityGradientRelaxationMapping.h:158
const tarch::la::Vector< dim, double > _innerLowerLeft
Definition VelocityGradientRelaxationMapping.h:191
const double _velocityRelaxationFactor
Definition VelocityGradientRelaxationMapping.h:186
const tarch::la::Vector< dim, double > _currentVelocity
Definition VelocityGradientRelaxationMapping.h:188
void createCouplingCellIndex4SecondOrderInterpolation(const tarch::la::Vector< dim, double > &position, tarch::la::Vector< dim, double > &normalisedPosition, bool &secondCake, I02 *res) const
Definition VelocityGradientRelaxationMapping.h:228
void handleCell(LinkedCell &cell)
Definition VelocityGradientRelaxationMapping.h:74
bool ignoreThisCell(const I02 &idx) const
Definition VelocityGradientRelaxationMapping.h:174
tarch::la::Vector< dim, double > getInnerUpperRightCorner() const
Definition VelocityGradientRelaxationMapping.h:208
void interpolateVelocitySecondOrder(I02 *cellIndex, const tarch::la::Vector< dim, double > &normalisedPosition, const bool &secondCake, tarch::la::Vector< dim, double > &newVelocity) const
Definition VelocityGradientRelaxationMapping.h:334
tarch::la::Vector< dim, double > getOuterLowerLeftCorner() const
Definition VelocityGradientRelaxationMapping.h:214
This is the same as the class coupling::cellmappings::VelocityGradientRelaxationMapping,...
Definition VelocityGradientRelaxationMapping.h:406
virtual bool relaxMolecule(const tarch::la::Vector< dim, double > &position) const
Definition VelocityGradientRelaxationMapping.h:445
VelocityGradientRelaxationTopOnlyMapping(const double &velocityRelaxationFactor, const tarch::la::Vector< dim, double > &currentVelocity, const I02 &cellIndex, coupling::interface::MDSolverInterface< LinkedCell, dim > *const mdSolverInterface, const coupling::datastructures::CouplingCellWithLinkedCells< LinkedCell, dim > *const couplingCells)
Definition VelocityGradientRelaxationMapping.h:423
defines the cell type with cell-averaged quantities. Derived from the class coupling::datastructures:...
Definition CouplingCellWithLinkedCells.h:26
static tarch::la::Vector< dim, unsigned int > numberCellsInDomain
Definition CellIndex.h:264
value_T get() const
Definition CellIndex.h:138
interface to the MD simulation
Definition MDSolverInterface.h:25
some iterator scheme for traversing the molecules within a linked cell.
Definition MoleculeIterator.h:24
virtual bool continueIteration() const =0
virtual coupling::interface::Molecule< dim > & get()=0
interface to access a single molecule in the MD simulation.
Definition Molecule.h:23
virtual void setVelocity(const tarch::la::Vector< dim, double > &velocity)=0
virtual tarch::la::Vector< dim, double > getVelocity() const =0
virtual tarch::la::Vector< dim, double > getPosition() const =0
Definition Vector.h:24
everything necessary for coupling operations, is defined in here
Definition AdditiveMomentumInsertion.h:15