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_CONFIGURATIONS_MOMENTUMINSERTIONCONFIGURATION_H_
6 : #define _MOLECULARDYNAMICS_COUPLING_CONFIGURATIONS_MOMENTUMINSERTIONCONFIGURATION_H_
7 :
8 : #include "coupling/AdditiveMomentumInsertion.h"
9 : #include "coupling/NieVelocityImposition.h"
10 : #include "coupling/NoMomentumInsertion.h"
11 : #include "coupling/SetGivenVelocity4MomentumInsertion.h"
12 : #include "coupling/VelocityGradientRelaxation.h"
13 : #include "tarch/configuration/Configuration.h"
14 : #include "tarch/configuration/ParseConfiguration.h"
15 : #include "tarch/la/Vector.h"
16 : #include <iostream>
17 :
18 : namespace coupling {
19 : namespace configurations {
20 : template <unsigned int dim> class MomentumInsertionConfiguration;
21 : }
22 : } // namespace coupling
23 :
24 : /** forward declaration for testing */
25 : class NieTest;
26 :
27 : /** momentum insertion configuration. friend class: NieTest
28 : * @brief momentum insertion configuration. friend class: NieTest
29 : * @author Philipp Neumann
30 : */
31 : template <unsigned int dim> class coupling::configurations::MomentumInsertionConfiguration : public tarch::configuration::Configuration {
32 : public:
33 : // for testing: give access to variables; will only be used in the read-sense
34 : friend class ::NieTest;
35 :
36 : /** momentum insertion types that are implemented.
37 : * @enum MomentumInsertionType
38 : */
39 : enum MomentumInsertionType {
40 : ADDITIVE_MOMENTUM_INSERTION = 0 /**< ADDITIVE_MOMENTUM_INSERTION*/,
41 : DIRECT_VELOCITY_INSERTION = 1 /**< DIRECT_VELOCITY_INSERTION*/,
42 : VELOCITY_GRADIENT_RELAXATION = 2 /**< VELOCITY_GRADIENT_RELAXATION*/,
43 : NO_INSERTION = 3 /**< NO_INSERTION*/,
44 : VELOCITY_GRADIENT_RELAXATION_TOPONLY = 4 /**< VELOCITY_GRADIENT_RELAXATION_TOPONLY*/,
45 : NIE_VELOCITY_IMPOSITION = 5 /**< NIE_VELOCITY_IMPOSITION*/
46 : };
47 :
48 : /** Constructor, initializes the class */
49 408 : MomentumInsertionConfiguration() : _insertionType(ADDITIVE_MOMENTUM_INSERTION), _isValid(true) {}
50 :
51 : /** Destructor */
52 412 : virtual ~MomentumInsertionConfiguration() {}
53 :
54 : /** parseSubtag
55 : * @param node
56 : */
57 4 : void parseSubtag(tinyxml2::XMLElement* node) {
58 4 : std::string value;
59 4 : tarch::configuration::ParseConfiguration::readStringMandatory(value, node, "type");
60 4 : if (value == "additive-momentum-insertion") {
61 0 : _insertionType = ADDITIVE_MOMENTUM_INSERTION;
62 4 : } else if (value == "direct-velocity-insertion") {
63 0 : _insertionType = DIRECT_VELOCITY_INSERTION;
64 4 : } else if (value == "velocity-gradient-relaxation") {
65 0 : _insertionType = VELOCITY_GRADIENT_RELAXATION;
66 4 : } else if (value == "none") {
67 0 : _insertionType = NO_INSERTION;
68 4 : } else if (value == "velocity-gradient-relaxation-top-only") {
69 0 : _insertionType = VELOCITY_GRADIENT_RELAXATION_TOPONLY;
70 4 : } else if (value == "nie-velocity-imposition") {
71 4 : _insertionType = NIE_VELOCITY_IMPOSITION;
72 : } else {
73 0 : std::cout << "ERROR coupling::MomentumInsertionConfiguration: Wrong "
74 : "insertion type!"
75 0 : << std::endl;
76 0 : _isValid = false;
77 0 : exit(EXIT_FAILURE);
78 : }
79 :
80 4 : if (_insertionType == VELOCITY_GRADIENT_RELAXATION) {
81 0 : tarch::configuration::ParseConfiguration::readDoubleMandatory(_velocityRelaxationFactor, node, "velocity-relaxation-factor");
82 0 : if ((_velocityRelaxationFactor <= 0.0) || (_velocityRelaxationFactor > 1.0)) {
83 0 : std::cout << "ERROR coupling::MomentumInsertionConfiguration: "
84 : "velocity-relaxation-factor="
85 0 : << _velocityRelaxationFactor << "!";
86 0 : std::cout << " It must be in the range (0.0,1.0]!" << std::endl;
87 0 : _isValid = false;
88 0 : exit(EXIT_FAILURE);
89 : }
90 4 : } else if (_insertionType == VELOCITY_GRADIENT_RELAXATION_TOPONLY) {
91 0 : tarch::configuration::ParseConfiguration::readDoubleMandatory(_velocityRelaxationFactor, node, "velocity-relaxation-factor");
92 0 : if ((_velocityRelaxationFactor <= 0.0) || (_velocityRelaxationFactor > 1.0)) {
93 0 : std::cout << "ERROR coupling::MomentumInsertionConfiguration: "
94 : "velocity-relaxation-factor="
95 0 : << _velocityRelaxationFactor << "!";
96 0 : std::cout << " It must be in the range (0.0,1.0]!" << std::endl;
97 0 : _isValid = false;
98 0 : exit(EXIT_FAILURE);
99 : }
100 4 : } else if (_insertionType == NIE_VELOCITY_IMPOSITION) {
101 : int buf;
102 4 : tarch::configuration::ParseConfiguration::readIntMandatory(buf, node, "innermost-overlap-layer");
103 4 : if (buf <= 0) {
104 0 : std::cout << "ERROR coupling::MomentumInsertionConfiguration: "
105 : "innermost-overlap-layer="
106 0 : << buf << "!" << std::endl;
107 0 : _isValid = false;
108 0 : exit(EXIT_FAILURE);
109 : }
110 4 : _innerOverlap = (unsigned int)buf;
111 4 : tarch::configuration::ParseConfiguration::readIntMandatory(buf, node, "outermost-overlap-layer");
112 4 : if (((unsigned int)buf > _innerOverlap) || (buf <= 0)) {
113 0 : std::cout << "ERROR coupling::MomentumInsertionConfiguration: "
114 : "outermost-overlap-layer="
115 0 : << buf << "!" << std::endl;
116 0 : _isValid = false;
117 0 : exit(EXIT_FAILURE);
118 : }
119 4 : _outerOverlap = (unsigned int)buf;
120 28 : const std::string boundaries[6] = {"west", "east", "south", "north", "bottom", "top"}; // TODO change to +-xyz
121 28 : for (unsigned int d = 0; d < 2 * dim; d++) {
122 24 : _impositionEnabled[d] = true;
123 72 : tarch::configuration::ParseConfiguration::readBoolOptional(_impositionEnabled[d], node, boundaries[d]);
124 : }
125 28 : }
126 4 : }
127 :
128 : /** Returns name of xml tag that is associated to the configuration.
129 : * @return name of xml tag that is associated to the configuration
130 : */
131 20 : std::string getTag() const { return "momentum-insertion"; }
132 :
133 : /** checks if the configuration is valid. This operation usually fails, if
134 : *e.g.
135 : * 1. parseSubtag() hasn't been called, i.e. configuration has not been
136 : *used, or
137 : * 2. parseSubtag() failed due to a wrong file.
138 : * 3. If a tag ain't optional and parseSubtag() was not called (first case)
139 : * @return _isValid
140 : */
141 4 : bool isValid() const { return _isValid; }
142 :
143 : /** Returns momentum insertion type.
144 : * @return _insertionType
145 : */
146 4 : const MomentumInsertionType& getMomentumInsertionType() const { return _insertionType; }
147 :
148 : /**
149 : * @return _innerOverlap
150 : */
151 : unsigned int getInnerOverlap() const { return _innerOverlap; }
152 :
153 : /** Returns momentum insertion configuration.
154 : * @tparam LinkedCell type of the cell
155 : * @tparam dim Number of dimensions; it can be 1, 2 or 3
156 : * @param mdSolverInterface
157 : * @param couplingCells
158 : * @param numberMDTimestepsPerCouplingCycle
159 : * @return momentum insertion config
160 : */
161 : template <class LinkedCell>
162 : coupling::MomentumInsertion<LinkedCell, dim>*
163 4 : interpreteConfiguration(coupling::interface::MDSolverInterface<LinkedCell, dim>* const mdSolverInterface,
164 : const coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>* const couplingCells,
165 : unsigned int numberMDTimestepsPerCouplingCycle) const {
166 4 : if (_insertionType == ADDITIVE_MOMENTUM_INSERTION) {
167 0 : return new coupling::AdditiveMomentumInsertion<LinkedCell, dim>(mdSolverInterface, numberMDTimestepsPerCouplingCycle);
168 4 : } else if (_insertionType == DIRECT_VELOCITY_INSERTION) {
169 0 : return new coupling::SetGivenVelocity4MomentumInsertion<LinkedCell, dim>(mdSolverInterface);
170 4 : } else if (_insertionType == VELOCITY_GRADIENT_RELAXATION) {
171 0 : return new coupling::VelocityGradientRelaxation<LinkedCell, dim>(_velocityRelaxationFactor, mdSolverInterface, couplingCells);
172 4 : } else if (_insertionType == NO_INSERTION) {
173 4 : return new coupling::NoMomentumInsertion<LinkedCell, dim>(mdSolverInterface);
174 0 : } else if (_insertionType == VELOCITY_GRADIENT_RELAXATION_TOPONLY) {
175 0 : return new coupling::VelocityGradientRelaxationTopOnly<LinkedCell, dim>(_velocityRelaxationFactor, mdSolverInterface, couplingCells);
176 0 : } else if (_insertionType == NIE_VELOCITY_IMPOSITION) {
177 0 : return new coupling::NieVelocityImposition<LinkedCell, dim>(mdSolverInterface, _outerOverlap, _innerOverlap, _impositionEnabled);
178 : }
179 : return NULL;
180 : }
181 :
182 : protected:
183 4 : MomentumInsertionConfiguration(MomentumInsertionType insertionType) : _insertionType(insertionType), _isValid(true) {}
184 :
185 : private:
186 : MomentumInsertionType _insertionType;
187 : double _velocityRelaxationFactor; // required by velocity relaxation schemes
188 : unsigned int _innerOverlap; // innermost layer of overlap cells (required by
189 : // nie velocity imposition)
190 : unsigned int _outerOverlap; // outermost layer of overlap cells (required by
191 : // nie velocity imposition)
192 : tarch::la::Vector<2 * dim, bool> _impositionEnabled; // true in each component, if one of the 2*dim
193 : // boundaries allows for velocity imposition (currently only used for nie)
194 : bool _isValid;
195 : };
196 :
197 : #endif // _MOLECULARDYNAMICS_COUPLING_CONFIGURATIONS_MOMENTUMINSERTIONCONFIGURATION_H_
|