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

Merge branch 'MplMediaMaterialIdsErrorHandling' into 'master'

MPL: Improve error report on media/material ids mismatch

See merge request ogs/ogs!5111
parents 6e1b1170 121f60c0
No related branches found
No related tags found
No related merge requests found
......@@ -23,6 +23,7 @@
#include <range/v3/action/unique.hpp>
#include <range/v3/algorithm/contains.hpp>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/adjacent_remove_if.hpp>
#include <set>
#include "BaseLib/Algorithm.h"
......@@ -355,6 +356,61 @@ 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;
......@@ -560,40 +616,27 @@ void ProjectData::parseMedia(
//! \ogs_file_param{prj__media__medium}
media_config->getConfigSubtreeList("medium"))
{
auto material_id_string =
auto create_medium = [dim = _mesh_vec[0]->getDimension(),
&medium_config, this](int const id)
{
return MaterialPropertyLib::createMedium(
id, _mesh_vec[0]->getDimension(), medium_config, _parameters,
_local_coordinate_system ? &*_local_coordinate_system : nullptr,
_curves);
};
auto const material_id_string =
//! \ogs_file_attr{prj__media__medium__id}
medium_config.getConfigAttribute<std::string>("id", "0");
auto const material_ids_of_this_medium =
BaseLib::splitMaterialIdString(material_id_string);
std::vector<int> const material_ids_of_this_medium =
parseMaterialIdString(material_id_string,
materialIDs(*_mesh_vec[0]));
for (auto const& id : material_ids_of_this_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] = MaterialPropertyLib::createMedium(
id, _mesh_vec[0]->getDimension(), medium_config,
_parameters,
_local_coordinate_system ? &*_local_coordinate_system
: nullptr,
_curves);
}
else
{
// This medium has multiple material IDs assigned and this is
// not the first material ID. Therefore we can reuse the medium
// we created before.
_media[id] = _media[material_ids_of_this_medium[0]];
}
createMediumForId(id, _media, material_ids_of_this_medium,
create_medium);
}
}
......
......@@ -11,6 +11,11 @@
*/
#include "MaterialSpatialDistributionMap.h"
#include <spdlog/fmt/bundled/core.h>
#include <spdlog/fmt/bundled/ranges.h>
#include <range/v3/view/map.hpp>
#include "MeshLib/Mesh.h"
namespace MaterialPropertyLib
......@@ -28,7 +33,36 @@ Medium const* MaterialSpatialDistributionMap::getMedium(
auto const material_id =
material_ids_ == nullptr ? 0 : (*material_ids_)[element_id];
return media_.at(material_id).get();
assert(!media_.empty());
if (auto const it = media_.find(material_id); it != media_.end())
{
return it->second.get();
}
//
// Error handling until end of the function.
//
if (material_ids_ == nullptr)
{
assert(material_id == 0);
ERR("No MaterialIDs given in the mesh therefore default material id = "
"0 is used.");
}
auto keys = media_ | ranges::views::keys;
if (media_.size() == 1)
{
ERR("Single medium for material id {} is defined.",
fmt::join(keys, ", "));
}
else
{
ERR("Media for material ids {} are defined.", fmt::join(keys, ", "));
}
OGS_FATAL("No medium for material id {} found for element {}.", material_id,
element_id);
}
void MaterialSpatialDistributionMap::checkElementHasMedium(
......
......@@ -16,7 +16,7 @@
</process>
</processes>
<media>
<medium id="0,1,2">
<medium id="*">
<properties>
<property>
<name>diffusion</name>
......
......@@ -30,7 +30,7 @@
</process>
</processes>
<media>
<medium id="0,1,2">
<medium id="*">
<phases>
<phase>
<type>AqueousLiquid</type>
......
......@@ -26,7 +26,7 @@
</process>
</processes>
<media>
<medium id="0,1,2,3,4,5,6,7,8,9">
<medium id="*">
<phases>
<phase>
<type>AqueousLiquid</type>
......
......@@ -33,7 +33,7 @@
</process>
</processes>
<media>
<medium id="0">
<medium id="*">
<phases>
<phase>
<type>AqueousLiquid</type>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment