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_TRANSFERSTRATEGIES_AVERAGINGTRANSFERSTRATEGY_H_ 6 : #define _MOLECULARDYNAMICS_COUPLING_TRANSFERSTRATEGIES_AVERAGINGTRANSFERSTRATEGY_H_ 7 : 8 : #include "coupling/cell-mappings/ComputeMassMapping.h" 9 : #include "coupling/cell-mappings/ComputeMomentumMapping.h" 10 : #include "coupling/indexing/IndexingService.h" 11 : #include "coupling/transferstrategies/TransferStrategy.h" 12 : #include <list> 13 : #include <map> 14 : 15 : namespace coupling { 16 : /** transferstrategies define how the data will be applied, send, and received 17 : * @brief the namespace is used for transferstrategies */ 18 : namespace transferstrategies { 19 : template <class LinkedCell, unsigned int dim> class AveragingTransferStrategy; 20 : } 21 : } // namespace coupling 22 : 23 : /** this class is used for pure averaging operations on the coupling cells. 24 : * This can be used e.g. to measure errors in averaging over time, to estimate 25 : * number of samples etc. 26 : * @author Philipp Neumann 27 : * @tparam LinkedCell the LinkedCell class is given by the implementation of 28 : * linked cells in the molecular dynamics simulation 29 : * @tparam dim refers to the spacial dimension of the simulation, can be 1, 2, 30 : * or 3 */ 31 : template <class LinkedCell, unsigned int dim> 32 : class coupling::transferstrategies::AveragingTransferStrategy : public coupling::transferstrategies::TransferStrategy<LinkedCell, dim> { 33 : public: 34 : /** @brief a simple constructor 35 : * @param mdSolverInterface interface for the md solver*/ 36 0 : AveragingTransferStrategy(coupling::interface::MDSolverInterface<LinkedCell, dim>* const mdSolverInterface) 37 0 : : coupling::transferstrategies::TransferStrategy<LinkedCell, dim>(mdSolverInterface), _massMapping(mdSolverInterface), 38 0 : _momentumMapping(mdSolverInterface), _sampleCounter(0), _rank(IDXS.getRank()) {} 39 : 40 : /** @brief a dummy destructor */ 41 0 : virtual ~AveragingTransferStrategy() {} 42 : 43 : /** @brief reset the sample counter before processing any cell */ 44 0 : void beginProcessInnerCouplingCellsBeforeReceivingMacroscopicSolverData() override { 45 : // reset sample counter for each coupling cycle 46 0 : _sampleCounter = 0; 47 0 : } 48 : 49 : /** @brief macroscopicMass and -Momentum are reset before the data from the 50 : * macro solver is transferred 51 : * @param cell the coupling cell to process 52 : * @param index the index of the coupling cell */ 53 0 : void processInnerCouplingCellBeforeReceivingMacroscopicSolverData(coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>& cell, 54 : I02 index) override { 55 : // reset buffers for sampling mass and momentum in each inner coupling 56 : // cell 57 0 : cell.setMacroscopicMass(0.0); 58 0 : cell.setMacroscopicMomentum(tarch::la::Vector<dim, double>(0.0)); 59 0 : } 60 : 61 : /** @brief values are reseted before the cells are processes and on rank=0 62 : * info is written to the stdstream */ 63 0 : void beginProcessInnerCouplingCellsAfterMDTimestep() override { 64 : // output information of last sampling... 65 0 : if (_rank == 0) { 66 0 : std::cout << "Global quantities of sampling no. " << _sampleCounter << " on rank 0: mass=" << _avgMass << ", momentum=" << _avgMomentum << std::endl; 67 : } 68 : // reset avg. mass and momentum... 69 0 : _avgMass = 0.0; 70 0 : _avgMomentum = tarch::la::Vector<dim, double>(0.0); 71 : // and increment sample counter 72 0 : _sampleCounter++; 73 0 : } 74 : 75 : /** the macroscopicMass and -Momentum are averaged over all md time steps 76 : * @brief the averaging operation is applied to the cell 77 : * @param cell the coupling cell to process 78 : * @param index the index of the coupling cell */ 79 0 : void processInnerCouplingCellAfterMDTimestep(coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>& cell, I02 index) override { 80 : // compute total mass/momentum from previous samples 81 0 : const double oldMass = (_sampleCounter - 1) * cell.getMacroscopicMass(); 82 0 : const tarch::la::Vector<dim, double> oldMomentum = ((double)(_sampleCounter - 1)) * cell.getMacroscopicMomentum(); 83 : 84 : // compute new averaged mass and momentum 85 0 : cell.iterateConstCells(_massMapping); 86 0 : cell.iterateConstCells(_momentumMapping); 87 0 : const double mass = (1.0 / _sampleCounter) * (oldMass + _massMapping.getMass()); 88 0 : const tarch::la::Vector<dim, double> momentum = (1.0 / _sampleCounter) * (oldMomentum + _momentumMapping.getMomentum()); 89 0 : _avgMass += mass; 90 0 : _avgMomentum = _avgMomentum + momentum; 91 : // set mass and momentum in buffers 92 0 : cell.setMacroscopicMass(mass); 93 0 : cell.setMacroscopicMomentum(momentum); 94 0 : } 95 : 96 : private: 97 : /** necessary to compute the mass in the cells*/ 98 : coupling::cellmappings::ComputeMassMapping<LinkedCell, dim> _massMapping; 99 : /** necessary to compute the current momentum in the cell */ 100 : coupling::cellmappings::ComputeMomentumMapping<LinkedCell, dim> _momentumMapping; 101 : /** counter for the samples*/ 102 : unsigned int _sampleCounter; 103 : /** rank of the mpi process*/ 104 : const unsigned int _rank; 105 : /** the momentum of every cell is summed in this variable and divided by the 106 : * _sampleCounter so it holds the average momentum in the end */ 107 : tarch::la::Vector<dim, double> _avgMomentum; 108 : /** the mass of every cell is summed in this variable and divided by the 109 : * _sampleCounter so it holds the average mass in the end */ 110 : double _avgMass; 111 : }; 112 : #endif // _MOLECULARDYNAMICS_COUPLING_TRANSFERSTRATEGIES_AVERAGINGTRANSFERSTRATEGY_H_