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_
|