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_SENDRECV_DATAEXCHANGEFROMMD2MACRO_H_ 6 : #define _MOLECULARDYNAMICS_COUPLING_SENDRECV_DATAEXCHANGEFROMMD2MACRO_H_ 7 : 8 : #include "coupling/CouplingMDDefinitions.h" 9 : #include "coupling/datastructures/CouplingCell.h" 10 : #include "coupling/indexing/IndexingService.h" 11 : #include "coupling/interface/MacroscopicSolverInterface.h" 12 : #include "coupling/sendrecv/DataExchange.h" 13 : 14 : namespace coupling { 15 : namespace sendrecv { 16 : template <unsigned int dim> class DataExchangeFromMD2Macro; 17 : } 18 : } // namespace coupling 19 : 20 : /** data exchange from MD, that is the coupling tool, to the macroscopic solver. 21 : *We transfer the buffers macroscopicMass and macroscopicMomentum of the 22 : *CouplingCell. The target ranks are determined by the getRanks()-method of 23 : *the macroscopic solver interface: the macroscopic solver interface thus needs 24 : *to know on which ranks information from the MD simulation are required as 25 : *input. The source ranks arise from the unique rank determination within the 26 : *IndexConversion. We only allow transfer of non-ghost coupling cells to the 27 : *macroscopic solver, i.e. cells which are completely embedded into the MD 28 : *domain. 29 : * @brief data exchange from the MD solver to the macroscopic solver. 30 : *Derived from the class coupling::sendrecv::DataExchange 31 : * @tparam dim Number of dimensions; it can be 1, 2 or 3 32 : * @sa DataExchangeFromMacro2MD 33 : * @author Philipp Neumann 34 : */ 35 : template <unsigned int dim> 36 : class coupling::sendrecv::DataExchangeFromMD2Macro : public coupling::sendrecv::DataExchange<coupling::datastructures::CouplingCell<dim>, dim> { 37 : 38 : public: 39 : /** Constructor 40 : * @param interface macroscopic solver interface 41 : * @param tagoffset 0 per default 42 : */ 43 4 : DataExchangeFromMD2Macro(coupling::interface::MacroscopicSolverInterface<dim>* interface, unsigned int topologyOffset, unsigned int tagoffset = 0) 44 4 : : coupling::sendrecv::DataExchange<coupling::datastructures::CouplingCell<dim>, dim>(TAG_FROM_MD2MACRO + tagoffset), _msi(interface), 45 4 : _topologyOffset(topologyOffset) { 46 : #if (COUPLING_MD_DEBUG == COUPLING_MD_YES) 47 : std::cout << "DataExchangeFromMD2Macro initialised..." << std::endl; 48 : #endif 49 : } 50 : /** Destructor */ 51 0 : virtual ~DataExchangeFromMD2Macro() {} 52 : 53 : /** returns the ranks to which a particular cell (at index idx) 54 : *should be sent. 55 : * @param idx 56 : * @return the corresponding ranks via IndexConversion, if we need 57 : *information on MD side, otherwise empty vector 58 : */ 59 0 : std::vector<unsigned int> getTargetRanks(I01 idx) override { 60 : // if we need information on macroscopic solver side, return the respective 61 : // ranks via interface 62 0 : if (I12::contains(idx)) { 63 0 : return _msi->getTargetRanks(idx); 64 : // otherwise return empty vector 65 : } else { 66 0 : return std::vector<unsigned int>(); 67 : } 68 : } 69 : 70 : /** returns all ranks from which a particular cell (at index idx) 71 : *is sent. 72 : * @param idx 73 : * @return the corresponding ranks via MacroscopicSolverInterface, if we 74 : *need information on MD side, otherwise empty vector 75 : */ 76 0 : std::vector<unsigned int> getSourceRanks(I01 idx) override { 77 0 : std::vector<unsigned int> sourceRanks; 78 0 : if (I12::contains(idx)) { 79 0 : sourceRanks.push_back(IDXS.getUniqueRankForCouplingCell(idx, _topologyOffset)); 80 : } 81 0 : return sourceRanks; 82 0 : } 83 : 84 : /** local rule to read from coupling cell and write data to (e.g. send) 85 : * buffer. We only send the macroscopic mass and macroscopic momentum from MD 86 : * to the macroscopic solver. 87 : * @param buffer 88 : * @param cell 89 : */ 90 0 : void readFromCell(double* const buffer, const coupling::datastructures::CouplingCell<dim>& cell) override { 91 0 : buffer[0] = cell.getMacroscopicMass(); 92 0 : for (unsigned int d = 0; d < dim; d++) { 93 0 : buffer[d + 1] = cell.getMacroscopicMomentum()[d]; 94 : } 95 0 : } 96 : 97 : /** local rule to read from receive buffer and write data to coupling cell 98 : * @param buffer 99 : * @param cell 100 : */ 101 0 : void writeToCell(const double* const buffer, coupling::datastructures::CouplingCell<dim>& cell) override { 102 0 : tarch::la::Vector<dim, double> macroscopicMomentum(0.0); 103 0 : for (unsigned int d = 0; d < dim; d++) { 104 0 : macroscopicMomentum[d] = buffer[1 + d]; 105 : } 106 0 : cell.setMacroscopicMomentum(macroscopicMomentum); 107 0 : cell.setMacroscopicMass(buffer[0]); 108 0 : } 109 : 110 : /** returns the number of doubles that are sent per coupling cell. @return 111 : * 1+dim */ 112 0 : unsigned int getDoublesPerCell() const override { 113 : // 1 double: macroscopic mass; dim doubles: macroscopic momentum 114 0 : return 1 + dim; 115 : } 116 : 117 : private: 118 : coupling::interface::MacroscopicSolverInterface<dim>* _msi; 119 : unsigned int _topologyOffset; 120 : }; 121 : #endif // _MOLECULARDYNAMICS_COUPLING_SENDRECV_DATAEXCHANGEFROMMD2MACRO_H_