Line data Source code
1 : // Copyright (C) 2016 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 _COUETTECONFIG_H_
6 : #define _COUETTECONFIG_H_
7 :
8 : #include "tarch/configuration/ParseConfiguration.h"
9 : #include "tarch/la/Vector.h"
10 :
11 : using tarch::configuration::ParseConfiguration;
12 :
13 : namespace coupling {
14 : namespace configurations {
15 :
16 : struct CouetteConfig;
17 : }
18 : } // namespace coupling
19 : /** Configuration parameters for Couette flow scenario
20 : * @brief Configuration parameters for Couette flow scenario
21 : *
22 : *
23 : * @author Niklas Wittmer
24 : */
25 4 : struct coupling::configurations::CouetteConfig {
26 :
27 : private:
28 : // CouetteConfig(){}
29 :
30 : public:
31 : /** Defines the type of continuum solver for the coupled simulation */
32 : enum MacroSolverType {
33 : COUETTE_ANALYTICAL = 0, ///< the analytical couette solver is used
34 : ///< (coupling::solvers::CouetteSolver)
35 : COUETTE_LB = 1, ///< the Lattice-Bolzmann solver is used
36 : ///< (coupling::solvers::LBCouetteSolver)
37 : COUETTE_FD = 2, ///< the 1d finite-difference solver is used
38 : ///< (coupling::solvers::FiniteDifferenceSolver)
39 : COUETTE_FOAM = 3 ///< the IcoFoam solver is used (coupling::solvers::IcoFoam)
40 : };
41 : /** Defines the type of md solver for the coupled simulation */
42 : enum MicroSolverType {
43 : SIMPLEMD = 0, ///< the SimpleMD solver is used
44 : SYNTHETIC = 1, ///< the synthetic solver is used
45 : LS1 = 2 ///< the LS1 solver is used
46 : };
47 :
48 : /** @brief creates CouetteConfig if all elements exist and can be read
49 : * @param filename
50 : */
51 4 : static CouetteConfig parseCouetteConfiguration(const std::string& filename) {
52 4 : CouetteConfig cfg;
53 :
54 4 : ParseConfiguration::XMLConfiguration xmlConfig = ParseConfiguration::XMLConfiguration::load(filename);
55 4 : tinyxml2::XMLElement* node = xmlConfig.root->FirstChildElement("couette-test");
56 :
57 4 : if (node == NULL) {
58 0 : std::cout << "Could not read input file " << filename
59 : << ": missing element "
60 0 : "<couette-test>"
61 0 : << std::endl;
62 0 : exit(EXIT_FAILURE);
63 : }
64 :
65 4 : tinyxml2::XMLElement* n_mamico = node->NextSiblingElement();
66 4 : if (n_mamico == NULL) {
67 0 : std::cout << "Could not read input file " << filename << ": missing element <mamico>" << std::endl;
68 0 : exit(EXIT_FAILURE);
69 : }
70 4 : tinyxml2::XMLElement* n_md = n_mamico->NextSiblingElement();
71 4 : if (n_md == NULL) {
72 0 : std::cout << "Could not read input file " << filename
73 : << ": missing element "
74 0 : "<molecular-dynamics>"
75 0 : << std::endl;
76 0 : exit(EXIT_FAILURE);
77 : }
78 4 : tinyxml2::XMLElement* n_fp = n_md->NextSiblingElement();
79 4 : if (n_fp == NULL) {
80 0 : std::cout << "Could not read input file " << filename
81 : << ": missing element "
82 0 : "<filter-pipeline>"
83 0 : << std::endl;
84 0 : exit(EXIT_FAILURE);
85 : }
86 4 : tinyxml2::XMLElement* n_unexpected = n_fp->NextSiblingElement();
87 4 : if (n_unexpected != NULL) {
88 0 : std::cout << "Could not read input file " << filename << ": unknown element " << n_unexpected->Name() << std::endl;
89 0 : exit(EXIT_FAILURE);
90 : }
91 :
92 4 : tinyxml2::XMLElement* subtag = node->FirstChildElement("domain");
93 4 : if (subtag == NULL) {
94 0 : std::cout << "Could not read input file " << filename << ": Missing subtag: domain" << std::endl;
95 0 : exit(EXIT_FAILURE);
96 : }
97 4 : tarch::configuration::ParseConfiguration::readDoubleMandatory(cfg.channelheight, subtag, "channelheight");
98 4 : tarch::configuration::ParseConfiguration::readVectorMandatory<3, double>(cfg.wallVelocity, subtag, "wall-velocity");
99 4 : cfg.wallInitCycles = 0;
100 4 : tarch::configuration::ParseConfiguration::readIntOptional(cfg.wallInitCycles, subtag, "wall-init-cycles");
101 4 : if (cfg.wallInitCycles > 0)
102 0 : tarch::configuration::ParseConfiguration::readVectorMandatory<3, double>(cfg.wallInitVelocity, subtag, "wall-init-velocity");
103 4 : cfg.wallOscillations = 0;
104 4 : tarch::configuration::ParseConfiguration::readDoubleOptional(cfg.wallOscillations, subtag, "wall-oscillations");
105 :
106 4 : subtag = node->FirstChildElement("coupling");
107 4 : if (subtag == NULL) {
108 0 : std::cout << "Could not read input file couette.xml: Missing subtag: coupling" << std::endl;
109 0 : exit(EXIT_FAILURE);
110 : }
111 4 : tarch::configuration::ParseConfiguration::readIntMandatory(cfg.couplingCycles, subtag, "coupling-cycles");
112 4 : tarch::configuration::ParseConfiguration::readBoolMandatory(cfg.twoWayCoupling, subtag, "two-way-coupling");
113 4 : tarch::configuration::ParseConfiguration::readBoolMandatory(cfg.md2Macro, subtag, "send-from-md-to-macro");
114 4 : tarch::configuration::ParseConfiguration::readBoolMandatory(cfg.macro2Md, subtag, "send-from-macro-to-md");
115 4 : tarch::configuration::ParseConfiguration::readIntMandatory(cfg.filterInitCycles, subtag, "filter-init-cycles");
116 4 : tarch::configuration::ParseConfiguration::readIntMandatory(cfg.csvEveryTimestep, subtag, "write-csv-every-timestep");
117 4 : tarch::configuration::ParseConfiguration::readBoolMandatory(cfg.computeSNR, subtag, "compute-snr");
118 :
119 4 : subtag = node->FirstChildElement("microscopic-solver");
120 4 : if (subtag == NULL) {
121 0 : std::cout << "Could not read input file " << filename
122 : << ": Missing subtag: "
123 0 : "microscopic-solver"
124 0 : << std::endl;
125 0 : exit(EXIT_FAILURE);
126 : }
127 4 : std::string type;
128 4 : tarch::configuration::ParseConfiguration::readStringMandatory(type, subtag, "type");
129 4 : if (type == "md") {
130 4 : cfg.miSolverType = SIMPLEMD;
131 4 : tarch::configuration::ParseConfiguration::readDoubleMandatory(cfg.temp, subtag, "temperature");
132 4 : tarch::configuration::ParseConfiguration::readIntMandatory(cfg.equSteps, subtag, "equilibration-steps");
133 :
134 4 : std::string num_MD;
135 4 : tarch::configuration::ParseConfiguration::readStringMandatory(num_MD, subtag, "number-md-simulations");
136 4 : if (num_MD == "dynamic") {
137 0 : cfg.totalNumberMDSimulations = -1;
138 0 : cfg.lowerBoundNumberMDSimulations = 1;
139 0 : tarch::configuration::ParseConfiguration::readIntOptional(cfg.lowerBoundNumberMDSimulations, subtag, "min-number-md");
140 0 : tarch::configuration::ParseConfiguration::readDoubleMandatory(cfg.absVelErrStart, subtag, "error-start");
141 0 : tarch::configuration::ParseConfiguration::readDoubleMandatory(cfg.absVelErrEnd, subtag, "error-end");
142 : } else {
143 4 : tarch::configuration::ParseConfiguration::readIntMandatory(cfg.totalNumberMDSimulations, subtag, "number-md-simulations");
144 4 : if (cfg.totalNumberMDSimulations < 1) {
145 0 : std::cout << "Could not read input file " << filename
146 : << ": "
147 0 : "number-md-simulations < 1"
148 0 : << std::endl;
149 0 : exit(EXIT_FAILURE);
150 : }
151 : }
152 4 : } else if (type == "synthetic") {
153 0 : cfg.miSolverType = SYNTHETIC;
154 0 : tarch::configuration::ParseConfiguration::readDoubleMandatory(cfg.noiseSigma, subtag, "noise-sigma");
155 0 : cfg.totalNumberMDSimulations = 1;
156 0 : tarch::configuration::ParseConfiguration::readIntOptional(cfg.totalNumberMDSimulations, subtag, "number-md-simulations");
157 0 : } else if (type == "ls1") {
158 0 : cfg.miSolverType = LS1;
159 :
160 0 : cfg.totalNumberMDSimulations = 1;
161 0 : tarch::configuration::ParseConfiguration::readDoubleMandatory(cfg.temp, subtag, "temperature");
162 0 : tarch::configuration::ParseConfiguration::readIntMandatory(cfg.equSteps, subtag, "equilibration-steps");
163 0 : tarch::configuration::ParseConfiguration::readIntOptional(cfg.totalNumberMDSimulations, subtag, "number-md-simulations");
164 : } else {
165 0 : std::cout << "Could not read input file " << filename
166 : << ": Unknown microscopic "
167 0 : "solver type!"
168 0 : << std::endl;
169 0 : exit(EXIT_FAILURE);
170 : }
171 4 : tarch::configuration::ParseConfiguration::readDoubleMandatory(cfg.density, subtag, "density");
172 :
173 4 : subtag = node->FirstChildElement("macroscopic-solver");
174 4 : if (subtag == NULL) {
175 0 : std::cout << "Could not read input file " << filename
176 : << ": Missing subtag: "
177 0 : "macroscopic-solver"
178 0 : << std::endl;
179 0 : exit(EXIT_FAILURE);
180 : }
181 20 : cfg.lbNumberProcesses = tarch::la::Vector<3, unsigned int>(1);
182 4 : tarch::configuration::ParseConfiguration::readStringMandatory(type, subtag, "type");
183 4 : if (type == "lb") {
184 0 : cfg.maSolverType = COUETTE_LB;
185 0 : tarch::configuration::ParseConfiguration::readVectorMandatory<3, unsigned int>(cfg.lbNumberProcesses, subtag, "number-of-processes");
186 0 : tarch::configuration::ParseConfiguration::readIntMandatory(cfg.plotEveryTimestep, subtag, "plot-every-timestep");
187 0 : cfg.plotAverageVelocity = false;
188 0 : tarch::configuration::ParseConfiguration::readBoolOptional(cfg.plotAverageVelocity, subtag, "plot-average-velocity");
189 4 : } else if (type == "fd") {
190 4 : cfg.maSolverType = COUETTE_FD;
191 4 : tarch::configuration::ParseConfiguration::readVectorMandatory<3, unsigned int>(cfg.lbNumberProcesses, subtag, "number-of-processes");
192 8 : tarch::configuration::ParseConfiguration::readIntMandatory(cfg.plotEveryTimestep, subtag, "plot-every-timestep");
193 : }
194 : #if (BUILD_WITH_OPENFOAM)
195 : else if (type == "foam") {
196 : cfg.maSolverType = COUETTE_FOAM;
197 : tarch::configuration::ParseConfiguration::readIntMandatory(cfg.plotEveryTimestep, subtag, "plot-every-timestep");
198 : tarch::configuration::ParseConfiguration::readStringMandatory(cfg.foam.directory, subtag, "foam-setup-directory");
199 : tarch::configuration::ParseConfiguration::readStringMandatory(cfg.foam.folder, subtag, "foam-setup-folder");
200 : tarch::configuration::ParseConfiguration::readVectorMandatory<12, unsigned int>(cfg.foam.boundariesWithMD, subtag, "boundaries-with-MD");
201 : }
202 : #endif
203 0 : else if (type == "analytical") {
204 0 : cfg.maSolverType = COUETTE_ANALYTICAL;
205 0 : if (!(cfg.wallVelocity[1] == 0.0 && cfg.wallVelocity[2] == 0.0)) {
206 0 : std::cout << "analytic solver only supports flow in x-direction" << std::endl;
207 0 : exit(EXIT_FAILURE);
208 : }
209 : } else {
210 0 : std::cout << "Could not read input file " << filename
211 : << ": Unknown macroscopic "
212 0 : "solver type!"
213 0 : << std::endl;
214 0 : exit(EXIT_FAILURE);
215 : }
216 4 : double vis;
217 4 : tarch::configuration::ParseConfiguration::readDoubleMandatory(vis, subtag, "viscosity");
218 4 : cfg.kinVisc = vis / cfg.density;
219 4 : tarch::configuration::ParseConfiguration::readIntMandatory(cfg.initAdvanceCycles, subtag, "init-advance-cycles");
220 :
221 4 : subtag = node->FirstChildElement("tws-loop");
222 4 : if (subtag == NULL)
223 4 : cfg.twsLoop = false;
224 : else {
225 0 : cfg.twsLoop = true;
226 0 : tarch::configuration::ParseConfiguration::readIntMandatory(cfg.twsLoopMin, subtag, "min");
227 0 : tarch::configuration::ParseConfiguration::readIntMandatory(cfg.twsLoopMax, subtag, "max");
228 0 : cfg.twsLoopStep = 1;
229 0 : tarch::configuration::ParseConfiguration::readIntOptional(cfg.twsLoopStep, subtag, "step");
230 : }
231 :
232 4 : if (cfg.miSolverType == SYNTHETIC) {
233 0 : if (cfg.macro2Md || cfg.totalNumberMDSimulations > 1 || cfg.lbNumberProcesses[0] != 1 || cfg.lbNumberProcesses[1] != 1 || cfg.lbNumberProcesses[2] != 1) {
234 0 : std::cout << "Invalid configuration: Synthetic MD runs sequentially on "
235 : "rank 0 only. "
236 : << "It does neither support parallel communication nor "
237 0 : "multi-instance sampling"
238 0 : << std::endl;
239 0 : exit(EXIT_FAILURE);
240 : }
241 : }
242 4 : if (cfg.maSolverType == COUETTE_ANALYTICAL) {
243 0 : if (cfg.twoWayCoupling) {
244 0 : std::cout << "Invalid configuration: COUETTE_ANALYTICAL does not "
245 0 : "support twoWayCoupling"
246 0 : << std::endl;
247 0 : exit(EXIT_FAILURE);
248 : }
249 : }
250 :
251 8 : return cfg;
252 4 : }
253 :
254 : #if (BUILD_WITH_OPENFOAM)
255 : /** @brief holds the variables necessary for the interface to the IcoFoam
256 : * solver */
257 : struct FoamConfig {
258 : /** @brief the path to the directory, where the folder with the IcoFoam
259 : * OpenFOAM setup files are */
260 : std::string directory;
261 : /** @brief the name of the OpenFOAM folder */
262 : std::string folder;
263 : /** @brief the cubic mesh with a cubic hole has 12 boundaries, this vector
264 : * tells which of them
265 : * shall be coupled with the md; The order has to be the same as in
266 : * the blockMeshDict */
267 : tarch::la::Vector<12, unsigned int> boundariesWithMD;
268 : };
269 : #endif
270 :
271 : /** @brief channel is always expected to have origin at (0.0,0.0,0.0) and to
272 : * be cubic (MD 30: 50.0, MD 60: 100.0, MD 120: 200.0) */
273 : double channelheight;
274 : /** @brief velocity of moving wall (lower boundary moves) */
275 : tarch::la::Vector<3, double> wallVelocity;
276 : /** @brief number of coupling cycles that will be done, while the wall
277 : * velocity is the wallInitVelocity */
278 : int wallInitCycles;
279 : /** @brief the velocity at the moving wall (z=0) while the wallInitCycles*/
280 : tarch::la::Vector<3, double> wallInitVelocity;
281 : /** @brief total number of oscillation periods of the oscillating wall
282 : * velocity*/
283 : double wallOscillations;
284 : /** @brief number of coupling cycles, that is continuum time steps; MD/DPD:
285 : * 1000 */
286 : int couplingCycles;
287 : /** @brief true if data will be send & received from the md to the continuum
288 : * solver */
289 : bool md2Macro;
290 : /** @brief true if data will be send & received from the continuum to the md
291 : * solver */
292 : bool macro2Md;
293 : /** @brief true if the signal to noise ratio shall be evaluated */
294 : bool computeSNR;
295 : /** @brief true if from the md solver will be applied as boundary condition
296 : * for the continuum solver */
297 : bool twoWayCoupling;
298 : /** @brief number of coupling cycles before a filter is applied*/
299 : int filterInitCycles;
300 : /** @brief the time step interval for writing the md data to csv files */
301 : int csvEveryTimestep;
302 : /** @brief the type of continuum solver */
303 : MacroSolverType maSolverType;
304 : /** @brief the type of md solver */
305 : MicroSolverType miSolverType;
306 : /** @brief the general density of the fluid under consideration */
307 : double density;
308 : /** @brief the kinematic viscosity of the fluid under consideration */
309 : double kinVisc;
310 : /** @brief only for LB couette solver: number of processes */
311 : tarch::la::Vector<3, unsigned int> lbNumberProcesses;
312 : /** @brief only for LB couette solver: VTK plotting per time step */
313 : int plotEveryTimestep;
314 : /** @brief only for LB couette solver: CSV plotting of average velocity */
315 : bool plotAverageVelocity;
316 : /** @brief number of cycles the continuum solver is advanced before the
317 : * coupling is enabled */
318 : int initAdvanceCycles;
319 : /** @brief the start temperature for the fluid under consideration */
320 : double temp;
321 : /** @brief number of equilibartion time steps = number of time steps that
322 : * the md will run before the coupling is enabled */
323 : int equSteps;
324 : /** @brief the number of md simulation instances in a multi-instance
325 : * coupling, -1 = dynamic */
326 : int totalNumberMDSimulations;
327 : /** @brief the minimum number of md simulation instances in dynamic MD coupling */
328 : int lowerBoundNumberMDSimulations;
329 : /** @brief only for dynamic MD: target absolute velocity error at start of all coupling cycles */
330 : double absVelErrStart;
331 : /** @brief only for dynamic MD: target absolute velocity error at end of all coupling cycles */
332 : double absVelErrEnd;
333 : /** @brief the sigma for the random noise in the case of synthetic md solver
334 : */
335 : double noiseSigma;
336 : /** @todo piet */
337 : bool twsLoop;
338 : /** @todo piet*/
339 : int twsLoopMin;
340 : /** @todo piet */
341 : int twsLoopMax;
342 : /** @todo piet */
343 : int twsLoopStep;
344 :
345 : #if (BUILD_WITH_OPENFOAM)
346 : /** @brief the configurations for the OpenFoam solver */
347 : FoamConfig foam;
348 : #endif
349 : };
350 :
351 : #endif
|