Skip to content
Snippets Groups Projects
Commit 6555bafe authored by Dmitri Naumov's avatar Dmitri Naumov
Browse files

Move media creation related fcts to MaterialLib

parent 057008cf
No related branches found
No related tags found
No related merge requests found
......@@ -37,6 +37,7 @@
#include "GeoLib/Raster.h"
#include "InfoLib/CMakeInfo.h"
#include "MaterialLib/MPL/CreateMedium.h"
#include "MaterialLib/Utils/MediaCreation.h"
#include "MathLib/Curve/CreatePiecewiseLinearCurve.h"
#if defined(USE_LIS)
#include "MathLib/LinAlg/EigenLis/LinearSolverOptionsParser.h"
......@@ -356,61 +357,6 @@ std::vector<GeoLib::NamedRaster> readRasters(
// }
//}
std::vector<int> parseMaterialIdString(
std::string const& material_id_string,
MeshLib::PropertyVector<int> const* const material_ids)
{
if (material_id_string == "*")
{
if (material_ids == nullptr)
{
OGS_FATAL(
"MaterialIDs property is not defined in the mesh but it is "
"required to parse '*' definition.");
}
std::vector<int> material_ids_of_this_medium =
*material_ids |
ranges::views::adjacent_remove_if(std::equal_to<>()) |
ranges::to_vector;
BaseLib::makeVectorUnique(material_ids_of_this_medium);
DBUG("Catch all medium definition for material ids {}.",
fmt::join(material_ids_of_this_medium, ", "));
return material_ids_of_this_medium;
}
// Usual case of ids separated by comma.
return BaseLib::splitMaterialIdString(material_id_string);
}
template <typename T, typename CreateMedium>
requires std::convertible_to<decltype(std::declval<CreateMedium>()(
std::declval<int>())),
std::shared_ptr<T>>
void createMediumForId(int const id,
std::map<int, std::shared_ptr<T>>& _media,
std::vector<int> const& material_ids_of_this_medium,
CreateMedium&& create_medium)
{
if (_media.find(id) != end(_media))
{
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.",
id);
}
if (id == material_ids_of_this_medium[0])
{
_media[id] = create_medium(id);
}
else
{
_media[id] = _media[material_ids_of_this_medium[0]];
}
}
} // namespace
ProjectData::ProjectData() = default;
......@@ -630,13 +576,13 @@ void ProjectData::parseMedia(
medium_config.getConfigAttribute<std::string>("id", "0");
std::vector<int> const material_ids_of_this_medium =
parseMaterialIdString(material_id_string,
MaterialLib::parseMaterialIdString(material_id_string,
materialIDs(*_mesh_vec[0]));
for (auto const& id : material_ids_of_this_medium)
{
createMediumForId(id, _media, material_ids_of_this_medium,
create_medium);
MaterialLib::createMediumForId(
id, _media, material_ids_of_this_medium, create_medium);
}
}
......
......@@ -132,56 +132,4 @@ std::string getUniqueName(std::vector<std::string> const& existing_names,
}
return result_name;
}
std::vector<int> splitMaterialIdString(std::string const& material_id_string)
{
auto const material_ids_strings =
BaseLib::splitString(material_id_string, ',');
std::vector<int> material_ids;
for (auto& mid_str : material_ids_strings)
{
std::size_t num_chars_processed = 0;
int material_id;
try
{
material_id = std::stoi(mid_str, &num_chars_processed);
}
catch (std::invalid_argument&)
{
OGS_FATAL(
"Could not parse material ID from '{}' to a valid "
"integer.",
mid_str);
}
catch (std::out_of_range&)
{
OGS_FATAL(
"Could not parse material ID from '{}'. The integer value "
"of the given string exceeds the permitted range.",
mid_str);
}
if (num_chars_processed != mid_str.size())
{
// Not the whole string has been parsed. Check the rest.
if (auto const it = std::find_if_not(
begin(mid_str) + num_chars_processed, end(mid_str),
[](unsigned char const c) { return std::isspace(c); });
it != end(mid_str))
{
OGS_FATAL(
"Could not parse material ID from '{}'. Please "
"separate multiple material IDs by comma only. "
"Invalid character: '{}' at position {}.",
mid_str, *it, distance(begin(mid_str), it));
}
}
material_ids.push_back(material_id);
};
return material_ids;
}
} // end namespace BaseLib
......@@ -83,9 +83,4 @@ std::string randomString(std::size_t length);
//! Append '-' and a number such that the name is unique.
std::string getUniqueName(std::vector<std::string> const& existing_names,
std::string const& input_name);
/// Parses a comma separated list of integers.
/// Such lists occur in the medium definition in the OGS prj file.
/// Error messages in this function refer to this specific purpose.
std::vector<int> splitMaterialIdString(std::string const& material_id_string);
} // end namespace BaseLib
add_subdirectory(SolidModels)
add_subdirectory(FractureModels)
add_subdirectory(Utils)
# Source files
get_source_files(SOURCES)
......@@ -42,7 +43,7 @@ ogs_add_library(
target_link_libraries(
MaterialLib PUBLIC BaseLib Eigen3::Eigen MaterialLib_SolidModels
MaterialLib_FractureModels
MaterialLib_FractureModels MaterialLib_Utils
PRIVATE MathLib MeshLib ParameterLib exprtk Boost::math
)
......
......@@ -11,7 +11,7 @@
#pragma once
#include "BaseLib/ConfigTree.h"
#include "BaseLib/StringTools.h"
#include "MaterialLib/Utils/MediaCreation.h"
#include "ParameterLib/Parameter.h"
namespace MaterialLib::Solids
......@@ -44,7 +44,7 @@ createConstitutiveRelationsGeneric(
"0");
auto const material_ids_of_this_constitutive_relation =
BaseLib::splitMaterialIdString(material_id_string);
MaterialLib::splitMaterialIdString(material_id_string);
auto first_relation_for_material_id = constitutive_relations.end();
for (auto const& material_id :
......
get_source_files(SOURCES)
ogs_add_library(MaterialLib_Utils ${SOURCES})
target_link_libraries(MaterialLib_Utils PRIVATE BaseLib MeshLib)
/**
* \file
* \copyright
* Copyright (c) 2012-2024, 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 <range/v3/range/conversion.hpp>
#include <range/v3/view/adjacent_remove_if.hpp>
#include "BaseLib/Algorithm.h"
#include "BaseLib/Logging.h"
#include "BaseLib/StringTools.h"
#include "MeshLib/PropertyVector.h"
namespace MaterialLib
{
std::vector<int> splitMaterialIdString(std::string const& material_id_string)
{
auto const material_ids_strings =
BaseLib::splitString(material_id_string, ',');
std::vector<int> material_ids;
for (auto& mid_str : material_ids_strings)
{
std::size_t num_chars_processed = 0;
int material_id;
try
{
material_id = std::stoi(mid_str, &num_chars_processed);
}
catch (std::invalid_argument&)
{
OGS_FATAL(
"Could not parse material ID from '{}' to a valid integer.",
mid_str);
}
catch (std::out_of_range&)
{
OGS_FATAL(
"Could not parse material ID from '{}'. The integer value of "
"the given string exceeds the permitted range.",
mid_str);
}
if (num_chars_processed != mid_str.size())
{
// Not the whole string has been parsed. Check the rest.
if (auto const it = std::find_if_not(
begin(mid_str) + num_chars_processed, end(mid_str),
[](unsigned char const c) { return std::isspace(c); });
it != end(mid_str))
{
OGS_FATAL(
"Could not parse material ID from '{}'. Please separate "
"multiple material IDs by comma only. Invalid character: "
"'{}' at position {}.",
mid_str, *it, distance(begin(mid_str), it));
}
}
material_ids.push_back(material_id);
};
return material_ids;
}
std::vector<int> parseMaterialIdString(
std::string const& material_id_string,
MeshLib::PropertyVector<int> const* const material_ids)
{
if (material_id_string == "*")
{
if (material_ids == nullptr)
{
OGS_FATAL(
"MaterialIDs property is not defined in the mesh but it is "
"required to parse '*' definition.");
}
std::vector<int> material_ids_of_this_medium =
*material_ids |
ranges::views::adjacent_remove_if(std::equal_to<>()) |
ranges::to_vector;
BaseLib::makeVectorUnique(material_ids_of_this_medium);
DBUG("Catch all medium definition for material ids {}.",
fmt::join(material_ids_of_this_medium, ", "));
return material_ids_of_this_medium;
}
// Usual case of ids separated by comma.
return splitMaterialIdString(material_id_string);
}
} // namespace MaterialLib
/**
* \file
* \copyright
* Copyright (c) 2012-2024, 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 <map>
#include <memory>
#include <string>
#include <vector>
#include "BaseLib/Error.h"
namespace MeshLib
{
template <typename PROP_VAL_TYPE>
class PropertyVector;
} // namespace MeshLib
namespace MaterialLib
{
/// Parses a comma separated list of integers.
/// Such lists occur in the medium definition in the OGS prj file.
/// Error messages in this function refer to this specific purpose.
std::vector<int> splitMaterialIdString(std::string const& material_id_string);
/// Parses a comma separated list of integers or "*" string.
/// Such lists occur in the medium definition in the OGS prj file.
/// For the "*" input a vector of all (unique) material ids is returned.
/// Error messages in this function refer to this specific purpose.
std::vector<int> parseMaterialIdString(
std::string const& material_id_string,
MeshLib::PropertyVector<int> const* const material_ids);
/// Creates a new entry for the material id in the media map by either calling
/// the create_medium function and creating a new shared pointer, or by reusing
/// the existing shared pointer.
template <typename T, typename CreateMedium>
requires std::convertible_to<
decltype(std::declval<CreateMedium>()(std::declval<int>())),
std::shared_ptr<T>>
void createMediumForId(int const id,
std::map<int, std::shared_ptr<T>>& media,
std::vector<int> const& material_ids_of_this_medium,
CreateMedium&& create_medium)
{
if (media.find(id) != end(media))
{
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.",
id);
}
if (id == material_ids_of_this_medium[0])
{
media[id] = create_medium(id);
}
else
{
media[id] = media[material_ids_of_this_medium[0]];
}
}
} // namespace MaterialLib
......@@ -14,7 +14,7 @@
#include "BaseLib/Algorithm.h"
#include "BaseLib/ConfigTree.h"
#include "BaseLib/StringTools.h" // required for splitMaterialIDString
#include "MaterialLib/Utils/MediaCreation.h" // required for splitMaterialIDString
#include "MeshLib/Mesh.h"
#include "MeshLib/Utils/createMaterialIDsBasedSubMesh.h"
#include "MeshLib/Utils/transformMeshToNodePartitionedMesh.h"
......@@ -50,7 +50,7 @@ std::string parseOutputMeshConfig(
}
auto const material_ids_for_output =
BaseLib::splitMaterialIdString(*material_id_string);
MaterialLib::splitMaterialIdString(*material_id_string);
#ifdef USE_PETSC
// this mesh isn't yet a NodePartitionedMesh
auto subdomain_mesh = MeshLib::createMaterialIDsBasedSubMesh(
......
......@@ -13,16 +13,16 @@
#include <algorithm>
#include "BaseLib/StringTools.h"
#include "MaterialLib/Utils/MediaCreation.h"
using namespace BaseLib;
using namespace MaterialLib;
TEST(BaseLib_SplitIntegerList, EmptyList)
TEST(MaterialLib_SplitIntegerList, EmptyList)
{
ASSERT_TRUE(splitMaterialIdString("").empty());
}
TEST(BaseLib_SplitIntegerList, SingleInt)
TEST(MaterialLib_SplitIntegerList, SingleInt)
{
using namespace testing;
......@@ -41,7 +41,7 @@ TEST(BaseLib_SplitIntegerList, SingleInt)
ContainerEq(std::vector<int>{-20}));
}
TEST(BaseLib_SplitIntegerList, SingleIntFail)
TEST(MaterialLib_SplitIntegerList, SingleIntFail)
{
// wrong character prefix/suffix
EXPECT_THROW(splitMaterialIdString("x"), std::runtime_error);
......@@ -62,7 +62,7 @@ TEST(BaseLib_SplitIntegerList, SingleIntFail)
std::runtime_error);
}
TEST(BaseLib_SplitIntegerList, IntList)
TEST(MaterialLib_SplitIntegerList, IntList)
{
using namespace testing;
......@@ -78,20 +78,20 @@ TEST(BaseLib_SplitIntegerList, IntList)
ContainerEq(std::vector<int>{20, 22, 24}));
}
TEST(BaseLib_SplitIntegerList, IntListFail)
TEST(MaterialLib_SplitIntegerList, IntListFail)
{
// only delimiter
EXPECT_THROW(BaseLib::splitMaterialIdString(","), std::runtime_error);
EXPECT_THROW(splitMaterialIdString(","), std::runtime_error);
// empty element
EXPECT_THROW(BaseLib::splitMaterialIdString("5,,6"), std::runtime_error);
EXPECT_THROW(splitMaterialIdString("5,,6"), std::runtime_error);
// leading comma
EXPECT_THROW(BaseLib::splitMaterialIdString(",40"), std::runtime_error);
EXPECT_THROW(splitMaterialIdString(",40"), std::runtime_error);
// missing comma
EXPECT_THROW(BaseLib::splitMaterialIdString("12 20"), std::runtime_error);
EXPECT_THROW(splitMaterialIdString("12 20"), std::runtime_error);
// wrong number in the list
EXPECT_THROW(BaseLib::splitMaterialIdString("1,2,x,5"), std::runtime_error);
EXPECT_THROW(splitMaterialIdString("1,2,x,5"), std::runtime_error);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment