Loading...
Searching...
No Matches
StoredParameters.C
1#include "ITHACAsystem.H"
2#include "StoredParameters.H"
3#include "SnapshotConfiguration.H"
4
5template <class Enum>
6struct StrLookup : public std::map<std::string, Enum> {
7 using Base = std::map<std::string, Enum>;
8 using Base::Base;
9 Enum lookup(std::string str, Enum defaultValue)
10 {
11 if (this->count(str))
12 {
13 return Base::at(str);
14 } else
15 {
16 return defaultValue;
17 }
18 }
19};
20
21
22StoredParameters::StoredParameters(int argc, char* argv[]):
23 meshConfig_(std::make_unique<MeshConfiguration>())
24 , fieldTemplates_(std::make_unique<FieldTemplates>())
25 , snapshotConfiguration_(std::make_unique<SnapshotConfiguration>())
26 , solverConfiguration_(std::make_unique<SolverConfiguration>())
27 , HyperreductionConfiguration_(std::make_unique<HyperreductionConfiguration>())
28 , ROMExecutionConfig_(std::make_unique<ROMExecutionConfig>())
29 , SimulationFlags_(std::make_unique<SimulationFlags>())
30 , PODConfiguration_(std::make_unique<PODConfiguration>())
31{
32
33 _args = autoPtr<argList>(
34 new argList(argc, argv));
35
36 if (!_args->checkRootCase())
37 {
38 Foam::FatalError.exit();
39 }
40
41 argList& args = _args();
42
43 for (int i = 0; i < argc; i++)
44 {
45 Info << "argv[" << i << "] = " << argv[i] << endl;
46 }
47
48 runTime0 = autoPtr<Foam::Time>(new Foam::Time(Foam::Time::controlDictName,
49 args));
50
51
52 meshConfig_->set_mesh(
53 new fvMesh(
54 Foam::IOobject(
55 Foam::fvMesh::defaultRegion,
56 runTime0->timeName(),
57 *runTime0,
58 Foam::IOobject::MUST_READ)));
59
60
61 meshConfig_->set_nCells(get_mesh().cells().size());
62 ithacaLibraryParameters = ITHACAparameters::getInstance(get_mesh(), *runTime0);
63 ITHACAdict = ithacaLibraryParameters->ITHACAdict;
64
65 snapshotConfiguration_->set_casenameData(ITHACAdict->lookupOrDefault<fileName>("casename", "./"));
66
67 PODConfiguration_->set_fieldlist(static_cast<List<word>>(ITHACAdict->lookup("fields")));
68 solverConfiguration_->set_eigensolver(ithacaLibraryParameters->eigensolver);
69 solverConfiguration_->set_precision(ithacaLibraryParameters->precision);
70 SimulationFlags_->set_exportPython(ithacaLibraryParameters->exportPython);
71 SimulationFlags_->set_exportMatlab(ithacaLibraryParameters->exportMatlab);
72 SimulationFlags_->set_exportTxt(ithacaLibraryParameters->exportTxt);
73 solverConfiguration_->set_outytpe(ithacaLibraryParameters->outytpe);
74 ROMExecutionConfig_->setPressureResolutionKind(StrLookup<PressureResolutionKind>(
75 {
76 { "FullOrder", PressureResolutionKind::FullOrder },
77 { "ReducedOrder", PressureResolutionKind::ReducedOrder },
78 { "Neglected", PressureResolutionKind::Neglected },
79 })
80 .lookup(ITHACAdict->lookupOrDefault<word>("pressureResolutionKind", ""), PressureResolutionKind::Undefined));
81 solverConfiguration_->set_nBlocks(ITHACAdict->lookupOrDefault<label>("nBlocks", 1));
82 solverConfiguration_->set_centeredOrNot(ITHACAdict->lookupOrDefault<bool>("centeredOrNot", 1));
83 HyperreductionConfiguration_->set_interpFieldCentered(ITHACAdict->lookupOrDefault<bool>("interpFieldCenteredOrNot", 0));
84 // nMagicPoints = ITHACAdict->lookupOrDefault<label>("nMagicPoints", 1);
85 HyperreductionConfiguration_->setHRMethod(ITHACAdict->lookupOrDefault<word>("HyperReduction", "DEIM"));
86 HyperreductionConfiguration_->setHRInterpolatedField(ITHACAdict->lookupOrDefault<word>("DEIMInterpolatedField", "fullStressFunction"));
87 HyperreductionConfiguration_->setECPAlgo(ITHACAdict->lookupOrDefault<word>("ECPAlgo", "Global"));
88 SimulationFlags_->set_onLineReconstruct(ITHACAdict->lookupOrDefault<bool>("onLineReconstruct", 0));
89 SimulationFlags_->set_forcingOrNot(ITHACAdict->lookupOrDefault<bool>("forcingOrNot", 0));
90 SimulationFlags_->set_symDiff(ITHACAdict->lookupOrDefault<bool>("symDiff", 0));
91 ROMExecutionConfig_->setROMTemporalScheme(ITHACAdict->lookupOrDefault<word>("ROMTemporalScheme", "euler"));
92 // SOTA can be 0 (no SOTA), D (deterministic version), S (stochastic version)
93 ROMExecutionConfig_->setUseSOTA(ITHACAdict->lookupOrDefault<word>("useSOTA", "None"));
94
95 if (ROMExecutionConfig_->useSOTA() != "None")
96 {
97 Info << "===============================================================" << endl;
98 Info << " RedLUM is launched in " << ROMExecutionConfig_->useSOTA() << "-SOTA mode" << endl;
99 Info << " Ithacadict file will be overidden by parameters specified in m_parameters.C" << endl;
100 Info << "===============================================================" << endl;
101 }
102
103 if ((!(ROMExecutionConfig_->ROMTemporalScheme() == "adams-bashforth")) && (!(ROMExecutionConfig_->ROMTemporalScheme() == "euler")) && (!(ROMExecutionConfig_->ROMTemporalScheme() == "euler–maruyama")))
104 {
105 Info << "This temporal scheme is not implemented." << endl;
106 abort();
107 }
108
109 // Object Time to read OpenFOAM data in the correct folder
110 runTimeData = new Foam::Time(Foam::Time::controlDictName, ".", get_casenameData());
111 Foam::Time* runTime;
112
113 if (Pstream::parRun())
114 {
115 Foam::fileName casenamePar = get_casenameData() + "processor" + name(Pstream::myProcNo());
116 Foam::Time* runTimePar = new Foam::Time(Foam::Time::controlDictName, ".", casenamePar);
117 runTime = runTimePar;
118 } else
119 {
120 runTime = runTimeData;
121 }
122
123
124 fieldTemplates_->set_U(new volVectorField(
125 IOobject(
126 "U",
127 runTime->times()[1].name(),
128 get_mesh(),
129 IOobject::MUST_READ),
130 get_mesh()));
131
132
133 fieldTemplates_->set_p(new volScalarField(
134 IOobject(
135 "p",
136 runTime->times()[1].name(),
137 get_mesh(),
138 IOobject::MUST_READ),
139 get_mesh()));
140
141
142 snapshotConfiguration_->set_nSimu(ITHACAdict->lookupOrDefault("nSimu", 100));
143
144
145 initializeFieldConfiguration();
146
147 PODConfiguration_->set_weightH1(1.0);
148 PODConfiguration_->set_weightBC(ITHACAdict->lookupOrDefault<double>("weightBC", 0.));
149 PODConfiguration_->set_patchBC(ITHACAdict->lookupOrDefault<word>("patchBC", "inlet"));
150
151 // Initialize startTime, endTime and nSnapshots
152
153 // Get times list from the case folder
154 instantList Times = runTime->times();
155
156 // Read Initial and last time from the POD dictionary
157 const entry* existnsnap = ITHACAdict->findEntry("Nsnapshots");
158 const entry* existLT = ITHACAdict->findEntry("FinalTime");
159
160 // Initiate variable from PODSolverDict
161 if ((existnsnap) && (existLT))
162 {
163 Info << "Error you cannot define LatestTime and NSnapShots together" << endl;
164 abort();
165 } else if (existnsnap)
166 {
167 snapshotConfiguration_->set_initialTime(ITHACAdict->lookupOrDefault<scalar>("InitialTime", 0));
168 snapshotConfiguration_->set_finalTime(ITHACAdict->lookupOrDefault<scalar>("FinalTime", 100000000000000));
169 snapshotConfiguration_->set_nSnapshots(readScalar(ITHACAdict->lookup("Nsnapshots")));
170 snapshotConfiguration_->set_startTime(Time::findClosestTimeIndex(runTime->times(), get_initialTime()));
171 snapshotConfiguration_->set_nSnapshots(min(get_nSnapshots(), Times.size() - get_startTime()));
172 snapshotConfiguration_->set_endTime(get_startTime() + get_nSnapshots() - 1);
173 snapshotConfiguration_->set_finalTime(std::stof(runTime->times()[get_endTime()].name()));
174 } else
175 {
176 snapshotConfiguration_->set_initialTime(ITHACAdict->lookupOrDefault<scalar>("InitialTime", 0));
177 snapshotConfiguration_->set_finalTime(ITHACAdict->lookupOrDefault<scalar>("FinalTime", 100000000000000));
178 snapshotConfiguration_->set_endTime(Time::findClosestTimeIndex(runTime->times(), get_finalTime()));
179 snapshotConfiguration_->set_startTime(Time::findClosestTimeIndex(runTime->times(), get_initialTime()));
180 snapshotConfiguration_->set_nSnapshots(get_endTime() - get_startTime() + 1);
181 if (get_initialTime() > get_finalTime())
182 {
183 Info << "FinalTime cannot be smaller than the InitialTime check your ITHACAdict file\n"
184 << endl;
185 abort();
186 }
187 snapshotConfiguration_->set_finalTime(std::stof(runTime->times()[get_endTime()].name()));
188 }
189
190 // Read Initial and last time from the POD dictionary
191 const entry* existnsnapSimulation = ITHACAdict->findEntry("NsnapshotsSimulation");
192 const entry* existLTSimulation = ITHACAdict->findEntry("FinalTimeSimulation");
193
194 scalar InitialTimeSimulation(get_finalTime());
195 label startTimeSimulation(Time::findClosestTimeIndex(runTime->times(), InitialTimeSimulation));
196
197 if ((existnsnapSimulation) && (existLTSimulation))
198 {
199 Info << "Error you cannot define LatestTimeSimulation and NSnapShotsSimulation together" << endl;
200 abort();
201 } else if (existnsnapSimulation)
202 {
203 snapshotConfiguration_->set_nSnapshotsSimulation(readScalar(ITHACAdict->lookup("NsnapshotsSimulation")));
204 snapshotConfiguration_->set_nSnapshotsSimulation(min(get_nSnapshotsSimulation(), Times.size() - startTimeSimulation));
205 snapshotConfiguration_->set_endTimeSimulation(startTimeSimulation + get_nSnapshotsSimulation() - 1);
206 snapshotConfiguration_->set_finalTimeSimulation(std::stof(runTime->times()[get_endTimeSimulation()].name()));
207 } else
208 {
209 snapshotConfiguration_->set_finalTimeSimulation(ITHACAdict->lookupOrDefault<scalar>("FinalTimeSimulation", 100000000000000));
210 snapshotConfiguration_->set_endTimeSimulation(Time::findClosestTimeIndex(runTime->times(), get_finalTimeSimulation()));
211 snapshotConfiguration_->set_nSnapshotsSimulation(get_endTimeSimulation() - startTimeSimulation + 1);
212 if (InitialTimeSimulation > get_finalTimeSimulation())
213 {
214 Info << "FinalTimeSimulation cannot be smaller than the InitialTimeSimulation check your ITHACAdict file\n"
215 << endl;
216 abort();
217 }
218 snapshotConfiguration_->set_finalTimeSimulation(std::stof(runTime->times()[get_endTimeSimulation()].name()));
219 }
220
221 // Initialize writeInterval
222 IOdictionary controlDict(
223 IOobject(
224 "controlDict",
225 runTimeData->system(),
226 get_mesh(),
227 IOobject::MUST_READ,
228 IOobject::NO_WRITE));
229 snapshotConfiguration_->set_writeInterval(controlDict.lookupOrDefault<double>("writeInterval", 1));
230
231 IOdictionary transportProperties(
232 IOobject(
233 "transportProperties",
234 runTimeData->constant(),
235 get_mesh(),
236 IOobject::MUST_READ,
237 IOobject::NO_WRITE));
238
239 ROMExecutionConfig_->setNu(new dimensionedScalar(
240 "nu",
241 dimViscosity,
242 transportProperties));
243
244 meshConfig_->set_volume(new volScalarField(
245 IOobject(
246 "volume",
247 runTimeData->timeName(),
248 get_mesh(),
249 IOobject::NO_READ,
250 IOobject::NO_WRITE),
251 get_mesh(),
252 dimensionedScalar("volume", dimensionSet(0, 3, 0, 0, 0, 0, 0), 1.0)));
253
254 meshConfig_->get_volume().primitiveFieldRef() = get_mesh().V().field();
255 Eigen::VectorXd volVect = Foam2Eigen::field2Eigen(get_mesh().V().field());
256 meshConfig_->set_totalVolume(volVect.sum());
257
258 meshConfig_->set_delta(new volScalarField(pow(get_volume(), 1.0 / 3.0)));
259
260
261 // TO DO : rewrite the following method to search for the object turbulenceProperties and its attibutes (simulationType and LESModel)
262 string simulationType;
263 string LESModel;
264
265 string DDESModel;
266
267 string filename = "constant/turbulenceProperties";
268 std::ifstream strm(filename);
269
270 string line;
271 getline(strm, line);
272
273 while (line.find("simulationType") == string::npos || line.find("//") != string::npos)
274 {
275 getline(strm, line);
276 }
277
278
279 int N = line.size();
280 int i = 0;
281 while (i < N)
282 {
283 if (line[i] == ' ')
284 {
285 line.erase(i, 1);
286 N = N - 1;
287 } else
288 {
289 i++;
290 }
291 }
292
293 line.erase(line.size() - 1, 1);
294 line.erase(0, 14);
295 simulationType = line;
296
297
298 Info << "--------------------------------------------" << endl;
299 Info << "Simulation type:" << simulationType << endl;
300
301
302 if (simulationType == "laminar")
303 {
304 Info << "DNS simulation will be performed" << endl;
305 set_useDNS(true);
306 set_useDEIM(false);
307 } else if (simulationType == "LES")
308 {
309 fieldTemplates_->set_nut(new volScalarField(
310 IOobject(
311 "nut",
312 runTime->path() + runTime->times()[1].name(),
313 get_mesh(),
314 IOobject::MUST_READ),
315 get_mesh()));
316
317 getline(strm, line);
318 while (line.find("LESModel") == string::npos || line.find("//") != string::npos)
319 {
320 getline(strm, line);
321 }
322
323 N = line.size();
324 i = 0;
325 while (i < N)
326 {
327 if (line[i] == ' ')
328 {
329 line.erase(i, 1);
330 N = N - 1;
331 } else
332 {
333 i++;
334 }
335 }
336 line.erase(N - 1, 1);
337 line.erase(0, 8);
338 LESModel = line;
339
340
341 if (LESModel == "Smagorinsky")
342 {
343 set_useDEIM(true);
344 set_Ck(ITHACAdict->lookupOrDefault<double>("Ck", 0.094));
345 set_Ce(ITHACAdict->lookupOrDefault<double>("Ce", 1.048));
346 set_useDDES(false);
347
348 } else if (LESModel == "kOmegaSSTDDES")
349 {
350 set_useDDES(true);
351 set_useDEIM(false);
352 fieldTemplates_->set_omega(new volScalarField(
353 IOobject(
354 "omega",
355 runTime->path() + runTime->times()[1].name(),
356 get_mesh(),
357 IOobject::MUST_READ),
358 get_mesh()));
359 fieldTemplates_->set_k(new volScalarField(
360 IOobject(
361 "k",
362 runTime->path() + runTime->times()[1].name(),
363 get_mesh(),
364 IOobject::MUST_READ),
365 get_mesh()));
366 } else
367 {
368 Info << "Only turbulence model Smagorinsky is supported with simulation type LES" << endl;
369 Info << "DDES NOT USED**0**" << endl;
370 }
371
372
373 } else
374 {
375 Info << "Simulation type not LES, no DEIM will be performed" << endl;
376 set_useDEIM(false);
377 Info << "\n"
378 << "No DDES was performed" << endl;
379 set_useDDES(false);
380 Info << "\n"
381 << "No DNS simulation was perfomed" << endl;
382 set_useDNS(false);
383 abort();
384 }
385
386 HyperreductionConfiguration_->setFolderDEIM("./ITHACAoutput/");
387 if (SimulationFlags_->useDEIM())
388 {
389 if (get_hilbertSpacePOD()["nut"] == "dL2")
390 {
391 set_deltaWeight(ITHACAutilities::getMassMatrixFV(fieldTemplates_->get_nut()).array().pow(-2.0 / 3.0));
392 }
393 HyperreductionConfiguration_->initializeHyperreduction(PODConfiguration_);
394 }
395}
396
397void StoredParameters::initializeFieldConfiguration()
398{
399 const auto& fieldlist = PODConfiguration_->fieldlist();
400 // Resize field name/type arrays
401 Foam::List<Foam::word> field_names(fieldlist.size());
402 Foam::List<Foam::word> field_types(fieldlist.size());
403 // Read from dictionary and populate PODModeConfig
404 for (label k = 0; k < fieldlist.size(); k++)
405 {
406 dictionary& subDict = ITHACAdict->subDict(fieldlist[k]);
407
408 field_names[k] = static_cast<word>(subDict.lookup("field_name"));
409 field_types[k] = static_cast<word>(subDict.lookup("field_type"));
410
411 label nMode = subDict.lookupOrDefault<label>("nmodes", 1);
412 word hilbertSpace = subDict.lookupOrDefault<word>("hilbertSpacePOD", "L2");
413
414 // Populate the PODModeConfig module
415 PODConfiguration_->insert_nModes(field_names[k], nMode);
416 PODConfiguration_->insert_hilbertSpacePOD(field_names[k], hilbertSpace);
417 PODConfiguration_->set_varyingEnergy(field_names[k], 0);
418 PODConfiguration_->set_resolvedVaryingEnergy(field_names[k], 0);
419 }
420
421 // Store field names and types
422 PODConfiguration_->set_field_name(field_names);
423 PODConfiguration_->set_field_type(field_types);
424}
425
426
427Foam::word StoredParameters::get_pathHilbertSpace_fromHS(Foam::word hilbertSp)
428{
429 Foam::word pathHilbertSpace = "";
430
431 if (hilbertSp == "L2" || hilbertSp == "dL2")
432 {
433 pathHilbertSpace = "";
434 } else if (hilbertSp == "L2wBC")
435 {
436 pathHilbertSpace = "_L2wBC";
437 } else if (hilbertSp == "H1")
438 {
439 pathHilbertSpace = "_H1";
440 } else if (hilbertSp == "wH1")
441 {
442 pathHilbertSpace = "_wH1";
443 } else
444 {
445 Foam::Info << "Error: hilbertSpacePOD type " << hilbertSp
446 << " is not valid." << Foam::endl;
447 Foam::Info << "dot_product_POD is available for L2, L2wBC, H1 and wH1 only." << Foam::endl;
448 abort();
449 }
450
451 return pathHilbertSpace;
452}
453
454Foam::word StoredParameters::get_pathHilbertSpace(Foam::word fieldName)
455{
456 return get_pathHilbertSpace_fromHS(PODConfiguration_->hilbertSpacePOD()[fieldName]);
457}
458
Header file of the ITHACAsystem file.
Stores template fields for velocity, pressure, and turbulence quantities.
static Eigen::MatrixXd field2Eigen(GeometricField< Type, PatchField, GeoMesh > &field)
Convert a vector OpenFOAM field into an Eigen Vector.
Discrete Empirical Interpolation Method settings.
static ITHACAparameters * getInstance()
Gets an instance of ITHACAparameters, to be used if the instance is already existing.
Manages mesh-related parameters and geometric information.
Manages POD-specific parameters including modes, energy, and Hilbert spaces.
Manages boolean flags for various simulation options.
Manages snapshot and time-related parameters.
Controls which eigensolver algorithm is used and output formatting.
T min(Eigen::SparseMatrix< T > &mat, label &ind_row, label &ind_col)
Find the minimum of a sparse Matrix (Useful for DEIM).
Eigen::VectorXd getMassMatrixFV(GeometricField< Type, PatchField, GeoMesh > &snapshot)
Gets a vector containing the volumes of each cell of the mesh.