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 400 : MomentumInsertionConfiguration() : _insertionType(ADDITIVE_MOMENTUM_INSERTION), _isValid(true) {} 50 : 51 : /** Destructor */ 52 404 : virtual ~MomentumInsertionConfiguration() {} 53 : 54 : /** parseSubtag 55 : * @param node 56 : */ 57 4 : void parseSubtag(tinyxml2::XMLElement* node) { 58 4 : std::string value; 59 8 : 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 48 : 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 : } else if (_insertionType == DIRECT_VELOCITY_INSERTION) { 169 0 : return new coupling::SetGivenVelocity4MomentumInsertion<LinkedCell, dim>(mdSolverInterface); 170 : } else if (_insertionType == VELOCITY_GRADIENT_RELAXATION) { 171 0 : return new coupling::VelocityGradientRelaxation<LinkedCell, dim>(_velocityRelaxationFactor, mdSolverInterface, couplingCells); 172 : } else if (_insertionType == NO_INSERTION) { 173 4 : return new coupling::NoMomentumInsertion<LinkedCell, dim>(mdSolverInterface); 174 : } else if (_insertionType == VELOCITY_GRADIENT_RELAXATION_TOPONLY) { 175 0 : return new coupling::VelocityGradientRelaxationTopOnly<LinkedCell, dim>(_velocityRelaxationFactor, mdSolverInterface, couplingCells); 176 : } 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_