Line data Source code
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_NIEVELOCITYIMPOSITION_H_ 6 : #define _MOLECULARDYNAMICS_COUPLING_NIEVELOCITYIMPOSITION_H_ 7 : 8 : #include "coupling/MomentumInsertion.h" 9 : #include "coupling/cell-mappings/ComputeAvgForceAndVelocity.h" 10 : #include "coupling/cell-mappings/NieVelocityImpositionMapping.h" 11 : #include "coupling/interface/MDSolverInterface.h" 12 : 13 : namespace coupling { 14 : template <class LinkedCell, unsigned int dim> class NieVelocityImposition; 15 : } 16 : 17 : /** @brief Velocity imposition scheme following the respective paper by Nie et 18 : * al., J. Fluid. Mech. 500, 2004 19 : * @author Philipp Neumann 20 : * @tparam LinkedCell the LinkedCell class is given by the implementation of 21 : * linked cells in the molecular dynamics simulation 22 : * @tparam dim refers to the spacial dimension of the simulation, can be 1, 2, 23 : * or 3 24 : */ 25 : template <class LinkedCell, unsigned int dim> class coupling::NieVelocityImposition : public coupling::MomentumInsertion<LinkedCell, dim> { 26 : public: 27 : /** @brief a simple constructor 28 : * @param mdSolverInterface interface to the md solver 29 : * @param outermostLayer the index of the outermost cell layer 30 : * @param innermostLayer the index of the innermost cell layer 31 : * @param impositionEnabled whether imposition is allowed at the specified domain face */ 32 0 : NieVelocityImposition(coupling::interface::MDSolverInterface<LinkedCell, dim>* const mdSolverInterface, const unsigned int& outermostLayer, 33 : const unsigned int& innermostLayer, const tarch::la::Vector<2 * dim, bool> impositionEnabled) 34 0 : : coupling::MomentumInsertion<LinkedCell, dim>(mdSolverInterface), _outermostLayer(outermostLayer), _innermostLayer(innermostLayer), 35 0 : _impositionEnabled(impositionEnabled), _enableInnerImposition(false) {} 36 : 37 : /** @brief a simple destructor */ 38 0 : virtual ~NieVelocityImposition() {} 39 : 40 : /** @brief momentum shall be inserted in every md time step, so this returns 1 41 : * @returns the time step interval for momentum insertion, always 1 */ 42 0 : unsigned int getTimeIntervalPerMomentumInsertion() const override { return 1; } 43 : 44 : /** @brief inserts momentum to a cell 45 : * @param cell to the coupling cell will the momentum be inserted 46 : * @param idx local linearised index for the 47 : * coupling cell */ 48 0 : void insertMomentum(coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>& cell, I02 idx) const override { 49 : // nop if this is not an imposition cell 50 0 : if (!isInsideImpositionLayer(idx)) { 51 0 : return; 52 : } 53 : // set continuum velocity 54 0 : tarch::la::Vector<dim, double> continuumVelocity(cell.getMicroscopicMomentum()); 55 : 56 0 : coupling::cellmappings::ComputeAvgForceAndVelocity<LinkedCell, dim> computeForceAndVelocity( 57 0 : coupling::MomentumInsertion<LinkedCell, dim>::_mdSolverInterface); 58 0 : cell.iterateConstCells(computeForceAndVelocity); 59 0 : const tarch::la::Vector<dim, double> avgVel(computeForceAndVelocity.getAvgVelocity()); 60 0 : const tarch::la::Vector<dim, double> avgF(computeForceAndVelocity.getAvgForce()); 61 : 62 0 : coupling::cellmappings::NieVelocityImpositionMapping<LinkedCell, dim> velocityImposition(continuumVelocity, avgVel, avgF, 63 0 : coupling::MomentumInsertion<LinkedCell, dim>::_mdSolverInterface); 64 0 : cell.iterateCells(velocityImposition); 65 0 : } 66 : 67 0 : void setInnerImposition(bool enable) override { _enableInnerImposition = enable; } 68 : 69 : private: 70 : /** returns true if the local cell at index currentLocalCouplingCellIndex is 71 : * inside the layer of imposition cells, given by outermostLayer and 72 : * innermostLayer. For, e.g., outermostLayer=2 and innermostLayer=3, the 73 : * layers for imposition are located in the 3rd and 4th strip of cells (we 74 : * start counting from cell layer=0 which corresponds to the outermost, 75 : * actually ghost-layer of cells which surrounds the MD domain). 76 : * Also checks if imposition is enabled in that direction. 77 : * @brief based on the cell index, the function tells if the cell is inside 78 : * the imposition layer 79 : * @param globalCellIndex global linearised index of a coupling 80 : * cell to check 81 : * @returns a bool, that indicates if the given cell index is located in the 82 : * imposition layer (true) or not (false) */ 83 0 : bool isInsideImpositionLayer(I01 globalCellIndex) const { 84 0 : bool inner = true; 85 0 : bool outer = false; 86 0 : tarch::la::Vector<dim, unsigned int> globalIndexUnsigned{globalCellIndex.get()}; 87 0 : for (unsigned int d = 0; d < dim; d++) { 88 0 : if (_impositionEnabled[d * 2]) { // negative direction 89 0 : inner = inner && (globalIndexUnsigned[d] > _innermostLayer); 90 0 : outer = outer || (globalIndexUnsigned[d] < _outermostLayer); 91 : } 92 0 : if (_impositionEnabled[d * 2 + 1]) { // positive direction 93 0 : inner = inner && (globalIndexUnsigned[d] < 1 + I09::numberCellsInDomain[d] - _innermostLayer); 94 0 : outer = outer || (globalIndexUnsigned[d] > 1 + I09::numberCellsInDomain[d] - _outermostLayer); 95 : } 96 : } 97 0 : return (_enableInnerImposition || !inner) && !outer; 98 : } 99 : 100 : /** @brief the index of the outermost cell layer*/ 101 : const unsigned int _outermostLayer; 102 : /** @brief the index of the innermost cell layer*/ 103 : const unsigned int _innermostLayer; 104 : const tarch::la::Vector<2 * dim, bool> _impositionEnabled; 105 : bool _enableInnerImposition; 106 : }; 107 : 108 : #endif // _MOLECULARDYNAMICS_COUPLING_VELOCITYGRADIENTRELAXATION_H_