OGS 6.3.0-179-g962fdcd4e.dirty.20200403132553
ProjectData.cpp
Go to the documentation of this file.
1 
14 #include "ProjectData.h"
15 
16 #include <algorithm>
17 #include <cctype>
18 #include <logog/include/logog.hpp>
19 #include <set>
20 
21 #ifdef OGS_USE_PYTHON
22 #include <pybind11/eval.h>
23 #endif
24 
25 #include "BaseLib/Algorithm.h"
26 #include "BaseLib/ConfigTree.h"
27 #include "BaseLib/FileTools.h"
28 
29 #include "GeoLib/GEOObjects.h"
35 #include "MeshLib/Mesh.h"
36 
40 
41 // FileIO
44 
46 #include "ParameterLib/Utils.h"
48 #include "ProcessLib/TimeLoop.h"
49 
50 #ifdef OGS_BUILD_PROCESS_COMPONENTTRANSPORT
52 // The ComponenTransportProcess is needed for the instantiation of the chemical
53 // solver.
56 #endif
57 #ifdef OGS_BUILD_PROCESS_STEADYSTATEDIFFUSION
59 #endif
60 #ifdef OGS_BUILD_PROCESS_HT
62 #endif
63 #ifdef OGS_BUILD_PROCESS_HEATCONDUCTION
65 #endif
66 #ifdef OGS_BUILD_PROCESS_HEATTRANSPORTBHE
68 #endif
69 #ifdef OGS_BUILD_PROCESS_HYDROMECHANICS
71 #endif
72 #ifdef OGS_BUILD_PROCESS_LIE
75 #endif
76 #ifdef OGS_BUILD_PROCESS_LIQUIDFLOW
78 #endif
79 #ifdef OGS_BUILD_PROCESS_PHASEFIELD
81 #endif
82 #ifdef OGS_BUILD_PROCESS_RICHARDSCOMPONENTTRANSPORT
84 #endif
85 #ifdef OGS_BUILD_PROCESS_RICHARDSFLOW
87 #endif
88 #ifdef OGS_BUILD_PROCESS_RICHARDSMECHANICS
90 #endif
91 #ifdef OGS_BUILD_PROCESS_SMALLDEFORMATION
93 #endif
94 #ifdef OGS_BUILD_PROCESS_SMALLDEFORMATIONNONLOCAL
96 #endif
97 #ifdef OGS_BUILD_PROCESS_TES
99 #endif
100 #ifdef OGS_BUILD_PROCESS_THERMALTWOPHASEFLOWWITHPP
102 #endif
103 #ifdef OGS_BUILD_PROCESS_THERMOHYDROMECHANICS
105 #endif
106 #ifdef OGS_BUILD_PROCESS_THERMOMECHANICALPHASEFIELD
108 #endif
109 #ifdef OGS_BUILD_PROCESS_THERMOMECHANICS
111 #endif
112 #ifdef OGS_BUILD_PROCESS_TWOPHASEFLOWWITHPP
114 #endif
115 #ifdef OGS_BUILD_PROCESS_TWOPHASEFLOWWITHPRHO
117 #endif
118 
119 namespace
120 {
121 void readGeometry(std::string const& fname, GeoLib::GEOObjects& geo_objects)
122 {
123  DBUG("Reading geometry file '%s'.", fname.c_str());
124  GeoLib::IO::BoostXmlGmlInterface gml_reader(geo_objects);
125  gml_reader.readFile(fname);
126 }
127 
128 std::unique_ptr<MeshLib::Mesh> readSingleMesh(
129  BaseLib::ConfigTree const& mesh_config_parameter,
130  std::string const& project_directory)
131 {
132  std::string const mesh_file = BaseLib::copyPathToFileName(
133  mesh_config_parameter.getValue<std::string>(), project_directory);
134  DBUG("Reading mesh file '%s'.", mesh_file.c_str());
135 
136  auto mesh = std::unique_ptr<MeshLib::Mesh>(
137  MeshLib::IO::readMeshFromFile(mesh_file));
138  if (!mesh)
139  {
140  OGS_FATAL("Could not read mesh from '%s' file. No mesh added.",
141  mesh_file.c_str());
142  }
143 
144 #ifdef DOXYGEN_DOCU_ONLY
145  mesh_config_parameter.getConfigAttributeOptional<bool>("axially_symmetric");
147 #endif // DOXYGEN_DOCU_ONLY
148 
149  if (auto const axially_symmetric =
151  mesh_config_parameter.getConfigAttributeOptional<bool>(
152  "axially_symmetric"))
153  {
154  mesh->setAxiallySymmetric(*axially_symmetric);
155  }
156 
157  return mesh;
158 }
159 
160 std::vector<std::unique_ptr<MeshLib::Mesh>> readMeshes(
161  BaseLib::ConfigTree const& config, std::string const& project_directory)
162 {
163  std::vector<std::unique_ptr<MeshLib::Mesh>> meshes;
164 
166  auto optional_meshes = config.getConfigSubtreeOptional("meshes");
167  if (optional_meshes)
168  {
169  DBUG("Reading multiple meshes.");
170  for (auto mesh_config :
172  optional_meshes->getConfigParameterList("mesh"))
173  {
174  meshes.push_back(readSingleMesh(mesh_config, project_directory));
175  }
176  }
177  else
178  { // Read single mesh with geometry.
179  WARN(
180  "Consider switching from mesh and geometry input to multiple "
181  "meshes input. See "
182  "https://www.opengeosys.org/docs/tools/model-preparation/"
183  "constructmeshesfromgeometry/ tool for conversion.");
185  meshes.push_back(readSingleMesh(config.getConfigParameter("mesh"),
187 
188  std::string const geometry_file = BaseLib::copyPathToFileName(
190  config.getConfigParameter<std::string>("geometry"),
191  project_directory);
192  GeoLib::GEOObjects geoObjects;
193  readGeometry(geometry_file, geoObjects);
194 
195  std::unique_ptr<MeshGeoToolsLib::SearchLength> search_length_algorithm =
197  bool const multiple_nodes_allowed = false;
198  auto additional_meshes =
200  geoObjects, *meshes[0], std::move(search_length_algorithm),
201  multiple_nodes_allowed);
202 
203  std::move(begin(additional_meshes), end(additional_meshes),
204  std::back_inserter(meshes));
205  }
206  return meshes;
207 }
208 
209 boost::optional<ParameterLib::CoordinateSystem> parseLocalCoordinateSystem(
210  boost::optional<BaseLib::ConfigTree> const& config,
211  std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters)
212 {
213  if (!config)
214  {
215  return {};
216  }
217 
218  DBUG("Reading coordinate system configuration.");
219 
220  //
221  // Fetch the first basis vector; its length defines the dimension.
222  //
223  auto const& basis_vector_0 = ParameterLib::findParameter<double>(
224  *config,
226  "basis_vector_0", parameters, 0 /* any dimension */);
227  int const dimension = basis_vector_0.getNumberOfComponents();
228 
229  // check dimension
230  if (dimension != 2 && dimension != 3)
231  {
232  OGS_FATAL(
233  "Basis vector parameter '%s' must have two or three components, "
234  "but it has %d.",
235  basis_vector_0.name.c_str(), dimension);
236  }
237 
238  //
239  // Fetch the second basis vector, which must be of the same dimension as the
240  // first one.
241  //
242  auto const& basis_vector_1 = ParameterLib::findParameter<double>(
243  *config,
245  "basis_vector_1", parameters, dimension);
246 
247  //
248  // For two dimensions, we are done; construct coordinate system;
249  //
250  if (dimension == 2)
251  {
252  return ParameterLib::CoordinateSystem{basis_vector_0, basis_vector_1};
253  }
254 
255  //
256  // Parse the third vector, for three dimensions.
257  //
258  auto const& basis_vector_2 = ParameterLib::findParameter<double>(
259  *config,
261  "basis_vector_2", parameters, dimension);
262  return ParameterLib::CoordinateSystem{basis_vector_0, basis_vector_1,
263  basis_vector_2};
264 }
265 } // namespace
266 
267 ProjectData::ProjectData() = default;
268 
270  std::string const& project_directory,
271  std::string const& output_directory)
272 {
273  _mesh_vec = readMeshes(project_config, project_directory);
274 
275  if (auto const python_script =
277  project_config.getConfigParameterOptional<std::string>("python_script"))
278  {
279 #ifdef OGS_USE_PYTHON
280  namespace py = pybind11;
281 
282  // Append project's directory to python's module search path.
283  py::module::import("sys").attr("path").attr("append")(
285 
286  auto const script_path =
287  BaseLib::copyPathToFileName(*python_script, project_directory);
288 
289  // Evaluate in scope of main module
290  py::object scope = py::module::import("__main__").attr("__dict__");
291  py::eval_file(script_path, scope);
292 #else
293  OGS_FATAL("OpenGeoSys has not been built with Python support.");
294 #endif // OGS_USE_PYTHON
295  }
296 
298  parseCurves(project_config.getConfigSubtreeOptional("curves"));
299 
300  auto parameter_names_for_transformation =
302  parseParameters(project_config.getConfigSubtree("parameters"));
303 
306  project_config.getConfigSubtreeOptional("local_coordinate_system"),
307  _parameters);
308 
309  for (auto& parameter : _parameters)
310  {
311  if (std::find(begin(parameter_names_for_transformation),
312  end(parameter_names_for_transformation),
313  parameter->name) !=
314  end(parameter_names_for_transformation))
315  {
316  if (!_local_coordinate_system)
317  {
318  OGS_FATAL(
319  "The parameter '%s' is using the local coordinate system "
320  "but no local coordinate system was provided.",
321  parameter->name.c_str());
322  }
323  parameter->setCoordinateSystem(*_local_coordinate_system);
324  }
325 
326  parameter->initialize(_parameters);
327  }
328 
330  parseProcessVariables(project_config.getConfigSubtree("process_variables"));
331 
333  parseMedia(project_config.getConfigSubtreeOptional("media"));
334 
336  parseProcesses(project_config.getConfigSubtree("processes"),
337  project_directory, output_directory);
338 
340  parseLinearSolvers(project_config.getConfigSubtree("linear_solvers"));
341 
343  parseNonlinearSolvers(project_config.getConfigSubtree("nonlinear_solvers"));
344 
347  project_config.getConfigSubtreeOptional("chemical_system"),
348  output_directory);
349 
351  parseTimeLoop(project_config.getConfigSubtree("time_loop"),
352  output_directory);
353 }
354 
356  BaseLib::ConfigTree const& process_variables_config)
357 {
358  DBUG("Parse process variables:");
359 
360  std::set<std::string> names;
361 
362  for (auto var_config
364  : process_variables_config.getConfigSubtreeList("process_variable"))
365  {
366  // Either the mesh name is given, or the first mesh's name will be
367  // taken. Taking the first mesh's value is deprecated.
368  auto const mesh_name =
370  var_config.getConfigParameter<std::string>("mesh",
371  _mesh_vec[0]->getName());
372 
373  auto& mesh = *BaseLib::findElementOrError(
374  begin(_mesh_vec), end(_mesh_vec),
375  [&mesh_name](auto const& m) { return m->getName() == mesh_name; },
376  "Expected to find a mesh named " + mesh_name + ".");
377 
378  auto pv = ProcessLib::ProcessVariable{var_config, mesh, _mesh_vec,
379  _parameters};
380  if (!names.insert(pv.getName()).second)
381  {
382  OGS_FATAL("A process variable with name `%s' already exists.",
383  pv.getName().c_str());
384  }
385 
386  _process_variables.push_back(std::move(pv));
387  }
388 }
389 
390 std::vector<std::string> ProjectData::parseParameters(
391  BaseLib::ConfigTree const& parameters_config)
392 {
393  using namespace ProcessLib;
394 
395  std::set<std::string> names;
396  std::vector<std::string> parameter_names_for_transformation;
397 
398  DBUG("Reading parameters:");
399  for (auto parameter_config :
401  parameters_config.getConfigSubtreeList("parameter"))
402  {
403  auto p =
404  ParameterLib::createParameter(parameter_config, _mesh_vec, _curves);
405  if (!names.insert(p->name).second)
406  {
407  OGS_FATAL("A parameter with name `%s' already exists.",
408  p->name.c_str());
409  }
410 
411  auto const use_local_coordinate_system =
413  parameter_config.getConfigParameterOptional<bool>(
414  "use_local_coordinate_system");
415  if (!!use_local_coordinate_system && *use_local_coordinate_system)
416  {
417  parameter_names_for_transformation.push_back(p->name);
418  }
419 
420  _parameters.push_back(std::move(p));
421  }
422 
423  _parameters.push_back(
424  std::make_unique<ParameterLib::ConstantParameter<double>>(
426 
427  return parameter_names_for_transformation;
428 }
429 
431  boost::optional<BaseLib::ConfigTree> const& media_config)
432 {
433  if (!media_config)
434  {
435  return;
436  }
437 
438  DBUG("Reading media:");
439 
440  if (_mesh_vec.empty() || _mesh_vec[0] == nullptr)
441  {
442  ERR("A mesh is required to define medium materials.");
443  return;
444  }
445 
446  for (auto const& medium_config :
448  media_config->getConfigSubtreeList("medium"))
449  {
450  auto material_id_string =
452  medium_config.getConfigAttribute<std::string>("id", "0");
453  material_id_string.erase(
454  remove_if(begin(material_id_string), end(material_id_string),
455  [](unsigned char const c) { return std::isspace(c); }),
456  end(material_id_string));
457  auto const material_ids_strings =
458  BaseLib::splitString(material_id_string, ',');
459 
460  // Convert strings to ints;
461  std::vector<int> material_ids;
462  std::transform(
463  begin(material_ids_strings), end(material_ids_strings),
464  std::back_inserter(material_ids), [](std::string const& m_id) {
465  if (auto const it = std::find_if_not(
466  begin(m_id), end(m_id),
467  [](unsigned char const c) { return std::isdigit(c); });
468  it != end(m_id))
469  {
470  OGS_FATAL(
471  "Could not parse material ID's from '%s'. Please "
472  "separate multiple material ID's by comma only. "
473  "Invalid character: '%c'",
474  m_id.c_str(), *it);
475  }
476  return std::stoi(m_id);
477  });
478 
479  for (auto const& id : material_ids)
480  {
481  if (_media.find(id) != end(_media))
482  {
483  OGS_FATAL(
484  "Multiple media were specified for the same material id "
485  "'%d'. "
486  "Keep in mind, that if no material id is specified, it is "
487  "assumed to be 0 by default.",
488  id);
489  }
490 
491  _media[id] =
492  (id == material_ids[0])
494  medium_config, _parameters,
496  : nullptr,
497  _curves)
498  : _media[material_ids[0]];
499  }
500  }
501 
502  if (_media.empty())
503  {
504  OGS_FATAL("No entity is found inside <media>.");
505  }
506 }
507 
509  std::string const& project_directory,
510  std::string const& output_directory)
511 {
512  (void)project_directory; // to avoid compilation warning
513  (void)output_directory; // to avoid compilation warning
514 
515  DBUG("Reading processes:");
517  for (auto process_config : processes_config.getConfigSubtreeList("process"))
518  {
519  auto const type =
521  process_config.peekConfigParameter<std::string>("type");
522 
523  auto const name =
525  process_config.getConfigParameter<std::string>("name");
526 
527  auto const integration_order =
529  process_config.getConfigParameter<int>("integration_order");
530 
531  std::unique_ptr<ProcessLib::Process> process;
532 
533  auto jacobian_assembler = ProcessLib::createJacobianAssembler(
535  process_config.getConfigSubtreeOptional("jacobian_assembler"));
536 
537 #ifdef OGS_BUILD_PROCESS_STEADYSTATEDIFFUSION
538  if (type == "STEADY_STATE_DIFFUSION")
539  {
540  // The existence check of the in the configuration referenced
541  // process variables is checked in the physical process.
542  // TODO at the moment we have only one mesh, later there can be
543  // several meshes. Then we have to assign the referenced mesh
544  // here.
545  process =
547  name, *_mesh_vec[0], std::move(jacobian_assembler),
548  _process_variables, _parameters, integration_order,
549  process_config, _mesh_vec, output_directory, _media);
550  }
551  else
552 #endif
553 #ifdef OGS_BUILD_PROCESS_LIQUIDFLOW
554  if (type == "LIQUID_FLOW")
555  {
557  name, *_mesh_vec[0], std::move(jacobian_assembler),
558  _process_variables, _parameters, integration_order,
559  process_config, _mesh_vec, output_directory, _media);
560  }
561  else
562 #endif
563 #ifdef OGS_BUILD_PROCESS_TES
564  if (type == "TES")
565  {
567  name, *_mesh_vec[0], std::move(jacobian_assembler),
568  _process_variables, _parameters, integration_order,
569  process_config);
570  }
571  else
572 #endif
573 #ifdef OGS_BUILD_PROCESS_HEATCONDUCTION
574  if (type == "HEAT_CONDUCTION")
575  {
577  name, *_mesh_vec[0], std::move(jacobian_assembler),
578  _process_variables, _parameters, integration_order,
579  process_config);
580  }
581  else
582 #endif
583 #ifdef OGS_BUILD_PROCESS_HEATTRANSPORTBHE
584  if (type == "HEAT_TRANSPORT_BHE")
585  {
586  if (_mesh_vec[0]->getDimension() != 3)
587  {
588  OGS_FATAL(
589  "HEAT_TRANSPORT_BHE can only work with a 3-dimentional "
590  "mesh! ");
591  }
592 
593  process =
595  name, *_mesh_vec[0], std::move(jacobian_assembler),
596  _process_variables, _parameters, integration_order,
597  process_config, _curves, _media);
598  }
599  else
600 #endif
601 #ifdef OGS_BUILD_PROCESS_HYDROMECHANICS
602  if (type == "HYDRO_MECHANICS")
603  {
605  switch (process_config.getConfigParameter<int>("dimension"))
606  {
607  case 2:
608  process =
610  2>(name, *_mesh_vec[0],
611  std::move(jacobian_assembler),
613  _local_coordinate_system, integration_order,
614  process_config, _media);
615  break;
616  case 3:
617  process =
619  3>(name, *_mesh_vec[0],
620  std::move(jacobian_assembler),
622  _local_coordinate_system, integration_order,
623  process_config, _media);
624  break;
625  default:
626  OGS_FATAL(
627  "HYDRO_MECHANICS process does not support given "
628  "dimension");
629  }
630  }
631  else
632 #endif
633 #ifdef OGS_BUILD_PROCESS_LIE
634  if (type == "HYDRO_MECHANICS_WITH_LIE")
635  {
637  switch (process_config.getConfigParameter<int>("dimension"))
638  {
639  case 2:
640  process = ProcessLib::LIE::HydroMechanics::
641  createHydroMechanicsProcess<2>(
642  name, *_mesh_vec[0], std::move(jacobian_assembler),
644  _local_coordinate_system, integration_order,
645  process_config);
646  break;
647  case 3:
648  process = ProcessLib::LIE::HydroMechanics::
649  createHydroMechanicsProcess<3>(
650  name, *_mesh_vec[0], std::move(jacobian_assembler),
652  _local_coordinate_system, integration_order,
653  process_config);
654  break;
655  default:
656  OGS_FATAL(
657  "HYDRO_MECHANICS_WITH_LIE process does not support "
658  "given dimension");
659  }
660  }
661  else
662 #endif
663 #ifdef OGS_BUILD_PROCESS_HT
664  if (type == "HT")
665  {
667  name, *_mesh_vec[0], std::move(jacobian_assembler),
668  _process_variables, _parameters, integration_order,
669  process_config, _mesh_vec, output_directory, _media);
670  }
671  else
672 #endif
673 #ifdef OGS_BUILD_PROCESS_COMPONENTTRANSPORT
674  if (type == "ComponentTransport")
675  {
676  process =
678  name, *_mesh_vec[0], std::move(jacobian_assembler),
679  _process_variables, _parameters, integration_order,
680  process_config, _mesh_vec, output_directory, _media);
681  }
682  else
683 #endif
684 #ifdef OGS_BUILD_PROCESS_PHASEFIELD
685  if (type == "PHASE_FIELD")
686  {
687  switch (_mesh_vec[0]->getDimension())
688  {
689  case 2:
690  process =
692  name, *_mesh_vec[0], std::move(jacobian_assembler),
694  _local_coordinate_system, integration_order,
695  process_config);
696  break;
697  case 3:
698  process =
700  name, *_mesh_vec[0], std::move(jacobian_assembler),
702  _local_coordinate_system, integration_order,
703  process_config);
704  break;
705  }
706  }
707  else
708 #endif
709 #ifdef OGS_BUILD_PROCESS_RICHARDSCOMPONENTTRANSPORT
710  if (type == "RichardsComponentTransport")
711  {
714  name, *_mesh_vec[0], std::move(jacobian_assembler),
715  _process_variables, _parameters, integration_order,
716  process_config);
717  }
718  else
719 #endif
720 #ifdef OGS_BUILD_PROCESS_SMALLDEFORMATION
721  if (type == "SMALL_DEFORMATION")
722  {
723  switch (_mesh_vec[0]->getDimension())
724  {
725  case 2:
726  process = ProcessLib::SmallDeformation::
727  createSmallDeformationProcess<2>(
728  name, *_mesh_vec[0], std::move(jacobian_assembler),
730  _local_coordinate_system, integration_order,
731  process_config);
732  break;
733  case 3:
734  process = ProcessLib::SmallDeformation::
735  createSmallDeformationProcess<3>(
736  name, *_mesh_vec[0], std::move(jacobian_assembler),
738  _local_coordinate_system, integration_order,
739  process_config);
740  break;
741  default:
742  OGS_FATAL(
743  "SMALL_DEFORMATION process does not support "
744  "given dimension");
745  }
746  }
747  else
748 #endif
749 #ifdef OGS_BUILD_PROCESS_SMALLDEFORMATIONNONLOCAL
750  if (type == "SMALL_DEFORMATION_NONLOCAL")
751  {
752  switch (_mesh_vec[0]->getDimension())
753  {
754  case 2:
755  process = ProcessLib::SmallDeformationNonlocal::
756  createSmallDeformationNonlocalProcess<2>(
757  name, *_mesh_vec[0], std::move(jacobian_assembler),
759  _local_coordinate_system, integration_order,
760  process_config);
761  break;
762  case 3:
763  process = ProcessLib::SmallDeformationNonlocal::
764  createSmallDeformationNonlocalProcess<3>(
765  name, *_mesh_vec[0], std::move(jacobian_assembler),
767  _local_coordinate_system, integration_order,
768  process_config);
769  break;
770  default:
771  OGS_FATAL(
772  "SMALL_DEFORMATION_NONLOCAL process does not support "
773  "given dimension %d",
774  _mesh_vec[0]->getDimension());
775  }
776  }
777  else
778 #endif
779 #ifdef OGS_BUILD_PROCESS_LIE
780  if (type == "SMALL_DEFORMATION_WITH_LIE")
781  {
783  switch (process_config.getConfigParameter<int>("dimension"))
784  {
785  case 2:
786  process = ProcessLib::LIE::SmallDeformation::
787  createSmallDeformationProcess<2>(
788  name, *_mesh_vec[0], std::move(jacobian_assembler),
790  _local_coordinate_system, integration_order,
791  process_config);
792  break;
793  case 3:
794  process = ProcessLib::LIE::SmallDeformation::
795  createSmallDeformationProcess<3>(
796  name, *_mesh_vec[0], std::move(jacobian_assembler),
798  _local_coordinate_system, integration_order,
799  process_config);
800  break;
801  default:
802  OGS_FATAL(
803  "SMALL_DEFORMATION_WITH_LIE process does not support "
804  "given dimension");
805  }
806  }
807  else
808 #endif
809 #ifdef OGS_BUILD_PROCESS_THERMOHYDROMECHANICS
810  if (type == "THERMO_HYDRO_MECHANICS")
811  {
813  switch (process_config.getConfigParameter<int>("dimension"))
814  {
815  case 2:
816  process = ProcessLib::ThermoHydroMechanics::
817  createThermoHydroMechanicsProcess<2>(
818  name, *_mesh_vec[0], std::move(jacobian_assembler),
820  _local_coordinate_system, integration_order,
821  process_config, _media);
822  break;
823  case 3:
824  process = ProcessLib::ThermoHydroMechanics::
825  createThermoHydroMechanicsProcess<3>(
826  name, *_mesh_vec[0], std::move(jacobian_assembler),
828  _local_coordinate_system, integration_order,
829  process_config, _media);
830  break;
831  default:
832  OGS_FATAL(
833  "THERMO_HYDRO_MECHANICS process does not support given "
834  "dimension");
835  }
836  }
837  else
838 #endif
839 #ifdef OGS_BUILD_PROCESS_THERMOMECHANICALPHASEFIELD
840  if (type == "THERMO_MECHANICAL_PHASE_FIELD")
841  {
842  switch (_mesh_vec[0]->getDimension())
843  {
844  case 2:
845  process = ProcessLib::ThermoMechanicalPhaseField::
846  createThermoMechanicalPhaseFieldProcess<2>(
847  name, *_mesh_vec[0], std::move(jacobian_assembler),
849  _local_coordinate_system, integration_order,
850  process_config);
851  break;
852  case 3:
853  process = ProcessLib::ThermoMechanicalPhaseField::
854  createThermoMechanicalPhaseFieldProcess<3>(
855  name, *_mesh_vec[0], std::move(jacobian_assembler),
857  _local_coordinate_system, integration_order,
858  process_config);
859  break;
860  }
861  }
862  else
863 #endif
864 #ifdef OGS_BUILD_PROCESS_THERMOMECHANICS
865  if (type == "THERMO_MECHANICS")
866  {
867  switch (_mesh_vec[0]->getDimension())
868  {
869  case 2:
870  process = ProcessLib::ThermoMechanics::
871  createThermoMechanicsProcess<2>(
872  name, *_mesh_vec[0], std::move(jacobian_assembler),
874  _local_coordinate_system, integration_order,
875  process_config);
876  break;
877  case 3:
878  process = ProcessLib::ThermoMechanics::
879  createThermoMechanicsProcess<3>(
880  name, *_mesh_vec[0], std::move(jacobian_assembler),
882  _local_coordinate_system, integration_order,
883  process_config);
884  break;
885  }
886  }
887  else
888 #endif
889 #ifdef OGS_BUILD_PROCESS_RICHARDSFLOW
890  if (type == "RICHARDS_FLOW")
891  {
893  name, *_mesh_vec[0], std::move(jacobian_assembler),
894  _process_variables, _parameters, integration_order,
895  process_config, _curves, _media);
896  }
897  else
898 #endif
899 #ifdef OGS_BUILD_PROCESS_RICHARDSMECHANICS
900  if (type == "RICHARDS_MECHANICS")
901  {
903  switch (process_config.getConfigParameter<int>("dimension"))
904  {
905  case 2:
906  process = ProcessLib::RichardsMechanics::
907  createRichardsMechanicsProcess<2>(
908  name, *_mesh_vec[0], std::move(jacobian_assembler),
910  _local_coordinate_system, integration_order,
911  process_config, _media);
912  break;
913  case 3:
914  process = ProcessLib::RichardsMechanics::
915  createRichardsMechanicsProcess<3>(
916  name, *_mesh_vec[0], std::move(jacobian_assembler),
918  _local_coordinate_system, integration_order,
919  process_config, _media);
920  break;
921  }
922  }
923  else
924 #endif
925 #ifdef OGS_BUILD_PROCESS_TWOPHASEFLOWWITHPP
926  if (type == "TWOPHASE_FLOW_PP")
927  {
928  process =
930  name, *_mesh_vec[0], std::move(jacobian_assembler),
931  _process_variables, _parameters, integration_order,
932  process_config, _curves, _media);
933  }
934  else
935 #endif
936 #ifdef OGS_BUILD_PROCESS_TWOPHASEFLOWWITHPRHO
937  if (type == "TWOPHASE_FLOW_PRHO")
938  {
941  name, *_mesh_vec[0], std::move(jacobian_assembler),
942  _process_variables, _parameters, integration_order,
943  process_config, _curves);
944  }
945  else
946 #endif
947 #ifdef OGS_BUILD_PROCESS_THERMALTWOPHASEFLOWWITHPP
948  if (type == "THERMAL_TWOPHASE_WITH_PP")
949  {
952  name, *_mesh_vec[0], std::move(jacobian_assembler),
953  _process_variables, _parameters, integration_order,
954  process_config, _curves);
955  }
956  else
957 #endif
958  {
959  OGS_FATAL("Unknown process type: %s", type.c_str());
960  }
961 
963  _processes,
964  [&name](std::unique_ptr<ProcessLib::Process> const& p) {
965  return p->name == name;
966  }))
967  {
968  OGS_FATAL("The process name '%s' is not unique.", name.c_str());
969  }
970  _processes.push_back(std::move(process));
971  }
972 }
973 
975  std::string const& output_directory)
976 {
977  DBUG("Reading time loop configuration.");
978 
979  _time_loop = ProcessLib::createTimeLoop(config, output_directory,
982 
983  if (!_time_loop)
984  {
985  OGS_FATAL("Initialization of time loop failed.");
986  }
987 }
988 
990 {
991  DBUG("Reading linear solver configuration.");
992 
994  for (auto conf : config.getConfigSubtreeList("linear_solver"))
995  {
997  auto const name = conf.getConfigParameter<std::string>("name");
1000  name,
1001  std::make_unique<GlobalLinearSolver>("", &conf),
1002  "The linear solver name is not unique");
1003  }
1004 }
1005 
1007 {
1008  DBUG("Reading linear solver configuration.");
1009 
1011  for (auto conf : config.getConfigSubtreeList("nonlinear_solver"))
1012  {
1013  auto const ls_name =
1015  conf.getConfigParameter<std::string>("linear_solver");
1016  auto& linear_solver = BaseLib::getOrError(
1017  _linear_solvers, ls_name,
1018  "A linear solver with the given name does not exist.");
1019 
1021  auto const name = conf.getConfigParameter<std::string>("name");
1024  name,
1025  NumLib::createNonlinearSolver(*linear_solver, conf).first,
1026  "The nonlinear solver name is not unique");
1027  }
1028 }
1029 
1031  boost::optional<BaseLib::ConfigTree> const& config)
1032 {
1033  if (!config)
1034  {
1035  return;
1036  }
1037 
1038  DBUG("Reading curves configuration.");
1039 
1041  for (auto conf : config->getConfigSubtreeList("curve"))
1042  {
1044  auto const name = conf.getConfigParameter<std::string>("name");
1046  _curves,
1047  name,
1050  "The curve name is not unique.");
1051  }
1052 }
1053 
1055  boost::optional<BaseLib::ConfigTree> const& config,
1056  std::string const& output_directory)
1057 {
1058  if (!config)
1059  {
1060  return;
1061  }
1062 
1063 #ifdef OGS_BUILD_PROCESS_COMPONENTTRANSPORT
1064  INFO(
1065  "Ready for initializing interface to a chemical solver for water "
1066  "chemistry calculation.");
1067 
1068  if (auto const* component_transport_process = dynamic_cast<
1070  _processes[0].get()))
1071  {
1072  auto const& process_id_to_component_name_map =
1073  component_transport_process->getProcessIDToComponentNameMap();
1074 
1075  auto const chemical_solver =
1077  config->getConfigAttribute<std::string>("chemical_solver");
1078 
1079  if (boost::iequals(chemical_solver, "Phreeqc"))
1080  {
1081  INFO(
1082  "Configuring phreeqc interface for water chemistry "
1083  "calculation using file-based approach.");
1084 
1087  _mesh_vec, process_id_to_component_name_map, *config,
1088  output_directory);
1089  }
1090  else if (boost::iequals(chemical_solver, "PhreeqcKernel"))
1091  {
1092  INFO(
1093  "Configuring phreeqc interface for water chemistry "
1094  "calculation by direct memory access.");
1095 
1098  _mesh_vec, process_id_to_component_name_map, *config,
1099  output_directory);
1100  }
1101  else
1102  {
1103  OGS_FATAL(
1104  "Unknown chemical solver. Please specify either Phreeqc or "
1105  "PhreeqcKernel as the solver for water chemistry calculation "
1106  "instead.");
1107  }
1108  }
1109  else
1110 #endif
1111  {
1112  (void)output_directory;
1113 
1114  OGS_FATAL(
1115  "The specified type of the process to be solved is not component "
1116  "transport process so that water chemistry calculation could not "
1117  "be activated.");
1118  }
1119 }
Container class for geometric objects.
Definition: GEOObjects.h:63
std::vector< std::unique_ptr< ParameterLib::ParameterBase > > _parameters
Buffer for each parameter config passed to the process.
Definition: ProjectData.h:124
bool containsIf(Container const &container, Predicate &&predicate)
Definition: Algorithm.h:251
std::vector< std::unique_ptr< MeshLib::Mesh > > constructAdditionalMeshesFromGeoObjects(GeoLib::GEOObjects const &geo_objects, MeshLib::Mesh const &mesh, std::unique_ptr< SearchLength > search_length_algorithm, bool const multiple_nodes_allowed)
std::unique_ptr< Process > createTwoPhaseFlowWithPrhoProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation >> const &curves)
Definition of the BoostXmlGmlInterface class.
std::unique_ptr< ParameterBase > createParameter(BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< MeshLib::Mesh >> const &meshes, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation >> const &curves)
Definition: Parameter.cpp:25
std::unique_ptr< AbstractJacobianAssembler > createJacobianAssembler(boost::optional< BaseLib::ConfigTree > const &config)
void parseLinearSolvers(BaseLib::ConfigTree const &config)
void parseCurves(boost::optional< BaseLib::ConfigTree > const &config)
std::vector< std::unique_ptr< MeshLib::Mesh > > _mesh_vec
Definition: ProjectData.h:119
std::string copyPathToFileName(const std::string &file_name, const std::string &source)
Definition: FileTools.cpp:146
std::map< std::string, std::unique_ptr< NumLib::NonlinearSolverBase > > _nonlinear_solvers
Definition: ProjectData.h:136
std::unique_ptr< Process > createRichardsFlowProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation >> const &, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium >> const &media)
void parseProcessVariables(BaseLib::ConfigTree const &process_variables_config)
std::pair< std::unique_ptr< NonlinearSolverBase >, NonlinearSolverTag > createNonlinearSolver(GlobalLinearSolver &linear_solver, BaseLib::ConfigTree const &config)
std::unique_ptr< Process > createThermalTwoPhaseFlowWithPPProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation >> const &curves)
boost::optional< ParameterLib::CoordinateSystem > parseLocalCoordinateSystem(boost::optional< BaseLib::ConfigTree > const &config, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters)
Definition of the Mesh class.
Map::mapped_type & getOrError(Map &map, Key const &key, std::string const &error_message)
Definition: Algorithm.h:148
void parseMedia(boost::optional< BaseLib::ConfigTree > const &media_config)
Parses media configuration and saves them in an object.
std::unique_ptr< ProcessLib::TimeLoop > _time_loop
The time loop used to solve this project&#39;s processes.
Definition: ProjectData.h:131
std::unique_ptr< Process > createTwoPhaseFlowWithPPProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation >> const &curves, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium >> const &media)
Definition of the GEOObjects class.
T getConfigParameter(std::string const &param) const
MeshLib::Mesh * readMeshFromFile(const std::string &file_name)
static const std::string zero_parameter_name
std::unique_ptr< Medium > createMedium(BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, ParameterLib::CoordinateSystem const *const local_coordinate_system, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation >> const &curves)
std::unique_ptr< ChemistryLib::ChemicalSolverInterface > _chemical_system
Definition: ProjectData.h:141
std::unique_ptr< Process > createComponentTransportProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< MeshLib::Mesh >> const &meshes, std::string const &output_directory, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium >> const &media)
std::map< std::string, std::unique_ptr< GlobalLinearSolver > > _linear_solvers
Definition: ProjectData.h:133
boost::optional< ParameterLib::CoordinateSystem > _local_coordinate_system
Definition: ProjectData.h:126
std::vector< std::unique_ptr< ProcessLib::Process > > _processes
Definition: ProjectData.h:120
Single, constant value parameter.
template std::unique_ptr< Process > createPhaseFieldProcess< 3 >(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, boost::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const &config)
void parseProcesses(BaseLib::ConfigTree const &processes_config, std::string const &project_directory, std::string const &output_directory)
std::unique_ptr< GeoLib::GEOObjects > readGeometry(std::string const &filename)
std::unique_ptr< Process > createSteadyStateDiffusion(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< MeshLib::Mesh >> const &meshes, std::string const &output_directory, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium >> const &media)
std::unique_ptr< ChemicalSolverInterface > createChemicalSolverInterface(std::vector< std::unique_ptr< MeshLib::Mesh >> const &meshes, std::vector< std::pair< int, std::string >> const &process_id_to_component_name_map, BaseLib::ConfigTree const &config, std::string const &output_directory)
Definition of readMeshFromFile function.
std::vector< std::string > parseParameters(BaseLib::ConfigTree const &parameters_config)
void parseNonlinearSolvers(BaseLib::ConfigTree const &config)
std::unique_ptr< Process > createHydroMechanicsProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, boost::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium >> const &media)
void parseChemicalSystem(boost::optional< BaseLib::ConfigTree > const &config, const std::string &output_directory)
std::unique_ptr< TimeLoop > createTimeLoop(BaseLib::ConfigTree const &config, std::string const &output_directory, const std::vector< std::unique_ptr< Process >> &processes, const std::map< std::string, std::unique_ptr< NumLib::NonlinearSolverBase >> &nonlinear_solvers, std::vector< std::unique_ptr< MeshLib::Mesh >> const &meshes, std::unique_ptr< ChemistryLib::ChemicalSolverInterface > &phreeqc_io)
Builds a TimeLoop from the given configuration.
void parseTimeLoop(BaseLib::ConfigTree const &config, const std::string &output_directory)
Parses the time loop configuration.
static const double p
void insertIfKeyUniqueElseError(Map &map, Key const &key, Value &&value, std::string const &error_message)
Definition: Algorithm.h:105
template std::unique_ptr< Process > createPhaseFieldProcess< 2 >(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, boost::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const &config)
std::unique_ptr< Process > createRichardsComponentTransportProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config)
ConfigTree getConfigSubtree(std::string const &root) const
Definition: ConfigTree.cpp:151
std::unique_ptr< Process > createLiquidFlowProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< MeshLib::Mesh >> const &meshes, std::string const &output_directory, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium >> const &media)
std::vector< std::string > splitString(std::string const &str)
Definition: StringTools.cpp:28
Range< SubtreeIterator > getConfigSubtreeList(std::string const &root) const
Definition: ConfigTree.cpp:175
std::unique_ptr< MeshGeoToolsLib::SearchLength > createSearchLengthAlgorithm(BaseLib::ConfigTree const &external_config, MeshLib::Mesh const &mesh)
unsigned getDimension(MeshLib::MeshElemType eleType)
boost::optional< T > getConfigAttributeOptional(std::string const &attr) const
boost::optional< T > getConfigParameterOptional(std::string const &param) const
#define OGS_FATAL(fmt,...)
Definition: Error.h:64
boost::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
Definition: ConfigTree.cpp:161
Filename manipulation routines.
std::vector< std::unique_ptr< MeshLib::Mesh > > readMeshes(std::vector< std::string > const &filenames)
std::vector< ProcessLib::ProcessVariable > _process_variables
Definition: ProjectData.h:121
std::unique_ptr< Process > createHTProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< MeshLib::Mesh >> const &meshes, std::string const &output_directory, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium >> const &media)
std::iterator_traits< InputIt >::reference findElementOrError(InputIt begin, InputIt end, Predicate predicate, std::string const &error="")
Definition: Algorithm.h:68
std::map< int, std::shared_ptr< MaterialPropertyLib::Medium > > _media
Definition: ProjectData.h:128
std::unique_ptr< Process > createHeatTransportBHEProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation >> const &curves, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium >> const &media)
std::unique_ptr< Process > createTESProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config)
std::unique_ptr< Process > createHeatConductionProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config)
std::string project_directory
The directory where the prj file resides.
Definition: FileTools.cpp:25
std::unique_ptr< CurveType > createPiecewiseLinearCurve(BaseLib::ConfigTree const &config)
std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > _curves
Definition: ProjectData.h:139
std::unique_ptr< MeshLib::Mesh > readSingleMesh(BaseLib::ConfigTree const &mesh_config_parameter, std::string const &project_directory)