OGS 6.2.1-499-g3b941532c.dirty.20191012113459
ProjectData.cpp
Go to the documentation of this file.
1 
14 #include "ProjectData.h"
15 
16 #include <algorithm>
17 #include <set>
18 
19 #include <logog/include/logog.hpp>
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_GROUNDWATERFLOW
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  {
451  auto const material_id = medium_config.getConfigAttribute<int>("id", 0);
452 
453  if (_media.find(material_id) != _media.end())
454  {
455  OGS_FATAL(
456  "Multiple media were specified for the same material id %d. "
457  "Keep in mind, that if no material id is specified, it is "
458  "assumed to be 0 by default.",
459  material_id);
460  }
461 
462  _media[material_id] =
464  }
465 
466  if (_media.empty())
467  {
468  OGS_FATAL("No entity is found inside <media>.");
469  }
470 }
471 
473  std::string const& project_directory,
474  std::string const& output_directory)
475 {
476  (void)project_directory; // to avoid compilation warning
477  (void)output_directory; // to avoid compilation warning
478 
479  DBUG("Reading processes:");
481  for (auto process_config : processes_config.getConfigSubtreeList("process"))
482  {
483  auto const type =
485  process_config.peekConfigParameter<std::string>("type");
486 
487  auto const name =
489  process_config.getConfigParameter<std::string>("name");
490 
491  auto const integration_order =
493  process_config.getConfigParameter<int>("integration_order");
494 
495  std::unique_ptr<ProcessLib::Process> process;
496 
497  auto jacobian_assembler = ProcessLib::createJacobianAssembler(
499  process_config.getConfigSubtreeOptional("jacobian_assembler"));
500 
501 #ifdef OGS_BUILD_PROCESS_GROUNDWATERFLOW
502  if (type == "GROUNDWATER_FLOW")
503  {
504  // The existence check of the in the configuration referenced
505  // process variables is checked in the physical process.
506  // TODO at the moment we have only one mesh, later there can be
507  // several meshes. Then we have to assign the referenced mesh
508  // here.
510  name, *_mesh_vec[0], std::move(jacobian_assembler),
511  _process_variables, _parameters, integration_order,
512  process_config, _mesh_vec, output_directory);
513  }
514  else
515 #endif
516 #ifdef OGS_BUILD_PROCESS_LIQUIDFLOW
517  if (type == "LIQUID_FLOW")
518  {
520  name, *_mesh_vec[0], std::move(jacobian_assembler),
521  _process_variables, _parameters, integration_order,
522  process_config);
523  }
524  else
525 #endif
526 #ifdef OGS_BUILD_PROCESS_TES
527  if (type == "TES")
528  {
530  name, *_mesh_vec[0], std::move(jacobian_assembler),
531  _process_variables, _parameters, integration_order,
532  process_config);
533  }
534  else
535 #endif
536 #ifdef OGS_BUILD_PROCESS_HEATCONDUCTION
537  if (type == "HEAT_CONDUCTION")
538  {
540  name, *_mesh_vec[0], std::move(jacobian_assembler),
541  _process_variables, _parameters, integration_order,
542  process_config);
543  }
544  else
545 #endif
546 #ifdef OGS_BUILD_PROCESS_HEATTRANSPORTBHE
547  if (type == "HEAT_TRANSPORT_BHE")
548  {
549  if (_mesh_vec[0]->getDimension() != 3)
550  {
551  OGS_FATAL(
552  "HEAT_TRANSPORT_BHE can only work with a 3-dimentional "
553  "mesh! ");
554  }
555 
556  process =
558  name, *_mesh_vec[0], std::move(jacobian_assembler),
559  _process_variables, _parameters, integration_order,
560  process_config, _curves, _media);
561  }
562  else
563 #endif
564 #ifdef OGS_BUILD_PROCESS_HYDROMECHANICS
565  if (type == "HYDRO_MECHANICS")
566  {
568  switch (process_config.getConfigParameter<int>("dimension"))
569  {
570  case 2:
571  process =
573  2>(name, *_mesh_vec[0],
574  std::move(jacobian_assembler),
576  _local_coordinate_system, integration_order,
577  process_config);
578  break;
579  case 3:
580  process =
582  3>(name, *_mesh_vec[0],
583  std::move(jacobian_assembler),
585  _local_coordinate_system, integration_order,
586  process_config);
587  break;
588  default:
589  OGS_FATAL(
590  "HYDRO_MECHANICS process does not support given "
591  "dimension");
592  }
593  }
594  else
595 #endif
596 #ifdef OGS_BUILD_PROCESS_LIE
597  if (type == "HYDRO_MECHANICS_WITH_LIE")
598  {
600  switch (process_config.getConfigParameter<int>("dimension"))
601  {
602  case 2:
603  process = ProcessLib::LIE::HydroMechanics::
604  createHydroMechanicsProcess<2>(
605  name, *_mesh_vec[0], std::move(jacobian_assembler),
607  _local_coordinate_system, integration_order,
608  process_config);
609  break;
610  case 3:
611  process = ProcessLib::LIE::HydroMechanics::
612  createHydroMechanicsProcess<3>(
613  name, *_mesh_vec[0], std::move(jacobian_assembler),
615  _local_coordinate_system, integration_order,
616  process_config);
617  break;
618  default:
619  OGS_FATAL(
620  "HYDRO_MECHANICS_WITH_LIE process does not support "
621  "given dimension");
622  }
623  }
624  else
625 #endif
626 #ifdef OGS_BUILD_PROCESS_HT
627  if (type == "HT")
628  {
630  name, *_mesh_vec[0], std::move(jacobian_assembler),
631  _process_variables, _parameters, integration_order,
632  process_config, _mesh_vec, output_directory, _media);
633  }
634  else
635 #endif
636 #ifdef OGS_BUILD_PROCESS_COMPONENTTRANSPORT
637  if (type == "ComponentTransport")
638  {
639  process =
641  name, *_mesh_vec[0], std::move(jacobian_assembler),
642  _process_variables, _parameters, integration_order,
643  process_config, _mesh_vec, output_directory, _media);
644  }
645  else
646 #endif
647 #ifdef OGS_BUILD_PROCESS_PHASEFIELD
648  if (type == "PHASE_FIELD")
649  {
650  switch (_mesh_vec[0]->getDimension())
651  {
652  case 2:
653  process =
655  name, *_mesh_vec[0], std::move(jacobian_assembler),
657  _local_coordinate_system, integration_order,
658  process_config);
659  break;
660  case 3:
661  process =
663  name, *_mesh_vec[0], std::move(jacobian_assembler),
665  _local_coordinate_system, integration_order,
666  process_config);
667  break;
668  }
669  }
670  else
671 #endif
672 #ifdef OGS_BUILD_PROCESS_RICHARDSCOMPONENTTRANSPORT
673  if (type == "RichardsComponentTransport")
674  {
677  name, *_mesh_vec[0], std::move(jacobian_assembler),
678  _process_variables, _parameters, integration_order,
679  process_config);
680  }
681  else
682 #endif
683 #ifdef OGS_BUILD_PROCESS_SMALLDEFORMATION
684  if (type == "SMALL_DEFORMATION")
685  {
686  switch (_mesh_vec[0]->getDimension())
687  {
688  case 2:
689  process = ProcessLib::SmallDeformation::
690  createSmallDeformationProcess<2>(
691  name, *_mesh_vec[0], std::move(jacobian_assembler),
693  _local_coordinate_system, integration_order,
694  process_config);
695  break;
696  case 3:
697  process = ProcessLib::SmallDeformation::
698  createSmallDeformationProcess<3>(
699  name, *_mesh_vec[0], std::move(jacobian_assembler),
701  _local_coordinate_system, integration_order,
702  process_config);
703  break;
704  default:
705  OGS_FATAL(
706  "SMALL_DEFORMATION process does not support "
707  "given dimension");
708  }
709  }
710  else
711 #endif
712 #ifdef OGS_BUILD_PROCESS_SMALLDEFORMATIONNONLOCAL
713  if (type == "SMALL_DEFORMATION_NONLOCAL")
714  {
715  switch (_mesh_vec[0]->getDimension())
716  {
717  case 2:
718  process = ProcessLib::SmallDeformationNonlocal::
719  createSmallDeformationNonlocalProcess<2>(
720  name, *_mesh_vec[0], std::move(jacobian_assembler),
722  _local_coordinate_system, integration_order,
723  process_config);
724  break;
725  case 3:
726  process = ProcessLib::SmallDeformationNonlocal::
727  createSmallDeformationNonlocalProcess<3>(
728  name, *_mesh_vec[0], std::move(jacobian_assembler),
730  _local_coordinate_system, integration_order,
731  process_config);
732  break;
733  default:
734  OGS_FATAL(
735  "SMALL_DEFORMATION_NONLOCAL process does not support "
736  "given dimension %d",
737  _mesh_vec[0]->getDimension());
738  }
739  }
740  else
741 #endif
742 #ifdef OGS_BUILD_PROCESS_LIE
743  if (type == "SMALL_DEFORMATION_WITH_LIE")
744  {
746  switch (process_config.getConfigParameter<int>("dimension"))
747  {
748  case 2:
749  process = ProcessLib::LIE::SmallDeformation::
750  createSmallDeformationProcess<2>(
751  name, *_mesh_vec[0], std::move(jacobian_assembler),
753  _local_coordinate_system, integration_order,
754  process_config);
755  break;
756  case 3:
757  process = ProcessLib::LIE::SmallDeformation::
758  createSmallDeformationProcess<3>(
759  name, *_mesh_vec[0], std::move(jacobian_assembler),
761  _local_coordinate_system, integration_order,
762  process_config);
763  break;
764  default:
765  OGS_FATAL(
766  "SMALL_DEFORMATION_WITH_LIE process does not support "
767  "given dimension");
768  }
769  }
770  else
771 #endif
772 #ifdef OGS_BUILD_PROCESS_THERMOHYDROMECHANICS
773  if (type == "THERMO_HYDRO_MECHANICS")
774  {
776  switch (process_config.getConfigParameter<int>("dimension"))
777  {
778  case 2:
779  process = ProcessLib::ThermoHydroMechanics::
780  createThermoHydroMechanicsProcess<2>(
781  name, *_mesh_vec[0], std::move(jacobian_assembler),
783  _local_coordinate_system, integration_order,
784  process_config, _media);
785  break;
786  case 3:
787  process = ProcessLib::ThermoHydroMechanics::
788  createThermoHydroMechanicsProcess<3>(
789  name, *_mesh_vec[0], std::move(jacobian_assembler),
791  _local_coordinate_system, integration_order,
792  process_config, _media);
793  break;
794  default:
795  OGS_FATAL(
796  "THERMO_HYDRO_MECHANICS process does not support given "
797  "dimension");
798  }
799  }
800  else
801 #endif
802 #ifdef OGS_BUILD_PROCESS_THERMOMECHANICALPHASEFIELD
803  if (type == "THERMO_MECHANICAL_PHASE_FIELD")
804  {
805  switch (_mesh_vec[0]->getDimension())
806  {
807  case 2:
808  process = ProcessLib::ThermoMechanicalPhaseField::
809  createThermoMechanicalPhaseFieldProcess<2>(
810  name, *_mesh_vec[0], std::move(jacobian_assembler),
812  _local_coordinate_system, integration_order,
813  process_config);
814  break;
815  case 3:
816  process = ProcessLib::ThermoMechanicalPhaseField::
817  createThermoMechanicalPhaseFieldProcess<3>(
818  name, *_mesh_vec[0], std::move(jacobian_assembler),
820  _local_coordinate_system, integration_order,
821  process_config);
822  break;
823  }
824  }
825  else
826 #endif
827 #ifdef OGS_BUILD_PROCESS_THERMOMECHANICS
828  if (type == "THERMO_MECHANICS")
829  {
830  switch (_mesh_vec[0]->getDimension())
831  {
832  case 2:
833  process = ProcessLib::ThermoMechanics::
834  createThermoMechanicsProcess<2>(
835  name, *_mesh_vec[0], std::move(jacobian_assembler),
837  _local_coordinate_system, integration_order,
838  process_config);
839  break;
840  case 3:
841  process = ProcessLib::ThermoMechanics::
842  createThermoMechanicsProcess<3>(
843  name, *_mesh_vec[0], std::move(jacobian_assembler),
845  _local_coordinate_system, integration_order,
846  process_config);
847  break;
848  }
849  }
850  else
851 #endif
852 #ifdef OGS_BUILD_PROCESS_RICHARDSFLOW
853  if (type == "RICHARDS_FLOW")
854  {
856  name, *_mesh_vec[0], std::move(jacobian_assembler),
857  _process_variables, _parameters, integration_order,
858  process_config, _curves);
859  }
860  else
861 #endif
862 #ifdef OGS_BUILD_PROCESS_RICHARDSMECHANICS
863  if (type == "RICHARDS_MECHANICS")
864  {
866  switch (process_config.getConfigParameter<int>("dimension"))
867  {
868  case 2:
869  process = ProcessLib::RichardsMechanics::
870  createRichardsMechanicsProcess<2>(
871  name, *_mesh_vec[0], std::move(jacobian_assembler),
873  _local_coordinate_system, integration_order,
874  process_config);
875  break;
876  case 3:
877  process = ProcessLib::RichardsMechanics::
878  createRichardsMechanicsProcess<3>(
879  name, *_mesh_vec[0], std::move(jacobian_assembler),
881  _local_coordinate_system, integration_order,
882  process_config);
883  break;
884  }
885  }
886  else
887 #endif
888 #ifdef OGS_BUILD_PROCESS_TWOPHASEFLOWWITHPP
889  if (type == "TWOPHASE_FLOW_PP")
890  {
891  process =
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_TWOPHASEFLOWWITHPRHO
900  if (type == "TWOPHASE_FLOW_PRHO")
901  {
904  name, *_mesh_vec[0], std::move(jacobian_assembler),
905  _process_variables, _parameters, integration_order,
906  process_config, _curves);
907  }
908  else
909 #endif
910 #ifdef OGS_BUILD_PROCESS_THERMALTWOPHASEFLOWWITHPP
911  if (type == "THERMAL_TWOPHASE_WITH_PP")
912  {
915  name, *_mesh_vec[0], std::move(jacobian_assembler),
916  _process_variables, _parameters, integration_order,
917  process_config, _curves);
918  }
919  else
920 #endif
921  {
922  OGS_FATAL("Unknown process type: %s", type.c_str());
923  }
924 
926  _processes,
927  [&name](std::unique_ptr<ProcessLib::Process> const& p) {
928  return p->name == name;
929  }))
930  {
931  OGS_FATAL("The process name '%s' is not unique.", name.c_str());
932  }
933  _processes.push_back(std::move(process));
934  }
935 }
936 
938  std::string const& output_directory)
939 {
940  DBUG("Reading time loop configuration.");
941 
942  _time_loop = ProcessLib::createTimeLoop(config, output_directory,
945 
946  if (!_time_loop)
947  {
948  OGS_FATAL("Initialization of time loop failed.");
949  }
950 }
951 
953 {
954  DBUG("Reading linear solver configuration.");
955 
957  for (auto conf : config.getConfigSubtreeList("linear_solver"))
958  {
960  auto const name = conf.getConfigParameter<std::string>("name");
963  name,
964  std::make_unique<GlobalLinearSolver>("", &conf),
965  "The linear solver name is not unique");
966  }
967 }
968 
970 {
971  DBUG("Reading linear solver configuration.");
972 
974  for (auto conf : config.getConfigSubtreeList("nonlinear_solver"))
975  {
976  auto const ls_name =
978  conf.getConfigParameter<std::string>("linear_solver");
979  auto& linear_solver = BaseLib::getOrError(
980  _linear_solvers, ls_name,
981  "A linear solver with the given name does not exist.");
982 
984  auto const name = conf.getConfigParameter<std::string>("name");
987  name,
988  NumLib::createNonlinearSolver(*linear_solver, conf).first,
989  "The nonlinear solver name is not unique");
990  }
991 }
992 
994  boost::optional<BaseLib::ConfigTree> const& config)
995 {
996  if (!config)
997  {
998  return;
999  }
1000 
1001  DBUG("Reading curves configuration.");
1002 
1004  for (auto conf : config->getConfigSubtreeList("curve"))
1005  {
1007  auto const name = conf.getConfigParameter<std::string>("name");
1009  _curves,
1010  name,
1013  "The curve name is not unique.");
1014  }
1015 }
1016 
1018  boost::optional<BaseLib::ConfigTree> const& config,
1019  std::string const& output_directory)
1020 {
1021  if (!config)
1022  {
1023  return;
1024  }
1025 
1026 #ifdef OGS_BUILD_PROCESS_COMPONENTTRANSPORT
1027  INFO(
1028  "Ready for initializing interface to a chemical solver for water "
1029  "chemistry calculation.");
1030 
1031  if (auto const* component_transport_process = dynamic_cast<
1033  _processes[0].get()))
1034  {
1035  auto const& process_id_to_component_name_map =
1036  component_transport_process->getProcessIDToComponentNameMap();
1037 
1038  auto const chemical_solver =
1040  config->getConfigAttribute<std::string>("chemical_solver");
1041 
1042  if (boost::iequals(chemical_solver, "Phreeqc"))
1043  {
1044  INFO(
1045  "Configuring phreeqc interface for water chemistry "
1046  "calculation using file-based approach.");
1047 
1050  *_mesh_vec[0], process_id_to_component_name_map, *config,
1051  output_directory);
1052  }
1053  else if (boost::iequals(chemical_solver, "PhreeqcKernel"))
1054  {
1055  INFO(
1056  "Configuring phreeqc interface for water chemistry "
1057  "calculation by direct memory access.");
1058 
1061  *_mesh_vec[0], process_id_to_component_name_map, *config,
1062  output_directory);
1063  }
1064  else
1065  {
1066  OGS_FATAL(
1067  "Unknown chemical solver. Please specify either Phreeqc or "
1068  "PhreeqcKernel as the solver for water chemistry calculation "
1069  "instead.");
1070  }
1071  }
1072  else
1073 #endif
1074  {
1075  (void)output_directory;
1076 
1077  OGS_FATAL(
1078  "The specified type of the process to be solved is not component "
1079  "transport process so that water chemistry calculation could not "
1080  "be activated.");
1081  }
1082 }
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 &curves)
std::unique_ptr< Process > createGroundwaterFlowProcess(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)
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:125
bool containsIf(Container const &container, Predicate &&predicate)
Definition: Algorithm.h:249
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< 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::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:120
std::string copyPathToFileName(const std::string &file_name, const std::string &source)
Definition: FileTools.cpp:155
std::map< std::string, std::unique_ptr< NumLib::NonlinearSolverBase > > _nonlinear_solvers
Definition: ProjectData.h:137
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:146
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:132
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::map< int, std::unique_ptr< MaterialPropertyLib::Medium > > _media
Definition: ProjectData.h:129
std::unique_ptr< ChemistryLib::ChemicalSolverInterface > _chemical_system
Definition: ProjectData.h:142
std::unique_ptr< Medium > createMedium(BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters)
std::map< std::string, std::unique_ptr< GlobalLinearSolver > > _linear_solvers
Definition: ProjectData.h:134
boost::optional< ParameterLib::CoordinateSystem > _local_coordinate_system
Definition: ProjectData.h:127
std::vector< std::unique_ptr< ProcessLib::Process > > _processes
Definition: ProjectData.h:121
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< ChemicalSolverInterface > createChemicalSolverInterface(MeshLib::Mesh const &mesh, std::vector< std::pair< int, std::string >> const &process_id_to_component_name_map, BaseLib::ConfigTree const &config, std::string const &output_directory)
std::unique_ptr< GeoLib::GEOObjects > readGeometry(std::string const &filename)
Definition of readMeshFromFile function.
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::unique_ptr< MaterialPropertyLib::Medium >> const &media)
std::vector< std::string > parseParameters(BaseLib::ConfigTree const &parameters_config)
void parseNonlinearSolvers(BaseLib::ConfigTree const &config)
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:103
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
Range< SubtreeIterator > getConfigSubtreeList(std::string const &root) const
Definition: ConfigTree.cpp:175
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::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
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::unique_ptr< MaterialPropertyLib::Medium >> const &media)
boost::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
Definition: ConfigTree.cpp:161
Filename manipulation routines.
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::unique_ptr< MaterialPropertyLib::Medium >> const &media)
std::vector< std::unique_ptr< MeshLib::Mesh > > readMeshes(std::vector< std::string > const &filenames)
std::vector< ProcessLib::ProcessVariable > _process_variables
Definition: ProjectData.h:122
std::iterator_traits< InputIt >::reference findElementOrError(InputIt begin, InputIt end, Predicate predicate, std::string const &error="")
Definition: Algorithm.h:66
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< 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::unique_ptr< MaterialPropertyLib::Medium >> const &media)
std::unique_ptr< CurveType > createPiecewiseLinearCurve(BaseLib::ConfigTree const &config)
std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > _curves
Definition: ProjectData.h:140
std::unique_ptr< MeshLib::Mesh > readSingleMesh(BaseLib::ConfigTree const &mesh_config_parameter, std::string const &project_directory)