Skip to content
Snippets Groups Projects
Commit 4f5e4c3e authored by Norbert Grunwald's avatar Norbert Grunwald Committed by Dmitri Naumov
Browse files

[MatL] Multi-phase/-component library.

parent ebe4ae0b
No related branches found
No related tags found
No related merge requests found
Showing
with 1106 additions and 0 deletions
......@@ -26,6 +26,7 @@
#include "BaseLib/FileTools.h"
#include "GeoLib/GEOObjects.h"
#include "MaterialLib/MPL/mpMedium.h"
#include "MathLib/Curve/CreatePiecewiseLinearCurve.h"
#include "MeshGeoToolsLib/ConstructMeshesFromGeometries.h"
#include "MeshGeoToolsLib/CreateSearchLength.h"
......@@ -233,6 +234,9 @@ ProjectData::ProjectData(BaseLib::ConfigTree const& project_config,
//! \ogs_file_param{prj__process_variables}
parseProcessVariables(project_config.getConfigSubtree("process_variables"));
//! \ogs_file_param{prj__media}
parseMedia(project_config.getConfigSubtreeOptional("media"));
//! \ogs_file_param{prj__processes}
parseProcesses(project_config.getConfigSubtree("processes"),
project_directory, output_directory);
......@@ -309,6 +313,49 @@ void ProjectData::parseParameters(BaseLib::ConfigTree const& parameters_config)
parameter->initialize(_parameters);
}
void ProjectData::parseMedia(
boost::optional<BaseLib::ConfigTree> const& media_config)
{
if (!media_config)
return;
DBUG("Reading media:");
if (_mesh_vec.empty() || _mesh_vec[0] == nullptr)
{
ERR("A mesh is required to define medium materials.");
return;
}
for (auto const& medium_config :
//! \ogs_file_param{material__media__medium}
media_config->getConfigSubtreeList("medium"))
{
auto const material_id = medium_config.getConfigAttribute<int>("id", 0);
if (_media.find(material_id) != _media.end())
{
OGS_FATAL(
"Multiple media were specified for the same "
"material id %d. Keep in mind, that if no material id is "
"specified, it is assumed to be 0 by default.",
material_id);
}
_media[material_id] =
std::make_unique<MaterialPropertyLib::Medium>(medium_config);
}
if (_media.empty())
OGS_FATAL("No entity is found inside <media>.");
if (_media.rbegin()->first != static_cast<int>(_media.size()) - 1)
OGS_FATAL(
"The ids in the porous media definitions in the project file have "
"to be sequential, starting with the id zero.");
}
void ProjectData::parseProcesses(BaseLib::ConfigTree const& processes_config,
std::string const& project_directory,
std::string const& output_directory)
......
......@@ -18,7 +18,9 @@
#include <string>
#include "BaseLib/ConfigTree.h"
#include "MaterialLib/MPL/mpMedium.h"
#include "MathLib/InterpolationAlgorithms/PiecewiseLinearInterpolation.h"
#include "ProcessLib/Parameter/Parameter.h"
#include "ProcessLib/Process.h"
#include "ProcessLib/ProcessVariable.h"
......@@ -89,6 +91,9 @@ private:
/// Checks if a parameter has name tag.
void parseParameters(BaseLib::ConfigTree const& parameters_config);
/// Parses media configuration and saves them in an object.
void parseMedia(boost::optional<BaseLib::ConfigTree> const& media_config);
/// Parses the processes configuration and creates new processes for each
/// process entry passing the corresponding subtree to the process
/// constructor.
......@@ -106,6 +111,7 @@ private:
void parseCurves(boost::optional<BaseLib::ConfigTree> const& config);
std::unique_ptr<MaterialPropertyLib::Medium> _medium;
std::vector<std::unique_ptr<MeshLib::Mesh>> _mesh_vec;
std::map<std::string, std::unique_ptr<ProcessLib::Process>> _processes;
std::vector<ProcessLib::ProcessVariable> _process_variables;
......@@ -113,6 +119,8 @@ private:
/// Buffer for each parameter config passed to the process.
std::vector<std::unique_ptr<ProcessLib::ParameterBase>> _parameters;
std::map<int, std::unique_ptr<MaterialPropertyLib::Medium>> _media;
/// The time loop used to solve this project's processes.
std::unique_ptr<TimeLoop> _time_loop;
......
......@@ -13,6 +13,10 @@ append_source_files(SOURCES Fluid/SpecificHeatCapacity)
append_source_files(SOURCES Fluid/ThermalConductivity)
append_source_files(SOURCES Fluid/WaterVaporProperties)
append_source_files(SOURCES MPL)
append_source_files(SOURCES MPL/Properties)
append_source_files(SOURCES MPL/Components)
append_source_files(SOURCES PorousMedium)
append_source_files(SOURCES PorousMedium/Porosity)
append_source_files(SOURCES PorousMedium/Storage)
......
/**
* \file
* \author Norbert Grunwald
* \date Sep 7, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "cWater.h"
#include "MaterialLib/MPL/Properties/properties.h"
namespace MaterialPropertyLib
{
Water::Water()
{
_properties[name] = std::make_unique<Constant>("Water");
}
} // namespace MaterialPropertyLib
/**
* \file
* \author Norbert Grunwald
* \date Sep 7, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include "MaterialLib/MPL/mpComponent.h"
namespace MaterialPropertyLib
{
/// A class for Water derived from Component.
///
/// This class can holds material constants and default properties of ordinary
/// water.
struct Water final : public Component
{
Water();
};
} // namespace MaterialPropertyLib
/**
* \file
* \author Norbert Grunwald
* \date Sep 7, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include "cWater.h"
/**
* \file
* \date Nov 28, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "CreateMaterialSpatialDistributionMap.h"
#include "MaterialSpatialDistributionMap.h"
#include "MeshLib/Mesh.h"
namespace MaterialPropertyLib
{
std::unique_ptr<MaterialSpatialDistributionMap>
createMaterialSpatialDistributionMap(
std::map<int, std::unique_ptr<Medium>> const& media,
MeshLib::Mesh const& mesh)
{
auto const material_ids = materialIDs(mesh);
int const max_material_id =
!material_ids
? 0
: *std::max_element(begin(*material_ids), end(*material_ids));
if (max_material_id > static_cast<int>(media.size() - 1))
OGS_FATAL(
"The maximum value of MaterialIDs in mesh is %d. As the "
"given number of porous media definitions in the project "
"file is %d, the maximum value of MaterialIDs in mesh must be %d "
"(index starts with zero).",
max_material_id, media.size(), max_material_id - 1);
if (max_material_id < static_cast<int>(media.size() - 1))
WARN(
"There are %d porous medium definitions in the project file but "
"only %d different values in the MaterialIDs vector/data_array in "
"the mesh.",
media.size(), max_material_id - 1);
return std::make_unique<MaterialSpatialDistributionMap>(media,
material_ids);
}
} // namespace MaterialPropertyLib
/**
* \file
* \date Nov 28, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include <map>
#include <memory>
namespace MeshLib
{
class Mesh;
}
namespace MaterialPropertyLib
{
class MaterialSpatialDistributionMap;
class Medium;
std::unique_ptr<MaterialSpatialDistributionMap>
createMaterialSpatialDistributionMap(
std::map<int, std::unique_ptr<Medium>> const& media,
MeshLib::Mesh const& mesh);
} // namespace MaterialPropertyLib
/**
* \file
* \date Nov 28, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "MaterialSpatialDistributionMap.h"
#include "MeshLib/Mesh.h"
namespace MaterialPropertyLib
{
Medium* MaterialSpatialDistributionMap::getMedium(std::size_t const element_id)
{
auto const material_id =
_material_ids == nullptr ? 0 : (*_material_ids)[element_id];
return _media.at(material_id).get();
}
} // namespace MaterialPropertyLib
/**
* \file
* \date Nov 28, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include <map>
#include <memory>
#include <vector>
namespace MeshLib
{
template <typename PROP_VAL_TYPE>
class PropertyVector;
} // namespace MeshLib
namespace MaterialPropertyLib
{
class Medium;
class MaterialSpatialDistributionMap
{
private:
std::map<int, std::unique_ptr<Medium>> const& _media;
MeshLib::PropertyVector<int> const* const _material_ids;
public:
MaterialSpatialDistributionMap(
std::map<int, std::unique_ptr<Medium>> const& media,
MeshLib::PropertyVector<int> const* const material_ids)
: _media(media), _material_ids(material_ids)
{
}
Medium* getMedium(std::size_t element_id);
};
} // namespace MaterialPropertyLib
/**
* \file
* \author Norbert Grunwald
* \date Sep 7, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "pConstant.h"
namespace MaterialPropertyLib
{
Constant::Constant(PropertyDataType const& v)
{
_value = v;
_dvalue = boost::apply_visitor(
[](auto const& value) -> PropertyDataType { return decltype(value){}; },
v);
};
} // namespace MaterialPropertyLib
/**
* \file
* \author Norbert Grunwald
* \date Sep 7, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include "MaterialLib/MPL/mpProperty.h"
namespace MaterialPropertyLib
{
/// The constant property class. This property simply retrieves the stored
/// constant value. It accepts all datatypes defined in PropertyDataType
/// (currently: double, Vector, Tensor, std::string)
class Constant final : public Property
{
public:
/// This constructor accepts single values of any data type defined in the
/// PropertyDataType definition and sets the protected attribute _value of
/// the base class Property to that value.
explicit Constant(PropertyDataType const& v);
};
} // namespace MaterialPropertyLib
/**
* \file
* \author Norbert Grunwald
* \date July 3rd, 2018
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "pUndefined.h"
#include <string>
#include "MaterialLib/MPL/mpEnums.h"
namespace MaterialPropertyLib
{
Undefined::Undefined(PropertyEnum const& pEnum)
{
thisPropertyEnum = pEnum;
}
PropertyDataType Undefined::value() const
{
std::string property = convertEnumToString[thisPropertyEnum];
OGS_FATAL(
"The property \'%s\' (property-enum no. %i in "
"MaterialLib/MPL/mpEnums.h) was requested, but is not defined in the "
"project file.",
property.c_str(), (int)thisPropertyEnum);
}
PropertyDataType Undefined::value(VariableArray const& /*v*/)
{
return value();
}
} // MaterialPropertyLib
/**
* \file
* \author Norbert Grunwald
* \date July 3rd, 2018
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include "MaterialLib/MPL/mpProperty.h"
namespace MaterialPropertyLib
{
/// The constant property class. This property simply retrieves the stored
/// constant value. It accepts all datatypes defined in PropertyDataType.
class Undefined final : public Property
{
private:
PropertyEnum thisPropertyEnum;
public:
explicit Undefined(PropertyEnum const&);
PropertyDataType value() const override;
PropertyDataType value(VariableArray const&) override;
};
} // MaterialPropertyLib
/**
* \file
* \author Norbert Grunwald
* \date Sep 7, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include "pConstant.h"
#include "pUndefined.h"
/**
* \file
* \author Norbert Grunwald
* \date Sep 7, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "mpComponent.h"
#include "Components/components.h"
#include "Properties/properties.h"
namespace MaterialPropertyLib
{
Component::Component()
{
// Default properties are set to zero.
createDefaultProperties();
// Some properties can be initialized by other default properties:
_properties[name] = std::make_unique<Constant>("no_name");
}
Component::Component(std::string const& component_name)
{
// Default properties are set to zero.
createDefaultProperties();
// Some properties can be initialized by other default properties:
_properties[name] = std::make_unique<Constant>(component_name);
}
void Component::createProperties(BaseLib::ConfigTree const& config)
{
for (auto property_config : config.getConfigSubtreeList("property"))
{
// Parsing the property name:
auto const property_name =
property_config.getConfigParameter<std::string>("name");
// Create a new property based on the configuration subtree:
auto property = newProperty(property_config, this);
// Insert the new property at the right position into the components
// private PropertyArray:
_properties[convertStringToProperty(property_name)] =
std::move(property);
}
}
void Component::createDefaultProperties()
{
for (std::size_t i = 0; i < number_of_property_enums; ++i)
{
_properties[i] =
std::make_unique<Undefined>(static_cast<PropertyEnum>(i));
}
}
Property& Component::property(PropertyEnum const& p) const
{
return *_properties[p];
}
std::unique_ptr<Component> newComponent(std::string const& component_name,
bool& isCustomComponent)
{
// If a name is given, it must conform with one of the derived component
// names in the following list:
if (boost::iequals(component_name, "water"))
{
return std::make_unique<Water>();
}
// If the given name does not appear in the list (which is common), the
// method creates a custom component, where all properties have to be
// specified manually.
isCustomComponent = true;
return std::make_unique<Component>(component_name);
}
} // namespace MaterialPropertyLib
/**
* \author Norbert Grunwald
* \date Sep 7, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include "BaseLib/ConfigTree.h"
#include "mpProperty.h"
namespace MaterialPropertyLib
{
/// \brief This class defines components (substances).
/// \details The Component class is a base class used for not further specified
/// components. Components are specified by the property 'name'. For specified
/// components we derive special classes from this class (for clarity they are
/// located in the 'components' subfolder).
class Component
{
protected:
/// The property array of the component.
PropertyArray _properties;
public:
/// Default constructor of Component. This constructor is used
/// when the component is not specified via the 'name'-tag.
Component();
/// Constructor for a custom component
explicit Component(std::string const& component_name);
virtual ~Component() = default;
/// The method reads the 'properties' tag in the prj-file and creates
/// component properties accordingly.
///
/// First, a new property iy created based on the specified property type.
/// Then, the property name is evaluated and the property is copied into the
/// properties array.
void createProperties(BaseLib::ConfigTree const& /*config*/);
/// This method initializes the component property array with constant
/// functions of value zero.
void createDefaultProperties();
/// A get-function for retrieving a cartain property.
Property& property(PropertyEnum const& /*p*/) const;
};
/// Method for creating a new component based on the specified component name.
///
/// This function creates a new component based on the (optional) component name
/// that is given in the prj-file.
///
/// The method evaluates the string in the 'name'-object and calls the
/// constructors of the derived component classes (if found) or that of the base
/// class (if no name is specified).
std::unique_ptr<Component> newComponent(std::string const& component_name,
bool& isNewComponent);
} // namespace MaterialPropertyLib
/**
* \author Norbert Grunwald
* \date Sep 7, 2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include <boost/algorithm/string/predicate.hpp>
#include <boost/variant.hpp>
#include <array>
#include <cstddef>
#include <string>
#include "BaseLib/Error.h"
namespace MaterialPropertyLib
{
/// Very simple vector data type for holding
/// a pair of values.
using Pair = std::array<double, 2>;
/// Very simple vector data type for holding
/// vector components.
using Vector = std::array<double, 3>;
/// Simple symmetric tensor data type for holding
/// xx, yy, zz, xy, xz, yz tensor components.
using SymmTensor = std::array<double, 9>;
/// Very simple tensor data type for holding
/// tensor components.
using Tensor = std::array<double, 9>;
/// Variables is simply a list of all commonly used variables that are used to
/// determine the size of the VariableArray. If the variable of your choice is
/// missing, simply add it somewhere at the list, but above the last entry
/// 'numberOfVariables'
enum Variables : std::size_t
{
phase_pressure,
capillary_pressure,
gas_density,
liquid_density,
temperature,
liquid_saturation,
u,
numberOfVariables
};
/// Data type for primary variables, designed to contain both scalar and vector
/// data.
using VariableType = boost::variant<double, Vector>;
/// The VariableArray is a std::array of fixed size. Its size is determined by
/// the Variables enumerator list. Data type of that array is defined by the
/// VariableType definition.
using VariableArray = std::array<VariableType, numberOfVariables>;
/// This method returns a value of type double from the variables array
inline double getScalar(VariableType pv)
{
return boost::get<double>(pv);
}
/// PropertyEnum is an enumerator list of all known properties of a substance.
/// This includes all properties on all scales (i.e. component, phase, and
/// medium scales). It is used as an indexer for the PropertyArray of the
/// materials. If a necessary property is not in the list, simply add a new one
/// in alphabetical order (of course, except for the last entry
/// 'number_of_property_enums'). Please note that any of these entries must also
/// appear in below convert functions.
enum PropertyEnum : std::size_t
{
acentric_factor,
binary_interaction_coefficient,
biot_coefficient,
brooks_corey_exponent,
bulk_modulus,
critical_density,
critical_pressure,
critical_temperature,
compressibility,
density,
drhodT,
effective_stress,
entry_pressure,
fredlund_parameters,
heat_capacity,
longitudinal_dispersivity,
molar_mass,
mole_fraction,
molecular_diffusion,
name,
permeability,
phase_velocity,
porosity,
reference_density,
reference_temperature,
reference_pressure,
relative_permeability,
residual_gas_saturation,
residual_liquid_saturation,
saturation,
specific_heat_capacity,
thermal_conductivity,
thermal_expansivity,
transveral_dispersivity,
viscosity,
number_of_property_enums
};
/// This function converts a string (e.g. a string from the configuration-tree)
/// into one of the entries of the PropertyEnum enumerator. To avoid confusion,
/// I suggest that the syntax of the properties in the input-files (i.e. the
/// strings) have to be identical to the syntax of the entries in the
/// enumerator.
inline PropertyEnum convertStringToProperty(std::string const& inString)
{
if (boost::iequals(inString, "acentric_factor"))
{
return acentric_factor;
}
if (boost::iequals(inString, "binary_interaction_coefficient"))
{
return binary_interaction_coefficient;
}
if (boost::iequals(inString, "biot_coefficient"))
{
return biot_coefficient;
}
if (boost::iequals(inString, "brooks_corey_exponent"))
{
return brooks_corey_exponent;
}
if (boost::iequals(inString, "bulk_modulus"))
{
return bulk_modulus;
}
if (boost::iequals(inString, "critical_density"))
{
return critical_density;
}
if (boost::iequals(inString, "critical_pressure"))
{
return critical_pressure;
}
if (boost::iequals(inString, "critical_temperature"))
{
return critical_temperature;
}
if (boost::iequals(inString, "compressibility"))
{
return compressibility;
}
if (boost::iequals(inString, "density"))
{
return density;
}
if (boost::iequals(inString, "drhodT"))
{
return drhodT;
}
if (boost::iequals(inString, "effective_stress"))
{
return effective_stress;
}
if (boost::iequals(inString, "entry_pressure"))
{
return entry_pressure;
}
if (boost::iequals(inString, "fredlund_parameters"))
{
return fredlund_parameters;
}
if (boost::iequals(inString, "heat_capacity"))
{
return heat_capacity;
}
if (boost::iequals(inString, "longitudinal_dispersivity"))
{
return longitudinal_dispersivity;
}
if (boost::iequals(inString, "molar_mass"))
{
return molar_mass;
}
if (boost::iequals(inString, "mole_fraction"))
{
return mole_fraction;
}
if (boost::iequals(inString, "molecular_diffusion"))
{
return molecular_diffusion;
}
if (boost::iequals(inString, "name"))
{
return name;
}
if (boost::iequals(inString, "permeability"))
{
return permeability;
}
if (boost::iequals(inString, "porosity"))
{
return porosity;
}
if (boost::iequals(inString, "phase_velocity"))
{
return phase_velocity;
}
if (boost::iequals(inString, "reference_density"))
{
return reference_density;
}
if (boost::iequals(inString, "reference_temperature"))
{
return reference_temperature;
}
if (boost::iequals(inString, "reference_pressure"))
{
return reference_pressure;
}
if (boost::iequals(inString, "relative_permeability"))
{
return relative_permeability;
}
if (boost::iequals(inString, "residual_gas_saturation"))
{
return residual_gas_saturation;
}
if (boost::iequals(inString, "residual_liquid_saturation"))
{
return residual_liquid_saturation;
}
if (boost::iequals(inString, "saturation"))
{
return saturation;
}
if (boost::iequals(inString, "specific_heat_capacity"))
{
return specific_heat_capacity;
}
if (boost::iequals(inString, "thermal_conductivity"))
{
return thermal_conductivity;
}
if (boost::iequals(inString, "thermal_expansivity"))
{
return thermal_expansivity;
}
if (boost::iequals(inString, "transveral_dispersivity"))
{
return transveral_dispersivity;
}
if (boost::iequals(inString, "viscosity"))
{
return viscosity;
}
OGS_FATAL(
"The property name \"%s\" does not correspond to any known "
"property",
inString.c_str());
return number_of_property_enums; // to avoid the 'no return' warning
}
const static std::vector<std::string> convertEnumToString{
{"acentric_factor"},
{"binary_interaction_coefficient"},
{"biot_coefficient"},
{"brooks_corey_exponent"},
{"bulk_modulus"},
{"critical_density"},
{"critical_pressure"},
{"critical_temperature"},
{"compressibility"},
{"density"},
{"drhodT"},
{"effective_stress"},
{"entry_pressure"},
{"fredlund_parameters"},
{"heat_capacity"},
{"longitudinal_dispersivity"},
{"molar_mass"},
{"mole_fraction"},
{"molecular_diffusion"},
{"name"},
{"permeability"},
{"phase_velocity"},
{"porosity"},
{"reference_density"},
{"reference_temperature"},
{"reference_pressure"},
{"relative_permeability"},
{"residual_gas_saturation"},
{"residual_liquid_saturation"},
{"saturation"},
{"specific_heat_capacity"},
{"thermal_conductivity"},
{"thermal_expansivity"},
{"transveral_dispersivity"},
{"viscosity"}};
} // namespace MaterialPropertyLib
/**
* \file
* \author Norbert Grunwald
* \date 07.09.2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "mpMedium.h"
#include <boost/variant.hpp>
#include <string>
#include "BaseLib/Algorithm.h"
#include "Properties/pUndefined.h"
#include "Properties/pConstant.h"
#include "mpComponent.h"
#include "mpPhase.h"
namespace MaterialPropertyLib
{
Medium::Medium(BaseLib::ConfigTree const& config)
{
// Default properties are initialized in the first place, such
// that user-defined properties overwrite those defaults.
createDefaultProperties();
// A name of a medium is entirely optional and has no effects
// other than a small gain of clarity in case several media
// should be defined.
auto const medium_name =
config.getConfigParameter<std::string>("name", "no_name");
// 'name' is a constant property of the medium
_properties[name] = std::make_unique<Constant>(medium_name);
// Parsing the phases
// Properties of phases may be not required in all the cases.
auto const phases_config = config.getConfigSubtreeOptional("phases");
if (phases_config)
createPhases(*phases_config);
// Parsing medium properties, overwriting the defaults.
auto const properties_config =
config.getConfigSubtreeOptional("properties");
if (properties_config)
{
createProperties(*properties_config);
}
if (!phases_config && !properties_config)
OGS_FATAL("Neither tag <phases> nor tag <properties> has been found.");
}
void Medium::createPhases(BaseLib::ConfigTree const& config)
{
std::set<std::string> phase_names;
for (auto phase_config : config.getConfigSubtreeList("phase"))
{
auto const phase_name =
phase_config.getConfigParameter<std::string>("name");
if (phase_name.empty())
OGS_FATAL("Phase name is a mandatory field and cannot be empty.");
auto newPhase = std::make_unique<Phase>(phase_name);
// Parsing the components
auto const components_config =
phase_config.getConfigSubtreeOptional("components");
if (components_config)
newPhase->createComponents(components_config.get());
// Properties of phases are optional
auto const properties_config =
phase_config.getConfigSubtreeOptional("properties");
if (properties_config)
newPhase->createProperties(properties_config.get());
if (!components_config && !properties_config)
OGS_FATAL(
"Neither tag <components> nor tag <properties> has been "
"found.");
phase_names.insert(phase_name);
_phases.push_back(std::move(newPhase));
}
if (phase_names.size() != _phases.size())
OGS_FATAL(
"Found duplicates with the same phase name tag inside a medium.");
}
void Medium::createProperties(BaseLib::ConfigTree const& config)
{
for (auto property_config : config.getConfigSubtreeList("property"))
{
// create a new Property based on configuration tree
auto property = newProperty(property_config, this);
/// parse the name of the property
auto const property_name =
property_config.getConfigParameter<std::string>("name");
// insert the newly created property at the right place
// into the property array
_properties[convertStringToProperty(property_name)] =
std::move(property);
}
}
void Medium::createDefaultProperties()
{
for (std::size_t i = 0; i < number_of_property_enums; ++i)
{
this->_properties[i] = std::make_unique<Undefined>((PropertyEnum)i);
}
}
Phase& Medium::phase(std::size_t const index) const
{
return *_phases[index];
}
Phase& Medium::phase(std::string const& name) const
{
return *BaseLib::findElementOrError(
_phases.begin(), _phases.end(),
[&name](std::unique_ptr<MaterialPropertyLib::Phase> const& p) {
return getString(p->property(
MaterialPropertyLib::PropertyEnum::name)) == name;
},
"Could not find phase name '" + name + "'.");
}
Property& Medium::property(PropertyEnum const& p) const
{
return *_properties[p];
}
std::size_t Medium::numberOfPhases() const
{
return _phases.size();
}
} // namespace MaterialPropertyLib
/**
* \author Norbert Grunwald
* \date 07.09.2017
*
* \copyright
* Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include "BaseLib/ConfigTree.h"
#include "mpPhase.h"
#include "mpProperty.h"
#include <memory>
#include <vector>
namespace MaterialPropertyLib
{
/// This class is for material objects on the Medium scale.
///
/// A Medium consists of an arbitrarily long vector of phases and an array of
/// properties.
class Medium
{
private:
/// The vector that holds the phases.
std::vector<std::unique_ptr<Phase>> _phases;
/// The array that holds the medium properties.
PropertyArray _properties;
public:
/// This constructor parses the "phases" and "properties" subtrees of the
/// config tree and calls create methods for the phase vector and the
/// properties array. Medium properties are optional. If not defined,
/// default properties are assigned.
Medium(BaseLib::ConfigTree const& config);
/// A method that parses the phase details and stores them in the
/// private _phases member.
///
/// This method creates the phases of the medium. Unlike a medium, a phase
/// may have a name. However, this is silly at the moment since this name
/// still has no effect (except of some benefits in regard of readability).
/// Phase components are required (a phase consists of at least one
/// component). Phase properties are optional. If not given, default
/// properties are assigned. These default properties average the component
/// properties, weighted by mole fraction.
void createPhases(BaseLib::ConfigTree const& config);
/// A method that parses the medium property details and stores
/// them in the private _properties member.
///
/// This method creates the properties of the Medium as defined in the
/// prj-file. Only specified properties overwrite the default properties.
void createProperties(BaseLib::ConfigTree const& config);
/// A method that creates the default properties of the medium. Currently,
/// these defaults is the volume fraction average.
///
/// Most properties are fine with the volume fraction average, but
/// special-defaults are allowed as well...
void createDefaultProperties();
/// A get-function for a particular phase. The ul argument specifies the
/// index within the _phases vector.
Phase& phase(std::size_t index) const;
/// A get-function for a particular phase by phase name.
Phase& phase(std::string const& phase_name) const;
/// A get-function for a property. The argument refers to the name of the
/// property.
Property& property(PropertyEnum const& p) const;
/// A simple get-function for retrieving the number of phases the medium
/// consists of.
std::size_t numberOfPhases() const;
};
} // namespace MaterialPropertyLib
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment