OGS
MeshToolsLib Namespace Reference

Namespaces

namespace  anonymous_namespace{AngleSkewMetric.cpp}
namespace  anonymous_namespace{ConvertToLinearMesh.cpp}
namespace  BoundaryExtraction
namespace  MeshGenerator
namespace  MeshGenerators
namespace  ProjectPointOnMesh
namespace  RasterDataToMesh
 Adding pixel values from a raster onto nodes or cells of a mesh.

Classes

struct  AngleSkewMetric
struct  EdgeRatioMetric
class  ElementQualityInterface
class  ElementQualityMetric
class  ElementSizeMetric
class  ElementValueModification
 A set of methods for manipulating mesh element values. More...
class  Mesh2MeshPropertyInterpolation
class  MeshInformation
 A set of tools for extracting information from a mesh. More...
class  MeshLayerMapper
 Manipulating and adding prism element layers to an existing 2D mesh. More...
class  MeshRevision
class  MeshSurfaceExtraction
 A set of tools concerned with extracting nodes and elements from a mesh surface. More...
struct  MeshValidation
 A collection of methods for testing mesh quality and correctness. More...
struct  NodesPartitionResult
struct  RadiusEdgeRatioMetric
class  RasterToMesh
 Converts raster data into an OGS mesh. More...
struct  SizeDifferenceMetric

Functions

template<typename ShapeFunction>
double computeElementVolumeNumerically (MeshLib::Element const &e)
double computeElementVolumeNumerically (MeshLib::Element const &e)
bool convertMeshToGeo (const MeshLib::Mesh &mesh, GeoLib::GEOObjects &geo_objects, double const eps)
MeshLib::MeshconvertSurfaceToMesh (const GeoLib::Surface &sfc, const std::string &mesh_name, double eps)
template<typename ElementType>
int getNumberOfElementIntegrationPointsGeneral (MeshLib::IntegrationPointMetaDataSingleField const &ip_meta_data)
int getNumberOfElementIntegrationPoints (MeshLib::IntegrationPointMetaDataSingleField const &ip_meta_data, MeshLib::Element const &e)
std::vector< std::size_t > getIntegrationPointDataOffsetsOfMeshElements (std::vector< MeshLib::Element * > const &mesh_elements, MeshLib::PropertyVectorBase const &pv, MeshLib::Properties const &properties)
MeshLib::ElementextrudeElement (std::vector< MeshLib::Node * > const &subsfc_nodes, MeshLib::Element const &sfc_elem, MeshLib::PropertyVector< std::size_t > const &sfc_to_subsfc_id_map, std::map< std::size_t, std::size_t > const &subsfc_sfc_id_map)
MeshLib::MeshaddLayerToMesh (MeshLib::Mesh const &mesh, double const thickness, std::string const &name, bool const on_top, bool const copy_material_ids, std::optional< int > const layer_id)
std::unique_ptr< MeshLib::MeshconvertToLinearMesh (MeshLib::Mesh const &mesh, std::string const &new_mesh_name)
std::unique_ptr< MeshLib::ElementcreateFlippedElement (MeshLib::Element const &elem, std::vector< MeshLib::Node * > const &nodes)
std::unique_ptr< MeshLib::MeshcreateFlippedMesh (MeshLib::Mesh const &mesh)
template<typename T>
void setSigma0 (int const pv_num_components, MeshLib::PropertyVector< T > const *const pv_bulk_mesh, std::unordered_map< std::string, double > &initial_value_dict, MeshLib::PropertyVector< T > &new_pv)
template<typename T>
bool createNodeProperties (MeshLib::Mesh &merged_mesh, std::string const &pv_name, int const pv_num_components, MeshLib::PropertyVector< T > const *const pv_bulk_mesh, std::unordered_map< std::string, double > &initial_value_dict)
template<typename T>
bool createCellProperties (MeshLib::Mesh &merged_mesh, std::string const &pv_name, int const pv_num_components, MeshLib::PropertyVector< T > const *const pv_bulk_mesh, std::unordered_map< std::string, double > &initial_value_dict)
template<typename T>
bool createIntegrationPointProperties (MeshLib::Mesh &merged_mesh, std::string const &pv_name, int const pv_num_components, MeshLib::PropertyVector< T > const *const pv_bulk_mesh, std::unordered_map< std::string, double > &initial_value_dict, std::optional< MeshLib::IntegrationPointMetaData > const &integration_point_meta_data)
template<typename T>
bool createMergedPropertyVector (MeshLib::Mesh &merged_mesh, std::unordered_map< std::string, double > &initial_value_dict, MeshLib::PropertyVector< T > const *const pv_bulk_mesh, std::optional< MeshLib::IntegrationPointMetaData > const &integration_point_meta_data)
std::vector< MeshLib::Node * > findNodesInBoundedDomain (std::vector< MeshLib::Node * > const &nodes, GeoLib::AABB const &aabb)
std::unique_ptr< MeshLib::MeshmergeMeshToBulkMesh (MeshLib::Mesh const &bulk_mesh, MeshLib::Mesh const &other_mesh, std::unordered_map< std::string, double > &initial_value_dict)
unsigned lutPrismThirdNode (unsigned const id1, unsigned const id2)
template<typename Iterator>
void moveMeshNodes (Iterator begin, Iterator end, Eigen::Vector3d const &displacement)
NodesPartitionResult partitionNodesByCoordinateMatch (std::vector< MeshLib::Node * > const &node_vector, std::vector< MeshLib::Node * > const &tool_node_vector, GeoLib::AABB const &aabb, bool const return_non_paired_nodes)
MeshLib::MeshremoveElements (const MeshLib::Mesh &mesh, const std::vector< std::size_t > &removed_element_ids, const std::string &new_mesh_name)
std::vector< bool > markUnusedNodes (std::vector< MeshLib::Element * > const &elements, std::vector< MeshLib::Node * > const &nodes)
 Marks nodes not used by any of the elements.
void removeMarkedNodes (std::vector< bool > const &nodes_to_delete, std::vector< MeshLib::Node * > &nodes)
 Deallocates and removes nodes marked true.
MeshLib::MeshremoveNodes (const MeshLib::Mesh &mesh, const std::vector< std::size_t > &del_nodes_idx, const std::string &new_mesh_name)
std::unique_ptr< MeshLib::MeshcreateQuadraticOrderMesh (MeshLib::Mesh const &linear_mesh, bool const add_centre_node)
static void trackSurface (MeshLib::Element const *const element, std::vector< unsigned > &sfc_idx, unsigned const current_index)
template<typename T>
void processPropertyVector (MeshLib::PropertyVector< T > const &property, std::vector< std::size_t > const &id_map, MeshLib::Mesh &sfc_mesh)
bool createSfcMeshProperties (MeshLib::Mesh &sfc_mesh, MeshLib::Properties const &properties, std::vector< std::size_t > const &node_ids_map, std::vector< std::size_t > const &element_ids_map)
std::tuple< std::vector< MeshLib::Node * >, std::vector< std::size_t > > createNodesAndIDMapFromElements (std::vector< MeshLib::Element * > const &elements, std::size_t const n_all_nodes)
void createSurfaceElementsFromElement (MeshLib::Element const &surface_element, std::vector< MeshLib::Element * > &surface_elements, std::vector< std::size_t > &element_to_bulk_element_id_map, std::vector< std::size_t > &element_to_bulk_face_id_map)
std::tuple< std::vector< MeshLib::Element * >, std::vector< std::size_t >, std::vector< std::size_t > > createBoundaryElements (MeshLib::Mesh const &bulk_mesh)
void addBulkIDPropertiesToMesh (MeshLib::Mesh &surface_mesh, std::string_view node_to_bulk_node_id_map_name, std::vector< std::size_t > const &node_to_bulk_node_id_map, std::string_view element_to_bulk_element_id_map_name, std::vector< std::size_t > const &element_to_bulk_element_id_map, std::string_view element_to_bulk_face_id_map_name, std::vector< std::size_t > const &element_to_bulk_face_id_map)
void zeroMeshFieldDataByMaterialIDs (MeshLib::Mesh &mesh, std::vector< int > const &selected_material_ids)

Function Documentation

◆ addBulkIDPropertiesToMesh()

void MeshToolsLib::addBulkIDPropertiesToMesh ( MeshLib::Mesh & surface_mesh,
std::string_view node_to_bulk_node_id_map_name,
std::vector< std::size_t > const & node_to_bulk_node_id_map,
std::string_view element_to_bulk_element_id_map_name,
std::vector< std::size_t > const & element_to_bulk_element_id_map,
std::string_view element_to_bulk_face_id_map_name,
std::vector< std::size_t > const & element_to_bulk_face_id_map )

Definition at line 521 of file MeshSurfaceExtraction.cpp.

529{
530 // transmit the original node ids of the bulk mesh as a property
531 if (!node_to_bulk_node_id_map_name.empty())
532 {
534 surface_mesh, node_to_bulk_node_id_map_name,
535 MeshLib::MeshItemType::Node, 1, {node_to_bulk_node_id_map});
536 }
537
538 // transmit the original bulk element ids as a property
539 if (!element_to_bulk_element_id_map_name.empty())
540 {
542 surface_mesh, element_to_bulk_element_id_map_name,
543 MeshLib::MeshItemType::Cell, 1, {element_to_bulk_element_id_map});
544 }
545
546 // transmit the face id of the original bulk element as a property
547 if (!element_to_bulk_face_id_map_name.empty())
548 {
550 surface_mesh, element_to_bulk_face_id_map_name,
551 MeshLib::MeshItemType::Cell, 1, {element_to_bulk_face_id_map});
552 }
553}
void addPropertyToMesh(Mesh &mesh, std::string_view name, MeshItemType item_type, std::size_t number_of_components, std::span< T const > values)

References MeshLib::addPropertyToMesh(), MeshLib::Cell, and MeshLib::Node.

Referenced by MeshToolsLib::BoundaryExtraction::getBoundaryElementsAsMesh(), and MeshToolsLib::MeshSurfaceExtraction::getMeshSurface().

◆ addLayerToMesh()

MeshLib::Mesh * MeshToolsLib::addLayerToMesh ( MeshLib::Mesh const & mesh,
double const thickness,
std::string const & name,
bool const on_top,
bool const copy_material_ids,
std::optional< int > const layer_id )

Adds a layer to the mesh. If on_top is true, the layer is added on top, if it is false, the layer is added at the bottom.

Definition at line 81 of file AddLayerToMesh.cpp.

85{
86 INFO("Extracting top surface of mesh '{:s}' ... ", mesh.getName());
87 double const flag = on_top ? -1.0 : 1.0;
88 Eigen::Vector3d const dir({0, 0, flag});
89 double const angle(90);
90 std::unique_ptr<MeshLib::Mesh> sfc_mesh(nullptr);
91
92 auto const prop_name =
94
95 if (mesh.getDimension() == 3)
96 {
98 mesh, dir, angle, prop_name));
99 }
100 else
101 {
102 sfc_mesh = (on_top) ? std::make_unique<MeshLib::Mesh>(mesh)
103 : std::unique_ptr<MeshLib::Mesh>(
105 // add property storing node ids
106 auto* const pv =
107 sfc_mesh->getProperties().createNewPropertyVector<std::size_t>(
109 sfc_mesh->getNumberOfNodes(), 1);
110 if (pv)
111 {
112 pv->assign(ranges::views::iota(0u, sfc_mesh->getNumberOfNodes()));
113 }
114 else
115 {
116 ERR("Could not create and initialize property '{}'.", prop_name);
117 return nullptr;
118 }
119 }
120 INFO("done.");
121
122 // *** add new surface nodes
123 std::vector<MeshLib::Node*> subsfc_nodes =
124 MeshLib::copyNodeVector(mesh.getNodes());
125 std::vector<MeshLib::Element*> subsfc_elements =
126 MeshLib::copyElementVector(mesh.getElements(), subsfc_nodes);
127
128 std::size_t const n_subsfc_nodes(subsfc_nodes.size());
129
130 std::vector<MeshLib::Node*> const& sfc_nodes(sfc_mesh->getNodes());
131 std::size_t const n_sfc_nodes(sfc_nodes.size());
132
133 if (!sfc_mesh->getProperties().existsPropertyVector<std::size_t>(prop_name))
134 {
135 ERR("Need subsurface node ids, but the property '{:s}' is not "
136 "available.",
137 prop_name);
138 return nullptr;
139 }
140 // fetch subsurface node ids PropertyVector
141 auto const* const node_id_pv =
142 sfc_mesh->getProperties().getPropertyVector<std::size_t>(prop_name);
143
144 // *** copy sfc nodes to subsfc mesh node
145 std::map<std::size_t, std::size_t> subsfc_sfc_id_map;
146 for (std::size_t k(0); k < n_sfc_nodes; ++k)
147 {
148 std::size_t const subsfc_id((*node_id_pv)[k]);
149 std::size_t const sfc_id(k + n_subsfc_nodes);
150 subsfc_sfc_id_map.insert(std::make_pair(subsfc_id, sfc_id));
151 MeshLib::Node const& node(*sfc_nodes[k]);
152 subsfc_nodes.push_back(new MeshLib::Node(
153 node[0], node[1], node[2] - (flag * thickness), sfc_id));
154 }
155
156 // *** insert new layer elements into subsfc_mesh
157 std::vector<MeshLib::Element*> const& sfc_elements(sfc_mesh->getElements());
158 std::size_t const n_sfc_elements(sfc_elements.size());
159 for (std::size_t k(0); k < n_sfc_elements; ++k)
160 {
161 subsfc_elements.push_back(extrudeElement(
162 subsfc_nodes, *sfc_elements[k], *node_id_pv, subsfc_sfc_id_map));
163 }
164
165 auto new_mesh = new MeshLib::Mesh(name, subsfc_nodes, subsfc_elements,
166 true /* compute_element_neighbors */);
167
168 if (!mesh.getProperties().existsPropertyVector<int>("MaterialIDs"))
169 {
170 ERR("Could not copy the property 'MaterialIDs' since the original mesh "
171 "does not contain such a property.");
172 return new_mesh;
173 }
174 auto const* const materials =
175 mesh.getProperties().getPropertyVector<int>("MaterialIDs");
176
177 auto* const new_materials =
178 new_mesh->getProperties().createNewPropertyVector<int>(
179 "MaterialIDs", MeshLib::MeshItemType::Cell, 1);
180 if (!new_materials)
181 {
182 ERR("Can not set material properties for new layer");
183 return new_mesh;
184 }
185
186 int next_material_id = 0; // default, if materials are not available.
187
188 if (materials != nullptr)
189 {
190 next_material_id = *ranges::max_element(*materials) + 1;
191 }
192
193 auto initial_values =
194 materials ? ranges::any_view<int const>{*materials}
195 : ranges::views::repeat_n(layer_id.value_or(next_material_id),
196 mesh.getNumberOfElements());
197
198 auto additional_values = [&]() -> ranges::any_view<int const>
199 {
200 if (copy_material_ids &&
201 sfc_mesh->getProperties().existsPropertyVector<int>("MaterialIDs"))
202 {
203 return ranges::any_view<int const>{
204 *sfc_mesh->getProperties().getPropertyVector<int>(
205 "MaterialIDs")};
206 }
207 else
208 {
209 int const new_layer_id = layer_id.value_or(next_material_id);
210 auto const n_new_props =
211 subsfc_elements.size() - mesh.getNumberOfElements();
212 return ranges::views::repeat_n(new_layer_id, n_new_props);
213 }
214 }();
215
216 new_materials->assign(ranges::views::common(
217 ranges::views::concat(initial_values, additional_values)));
218 return new_mesh;
219}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
static MeshLib::Mesh * getMeshSurface(const MeshLib::Mesh &subsfc_mesh, Eigen::Vector3d const &dir, double angle, std::string_view subsfc_node_id_prop_name="", std::string_view subsfc_element_id_prop_name="", std::string_view face_id_prop_name="")
std::vector< Node * > copyNodeVector(const std::vector< Node * > &nodes)
Creates a deep copy of a Node vector.
constexpr std::string_view getBulkIDString(MeshItemType mesh_item_type)
std::vector< Element * > copyElementVector(std::vector< Element * > const &elements, std::vector< Node * > const &new_nodes, std::vector< std::size_t > const *const node_id_map)
std::unique_ptr< MeshLib::Mesh > createFlippedMesh(MeshLib::Mesh const &mesh)
MeshLib::Element * extrudeElement(std::vector< MeshLib::Node * > const &subsfc_nodes, MeshLib::Element const &sfc_elem, MeshLib::PropertyVector< std::size_t > const &sfc_to_subsfc_id_map, std::map< std::size_t, std::size_t > const &subsfc_sfc_id_map)

References MeshLib::Cell, MeshLib::copyElementVector(), MeshLib::copyNodeVector(), createFlippedMesh(), ERR(), MeshLib::Properties::existsPropertyVector(), extrudeElement(), MeshLib::getBulkIDString(), MeshLib::Mesh::getDimension(), MeshLib::Mesh::getElements(), MeshToolsLib::MeshSurfaceExtraction::getMeshSurface(), MeshLib::Mesh::getName(), MeshLib::Mesh::getNodes(), MeshLib::Mesh::getNumberOfElements(), MeshLib::Mesh::getProperties(), MeshLib::Properties::getPropertyVector(), INFO(), and MeshLib::Node.

Referenced by MeshToolsLib::MeshGenerator::generateRegularPrismMesh(), main(), and MeshView::openAddLayerDialog().

◆ computeElementVolumeNumerically() [1/2]

template<typename ShapeFunction>
double MeshToolsLib::computeElementVolumeNumerically ( MeshLib::Element const & e)

Definition at line 39 of file ComputeElementVolumeNumerically.cpp.

40{
41 // Space dimension is set to 3 in case that 1D or 2D element is inclined.
42 constexpr int space_dim = 3;
44
45 // Integration order is set to 3:
46 auto const& integration_method =
47 NumLib::IntegrationMethodRegistry::template getIntegrationMethod<
48 typename ShapeFunction::MeshElement>(NumLib::IntegrationOrder{3});
49
50 auto const shape_function_data =
52 e, false /*is_axially_symmetric*/, integration_method);
53
54 auto const n_integration_points = integration_method.getNumberOfPoints();
55 double volume = 0.0;
56 for (unsigned ip = 0; ip < n_integration_points; ++ip)
57 {
58 auto const weight = integration_method.getWeightedPoint(ip).getWeight();
59 volume += shape_function_data[ip].detJ * weight;
60 }
61
62 return volume;
63}
EigenFixedShapeMatrixPolicy< ShapeFunction, GlobalDim > ShapeMatrixPolicyType
std::vector< typename ShapeMatricesType::ShapeMatrices, Eigen::aligned_allocator< typename ShapeMatricesType::ShapeMatrices > > initShapeMatrices(MeshLib::Element const &e, bool const is_axially_symmetric, IntegrationMethod const &integration_method)

References NumLib::initShapeMatrices().

Referenced by MeshToolsLib::ElementSizeMetric::calc1dQuality(), MeshToolsLib::ElementSizeMetric::calc2dOr3dQuality(), and computeElementVolumeNumerically().

◆ computeElementVolumeNumerically() [2/2]

double MeshToolsLib::computeElementVolumeNumerically ( MeshLib::Element const & e)

Definition at line 65 of file ComputeElementVolumeNumerically.cpp.

66{
67 switch (e.getCellType())
68 {
99 default:
100 OGS_FATAL(
101 "Numerical volume calculation is not available for element "
102 "with type {}. ",
103 MeshLib::CellType2String(e.getCellType()));
104 }
105}
#define OGS_FATAL(...)
Definition Error.h:19
std::string CellType2String(const CellType t)
Given a MeshElemType this returns the appropriate string.
double computeElementVolumeNumerically(MeshLib::Element const &e)

References MeshLib::CellType2String(), computeElementVolumeNumerically(), MeshLib::Element::getCellType(), MeshLib::HEX20, MeshLib::HEX8, MeshLib::LINE2, MeshLib::LINE3, OGS_FATAL, MeshLib::PRISM15, MeshLib::PRISM6, MeshLib::PYRAMID13, MeshLib::PYRAMID5, MeshLib::QUAD4, MeshLib::QUAD8, MeshLib::QUAD9, MeshLib::TET10, MeshLib::TET4, MeshLib::TRI3, and MeshLib::TRI6.

◆ convertMeshToGeo()

bool MeshToolsLib::convertMeshToGeo ( const MeshLib::Mesh & mesh,
GeoLib::GEOObjects & geo_objects,
double eps = std::numeric_limits< double >::epsilon() )

Converts a 2D mesh into a geometry. A new geometry with the name of the mesh will be inserted into geo_objects, consisting of points identical with mesh nodes and one surface representing the mesh. Triangles are converted to geometric triangles, quads are split into two triangles, all other elements are ignored.

Definition at line 66 of file convertMeshToGeo.cpp.

69{
70 if (mesh.getDimension() != 2)
71 {
72 ERR("Mesh to geometry conversion is only working for 2D meshes.");
73 return false;
74 }
75
76 // Special handling of the bounds in case there are no materialIDs present.
77 auto get_material_ids_and_bounds = [&]()
78 -> std::tuple<MeshLib::PropertyVector<int> const*, std::pair<int, int>>
79 {
80 auto const materialIds = materialIDs(mesh);
81 if (!materialIds)
82 {
83 return std::make_tuple(nullptr, std::make_pair(0, 0));
84 }
85
86 auto const bounds =
88 if (!bounds)
89 {
91 "Could not get minimum/maximum ranges values for the "
92 "MaterialIDs property in the mesh '{:s}'.",
93 mesh.getName());
94 }
95 return std::make_tuple(materialIds, *bounds);
96 };
97
98 auto const [materialIds, bounds] = get_material_ids_and_bounds();
99 // elements to surface triangles conversion
100 const unsigned nMatGroups(bounds.second - bounds.first + 1);
101 std::vector<GeoLib::Surface*> sfcs;
102 sfcs.reserve(nMatGroups);
103 std::string const geoobject_name =
104 convertMeshNodesToGeoPoints(mesh, eps, geo_objects);
105 auto const& points = *geo_objects.getPointVec(geoobject_name);
106 for (unsigned i = 0; i < nMatGroups; ++i)
107 {
108 sfcs.push_back(new GeoLib::Surface(points));
109 }
110
111 const std::vector<std::size_t>& id_map(
112 geo_objects.getPointVecObj(geoobject_name)->getIDMap());
113 const std::vector<MeshLib::Element*>& elements = mesh.getElements();
114 const std::size_t nElems(mesh.getNumberOfElements());
115
116 for (unsigned i = 0; i < nElems; ++i)
117 {
118 auto surfaceId = !materialIds ? 0 : ((*materialIds)[i] - bounds.first);
119 addElementToSurface(*elements[i], id_map, *sfcs[surfaceId]);
120 }
121
122 std::for_each(sfcs.begin(), sfcs.end(),
123 [](GeoLib::Surface*& sfc)
124 {
125 if (sfc->getNumberOfTriangles() == 0)
126 {
127 delete sfc;
128 sfc = nullptr;
129 }
130 });
131 auto sfcs_end = std::remove(sfcs.begin(), sfcs.end(), nullptr);
132 sfcs.erase(sfcs_end, sfcs.end());
133
134 geo_objects.addSurfaceVec(std::move(sfcs), geoobject_name,
136 return true;
137}
const std::vector< Point * > * getPointVec(const std::string &name) const
const PointVec * getPointVecObj(const std::string &name) const
void addSurfaceVec(std::vector< Surface * > &&sfc, const std::string &name, SurfaceVec::NameIdMap &&sfc_names)
const std::vector< std::size_t > & getIDMap() const
Definition PointVec.h:86
std::map< std::string, std::size_t > NameIdMap
Definition TemplateVec.h:30
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition Mesh.h:100
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
Definition Mesh.h:79
const std::string getName() const
Get name of the mesh.
Definition Mesh.h:94
std::size_t getNumberOfElements() const
Get the number of elements.
Definition Mesh.h:88
static std::optional< std::pair< T, T > > const getValueBounds(MeshLib::PropertyVector< T > const &property)
void addElementToSurface(MeshLib::Element const &e, std::vector< std::size_t > const &id_map, GeoLib::Surface &surface)
std::string convertMeshNodesToGeoPoints(MeshLib::Mesh const &mesh, double const eps, GeoLib::GEOObjects &geo_objects)

References ERR(), MeshLib::Mesh::getDimension(), MeshLib::Mesh::getElements(), GeoLib::PointVec::getIDMap(), MeshLib::Mesh::getName(), MeshLib::Mesh::getNumberOfElements(), GeoLib::GEOObjects::getPointVec(), GeoLib::GEOObjects::getPointVecObj(), MeshToolsLib::MeshInformation::getValueBounds(), and OGS_FATAL.

Referenced by MainWindow::convertMeshToGeometry(), FileIO::createSurface(), and main().

◆ convertSurfaceToMesh()

MeshLib::Mesh * MeshToolsLib::convertSurfaceToMesh ( const GeoLib::Surface & sfc,
const std::string & mesh_name,
double eps = std::numeric_limits< double >::epsilon() )

Converts a surface into a triangular mesh

Parameters
sfcSurface object
mesh_nameNew mesh name
epsMinimum distance for nodes not to be collapsed
Returns
a pointer to a converted mesh object. nullptr is returned if the conversion fails.

Definition at line 139 of file convertMeshToGeo.cpp.

142{
143 // convert to a mesh including duplicated nodes
144 std::vector<MeshLib::Node*> nodes;
145 std::vector<MeshLib::Element*> elements;
146 std::size_t nodeId = 0;
147 for (std::size_t i = 0; i < sfc.getNumberOfTriangles(); i++)
148 {
149 auto* tri = sfc[i];
150 auto** tri_nodes = new MeshLib::Node*[3];
151 for (unsigned j = 0; j < 3; j++)
152 {
153 tri_nodes[j] =
154 new MeshLib::Node(tri->getPoint(j)->data(), nodeId++);
155 }
156 elements.push_back(new MeshLib::Tri(tri_nodes, i));
157 for (unsigned j = 0; j < 3; j++)
158 {
159 nodes.push_back(tri_nodes[j]);
160 }
161 }
162 MeshLib::Mesh mesh_with_duplicated_nodes(
163 mesh_name, nodes, elements, true /* compute_element_neighbors */);
164
165 // remove duplicated nodes
166 MeshToolsLib::MeshRevision rev(mesh_with_duplicated_nodes);
167 return rev.simplifyMesh(mesh_with_duplicated_nodes.getName(), eps);
168}
std::size_t getNumberOfTriangles() const
Definition Surface.cpp:76
TemplateElement< MeshLib::TriRule3 > Tri
Definition Tri.h:15

References convertSurfaceToMesh(), MeshLib::Mesh::getName(), GeoLib::Surface::getNumberOfTriangles(), MeshLib::Node, and MeshToolsLib::MeshRevision::simplifyMesh().

Referenced by convertSurfaceToMesh(), and main().

◆ convertToLinearMesh()

std::unique_ptr< MeshLib::Mesh > MeshToolsLib::convertToLinearMesh ( const MeshLib::Mesh & mesh,
const std::string & new_mesh_name )

Converts a non-linear mesh to a linear mesh. All the mesh properties will be copied except for entries for non-linear nodes.

Definition at line 40 of file ConvertToLinearMesh.cpp.

42{
43 auto const& org_elements = mesh.getElements();
44
45 // mark base nodes
46 std::vector<bool> marked_base_nodes(mesh.getNodes().size(), false);
47 for (auto const org_element : org_elements)
48 {
49 for (std::size_t k = 0; k < org_element->getNumberOfBaseNodes(); ++k)
50 {
51 auto const& base_node = *org_element->getNode(k);
52 marked_base_nodes[base_node.getID()] = true;
53 }
54 }
55
56 // construct map and fill new_mesh_nodes
57 std::vector<MeshLib::Node*> new_mesh_nodes{static_cast<std::size_t>(
58 std::count(begin(marked_base_nodes), end(marked_base_nodes), true))};
59 std::size_t base_node_cnt = 0;
60 auto const& org_nodes = mesh.getNodes();
61 std::vector<std::size_t> base_node_map(org_nodes.size(), -1);
62 for (std::size_t k = 0; k < org_nodes.size(); ++k)
63 {
64 if (marked_base_nodes[k])
65 {
66 new_mesh_nodes[base_node_cnt] =
67 new MeshLib::Node(org_nodes[k]->data(), base_node_cnt);
68 base_node_map[k] = base_node_cnt;
69 base_node_cnt++;
70 }
71 }
72
73 // create new elements with the quadratic nodes
74 std::vector<MeshLib::Element*> vec_new_eles;
75 for (MeshLib::Element const* e : mesh.getElements())
76 {
77 if (e->getCellType() == MeshLib::CellType::LINE3)
78 {
79 vec_new_eles.push_back(createLinearElement<MeshLib::Line>(
80 e, new_mesh_nodes, base_node_map));
81 }
82 else if (e->getCellType() == MeshLib::CellType::QUAD8)
83 {
84 vec_new_eles.push_back(createLinearElement<MeshLib::Quad>(
85 e, new_mesh_nodes, base_node_map));
86 }
87 else if (e->getCellType() == MeshLib::CellType::TRI6)
88 {
89 vec_new_eles.push_back(createLinearElement<MeshLib::Tri>(
90 e, new_mesh_nodes, base_node_map));
91 }
92 else if (e->getCellType() == MeshLib::CellType::HEX20)
93 {
94 vec_new_eles.push_back(createLinearElement<MeshLib::Hex>(
95 e, new_mesh_nodes, base_node_map));
96 }
97 else if (e->getCellType() == MeshLib::CellType::TET10)
98 {
99 vec_new_eles.push_back(createLinearElement<MeshLib::Tet>(
100 e, new_mesh_nodes, base_node_map));
101 }
102 else
103 {
104 OGS_FATAL("Mesh element type {:s} is not supported",
105 MeshLib::CellType2String(e->getCellType()));
106 }
107 }
108
109 auto new_mesh = std::make_unique<MeshLib::Mesh>(
110 new_mesh_name, new_mesh_nodes, vec_new_eles,
111 true /* compute_element_neighbors */,
112 mesh.getProperties().excludeCopyProperties(
113 std::vector<MeshLib::MeshItemType>(1,
115
116 // copy property vectors for nodes
117 for (auto [name, property] : mesh.getProperties())
118 {
119 if (property->getMeshItemType() != MeshLib::MeshItemType::Node)
120 {
121 continue;
122 }
123 auto double_property =
124 dynamic_cast<MeshLib::PropertyVector<double>*>(property);
125 if (double_property == nullptr)
126 {
127 continue;
128 }
129 auto const n_src_comp = double_property->getNumberOfGlobalComponents();
130 auto new_prop =
131 new_mesh->getProperties().createNewPropertyVector<double>(
132 name, MeshLib::MeshItemType::Node, new_mesh->getNumberOfNodes(),
133 n_src_comp);
134 assert(new_prop != nullptr);
135
136 for (std::size_t k = 0; k < org_nodes.size(); ++k)
137 {
138 if (!marked_base_nodes[k])
139 {
140 continue;
141 }
142 std::copy_n(double_property->begin() + k * n_src_comp,
143 n_src_comp,
144 new_prop->begin() + base_node_map[k] * n_src_comp);
145 }
146 }
147 return new_mesh;
148}

References MeshLib::CellType2String(), MeshLib::Properties::excludeCopyProperties(), MeshLib::Mesh::getElements(), MeshLib::Mesh::getNodes(), MeshLib::PropertyVectorBase::getNumberOfGlobalComponents(), MeshLib::Mesh::getProperties(), MeshLib::HEX20, MeshLib::LINE3, MeshLib::Node, OGS_FATAL, MeshLib::QUAD8, MeshLib::TET10, and MeshLib::TRI6.

Referenced by main(), and anonymous_namespace{postLIE.cpp}::postVTU().

◆ createBoundaryElements()

std::tuple< std::vector< MeshLib::Element * >, std::vector< std::size_t >, std::vector< std::size_t > > MeshToolsLib::createBoundaryElements ( MeshLib::Mesh const & bulk_mesh)

Definition at line 436 of file MeshSurfaceExtraction.cpp.

437{
438 std::vector<std::size_t> element_to_bulk_element_id_map;
439 std::vector<std::size_t> element_to_bulk_face_id_map;
440 std::vector<MeshLib::Element*> surface_elements;
441
442 auto const& bulk_elements = bulk_mesh.getElements();
443 auto const mesh_dimension = bulk_mesh.getDimension();
444
445 for (auto const* elem : bulk_elements)
446 {
447 const unsigned element_dimension(elem->getDimension());
448 if (element_dimension < mesh_dimension)
449 {
450 continue;
451 }
452
453 if (!elem->isBoundaryElement())
454 {
455 continue;
456 }
457 createSurfaceElementsFromElement(*elem, surface_elements,
458 element_to_bulk_element_id_map,
459 element_to_bulk_face_id_map);
460 }
461 return {surface_elements, element_to_bulk_element_id_map,
462 element_to_bulk_face_id_map};
463}
void createSurfaceElementsFromElement(MeshLib::Element const &surface_element, std::vector< MeshLib::Element * > &surface_elements, std::vector< std::size_t > &element_to_bulk_element_id_map, std::vector< std::size_t > &element_to_bulk_face_id_map)

References createSurfaceElementsFromElement(), MeshLib::Mesh::getDimension(), and MeshLib::Mesh::getElements().

Referenced by MeshToolsLib::BoundaryExtraction::getBoundaryElementsAsMesh().

◆ createCellProperties()

template<typename T>
bool MeshToolsLib::createCellProperties ( MeshLib::Mesh & merged_mesh,
std::string const & pv_name,
int const pv_num_components,
MeshLib::PropertyVector< T > const *const pv_bulk_mesh,
std::unordered_map< std::string, double > & initial_value_dict )

Definition at line 93 of file MeshToolsLib/MeshEditing/MergeMeshToBulkMesh.cpp.

98{
100 merged_mesh, pv_name, MeshLib::MeshItemType::Cell, pv_num_components);
101 new_pv->resize(merged_mesh.getNumberOfElements() * pv_num_components);
102
103 std::copy(pv_bulk_mesh->begin(), pv_bulk_mesh->end(), new_pv->begin());
104
105 double const value =
106 (pv_name == "MaterialIDs") ? (initial_value_dict["mat_id"]) : 0.0;
107
108 std::fill(new_pv->begin() + pv_bulk_mesh->size(), new_pv->end(),
109 static_cast<T>(value));
110 return true;
111}
constexpr PROP_VAL_TYPE * begin()
constexpr std::size_t size() const
constexpr PROP_VAL_TYPE * end()
PropertyVector< T > * getOrCreateMeshProperty(Mesh &mesh, std::string const &property_name, MeshItemType const item_type, int const number_of_components)

References MeshLib::PropertyVector< PROP_VAL_TYPE >::begin(), MeshLib::Cell, MeshLib::PropertyVector< PROP_VAL_TYPE >::end(), MeshLib::Mesh::getNumberOfElements(), MeshLib::getOrCreateMeshProperty(), and MeshLib::PropertyVector< PROP_VAL_TYPE >::size().

Referenced by createMergedPropertyVector().

◆ createFlippedElement()

std::unique_ptr< MeshLib::Element > MeshToolsLib::createFlippedElement ( MeshLib::Element const & elem,
std::vector< MeshLib::Node * > const & nodes )

Creates a copy of an 1d / 2d element where the node order is reversed, such that the direction of a line changes and normals of 2D elements changes its sign.

Parameters
elemoriginal element
nodesnode vector used for the copy of the element
Returns
a flipped copy of the element

Definition at line 15 of file FlipElements.cpp.

17{
18 if (elem.getDimension() > 2)
19 {
20 return nullptr;
21 }
22
23 unsigned const n_nodes(elem.getNumberOfNodes());
24 auto elem_nodes = std::make_unique<MeshLib::Node*[]>(n_nodes);
25 for (unsigned i = 0; i < n_nodes; ++i)
26 {
27 elem_nodes[i] = nodes[elem.getNode(i)->getID()];
28 }
29 std::swap(elem_nodes[0], elem_nodes[1]);
30
31 if (elem.getGeomType() == MeshLib::MeshElemType::LINE)
32 {
33 return std::make_unique<MeshLib::Line>(elem_nodes.release(),
34 elem.getID());
35 }
36 if (elem.getGeomType() == MeshLib::MeshElemType::TRIANGLE)
37 {
38 return std::make_unique<MeshLib::Tri>(elem_nodes.release(),
39 elem.getID());
40 }
41 if (elem.getGeomType() == MeshLib::MeshElemType::QUAD)
42 {
43 std::swap(elem_nodes[2], elem_nodes[3]);
44 return std::make_unique<MeshLib::Quad>(elem_nodes.release(),
45 elem.getID());
46 }
47 return nullptr;
48}

References MeshLib::Element::getDimension(), MeshLib::Element::getGeomType(), MathLib::Point3dWithID::getID(), MeshLib::Element::getID(), MeshLib::Element::getNode(), MeshLib::Element::getNumberOfNodes(), MeshLib::LINE, MeshLib::QUAD, and MeshLib::TRIANGLE.

Referenced by createFlippedMesh().

◆ createFlippedMesh()

std::unique_ptr< MeshLib::Mesh > MeshToolsLib::createFlippedMesh ( MeshLib::Mesh const & mesh)

Creates a copy of a 1d / 2d mesh where the node order of all elements is reversed such that the direction of lines changes and normals of 2D elements changes their sign.

Parameters
meshinput mesh
Returns
a flipped copy of the input mesh

Definition at line 50 of file FlipElements.cpp.

51{
52 if (mesh.getDimension() > 2)
53 {
54 return nullptr;
55 }
56
57 std::vector<MeshLib::Node*> new_nodes(copyNodeVector(mesh.getNodes()));
58 std::vector<MeshLib::Element*> const& elems(mesh.getElements());
59 std::vector<MeshLib::Element*> new_elems;
60 std::size_t n_elems(mesh.getNumberOfElements());
61 new_elems.reserve(n_elems);
62
63 for (std::size_t i = 0; i < n_elems; ++i)
64 {
65 new_elems.push_back(
66 createFlippedElement(*elems[i], new_nodes).release());
67 }
68
69 return std::make_unique<MeshLib::Mesh>(
70 "FlippedElementMesh", new_nodes, new_elems,
71 true /* compute_element_neighbors */, mesh.getProperties());
72}
std::unique_ptr< MeshLib::Element > createFlippedElement(MeshLib::Element const &elem, std::vector< MeshLib::Node * > const &nodes)

References createFlippedElement(), MeshLib::Mesh::getDimension(), MeshLib::Mesh::getElements(), MeshLib::Mesh::getNodes(), MeshLib::Mesh::getNumberOfElements(), and MeshLib::Mesh::getProperties().

Referenced by addLayerToMesh().

◆ createIntegrationPointProperties()

template<typename T>
bool MeshToolsLib::createIntegrationPointProperties ( MeshLib::Mesh & merged_mesh,
std::string const & pv_name,
int const pv_num_components,
MeshLib::PropertyVector< T > const *const pv_bulk_mesh,
std::unordered_map< std::string, double > & initial_value_dict,
std::optional< MeshLib::IntegrationPointMetaData > const & integration_point_meta_data )

Definition at line 114 of file MeshToolsLib/MeshEditing/MergeMeshToBulkMesh.cpp.

121{
123 merged_mesh, pv_name, MeshLib::MeshItemType::IntegrationPoint,
124 pv_num_components);
125
126 // Count the integration points
127 std::size_t counter = 0;
128 auto const ip_meta_data = MeshLib::getIntegrationPointMetaDataSingleField(
129 integration_point_meta_data, pv_name);
130
131 for (auto const element : merged_mesh.getElements())
132 {
133 int const number_of_integration_points =
135 *element);
136 counter += number_of_integration_points;
137 }
138 new_pv->resize(counter * pv_num_components);
139
140 std::copy(pv_bulk_mesh->begin(), pv_bulk_mesh->end(), new_pv->begin());
141
142 if (pv_name.find("sigma") != std::string::npos)
143 {
144 setSigma0(pv_num_components, pv_bulk_mesh, initial_value_dict, *new_pv);
145 }
146
147 return true;
148}
IntegrationPointMetaDataSingleField getIntegrationPointMetaDataSingleField(std::optional< IntegrationPointMetaData > const &ip_meta_data, std::string const &field_name)
int getNumberOfElementIntegrationPoints(MeshLib::IntegrationPointMetaDataSingleField const &ip_meta_data, MeshLib::Element const &e)
void setSigma0(int const pv_num_components, MeshLib::PropertyVector< T > const *const pv_bulk_mesh, std::unordered_map< std::string, double > &initial_value_dict, MeshLib::PropertyVector< T > &new_pv)

References MeshLib::PropertyVector< PROP_VAL_TYPE >::begin(), MeshLib::PropertyVector< PROP_VAL_TYPE >::end(), MeshLib::Mesh::getElements(), MeshLib::getIntegrationPointMetaDataSingleField(), getNumberOfElementIntegrationPoints(), MeshLib::getOrCreateMeshProperty(), MeshLib::IntegrationPoint, and setSigma0().

Referenced by createMergedPropertyVector().

◆ createMergedPropertyVector()

template<typename T>
bool MeshToolsLib::createMergedPropertyVector ( MeshLib::Mesh & merged_mesh,
std::unordered_map< std::string, double > & initial_value_dict,
MeshLib::PropertyVector< T > const *const pv_bulk_mesh,
std::optional< MeshLib::IntegrationPointMetaData > const & integration_point_meta_data )

Definition at line 151 of file MeshToolsLib/MeshEditing/MergeMeshToBulkMesh.cpp.

157{
158 if (pv_bulk_mesh == nullptr)
159 {
160 return false;
161 }
162
163 if (pv_bulk_mesh->getPropertyName() == "vtkGhostType")
164 {
165 // Do nothing
166 return true;
167 }
168
169 auto const item_type = pv_bulk_mesh->getMeshItemType();
170
171 auto const pv_name = pv_bulk_mesh->getPropertyName();
172
173 auto const pv_num_components = pv_bulk_mesh->getNumberOfGlobalComponents();
174
175 if (pv_name == "OGS_VERSION" || pv_name == "IntegrationPointMetaData")
176 {
178 merged_mesh, pv_name, item_type, pv_num_components);
179 new_pv->resize(pv_bulk_mesh->size());
180
181 std::copy(pv_bulk_mesh->begin(), pv_bulk_mesh->end(), new_pv->begin());
182 return true;
183 }
184
185 if (item_type == MeshLib::MeshItemType::Node)
186 {
187 return createNodeProperties(merged_mesh, pv_name, pv_num_components,
188 pv_bulk_mesh, initial_value_dict);
189 }
190
191 if (item_type == MeshLib::MeshItemType::Cell)
192 {
193 return createCellProperties(merged_mesh, pv_name, pv_num_components,
194 pv_bulk_mesh, initial_value_dict);
195 }
196
198 {
200 merged_mesh, pv_name, pv_num_components, pv_bulk_mesh,
201 initial_value_dict, integration_point_meta_data);
202 }
203
204 return false;
205}
MeshItemType getMeshItemType() const
int getNumberOfGlobalComponents() const
std::string const & getPropertyName() const
bool createIntegrationPointProperties(MeshLib::Mesh &merged_mesh, std::string const &pv_name, int const pv_num_components, MeshLib::PropertyVector< T > const *const pv_bulk_mesh, std::unordered_map< std::string, double > &initial_value_dict, std::optional< MeshLib::IntegrationPointMetaData > const &integration_point_meta_data)
bool createCellProperties(MeshLib::Mesh &merged_mesh, std::string const &pv_name, int const pv_num_components, MeshLib::PropertyVector< T > const *const pv_bulk_mesh, std::unordered_map< std::string, double > &initial_value_dict)
bool createNodeProperties(MeshLib::Mesh &merged_mesh, std::string const &pv_name, int const pv_num_components, MeshLib::PropertyVector< T > const *const pv_bulk_mesh, std::unordered_map< std::string, double > &initial_value_dict)

References MeshLib::PropertyVector< PROP_VAL_TYPE >::begin(), MeshLib::Cell, createCellProperties(), createIntegrationPointProperties(), createNodeProperties(), MeshLib::PropertyVector< PROP_VAL_TYPE >::end(), MeshLib::PropertyVectorBase::getMeshItemType(), MeshLib::PropertyVectorBase::getNumberOfGlobalComponents(), MeshLib::getOrCreateMeshProperty(), MeshLib::PropertyVectorBase::getPropertyName(), MeshLib::IntegrationPoint, MeshLib::Node, and MeshLib::PropertyVector< PROP_VAL_TYPE >::size().

Referenced by mergeMeshToBulkMesh().

◆ createNodeProperties()

template<typename T>
bool MeshToolsLib::createNodeProperties ( MeshLib::Mesh & merged_mesh,
std::string const & pv_name,
int const pv_num_components,
MeshLib::PropertyVector< T > const *const pv_bulk_mesh,
std::unordered_map< std::string, double > & initial_value_dict )

Definition at line 48 of file MeshToolsLib/MeshEditing/MergeMeshToBulkMesh.cpp.

53{
55 merged_mesh, pv_name, MeshLib::MeshItemType::Node, pv_num_components);
56 new_pv->resize(merged_mesh.getNumberOfNodes() * pv_num_components);
57
58 std::copy(pv_bulk_mesh->begin(), pv_bulk_mesh->end(), new_pv->begin());
59
60 if (pv_num_components > 1)
61 {
62 if (pv_name.find("sigma") != std::string::npos)
63 {
64 setSigma0(pv_num_components, pv_bulk_mesh, initial_value_dict,
65 *new_pv);
66 }
67 return true;
68 }
69
70 // Map possible pv_name values to their corresponding dictionary
71 // keys
72 const std::unordered_map<std::string, std::string> pv_to_dict_key = {
73 {"pressure", "p"},
74 {"p", "p"},
75 {"gas_pressure", "pg"},
76 {"pg", "pg"},
77 {"capillary_pressure", "pc"},
78 {"pc", "pc"},
79 {"temperature", "T"},
80 {"T", "T"}};
81
82 T value = static_cast<T>(0.0);
83 auto it = pv_to_dict_key.find(pv_name);
84 if (it != pv_to_dict_key.end() && initial_value_dict.contains(it->second))
85 {
86 value = static_cast<T>(initial_value_dict[it->second]);
87 }
88 std::fill(new_pv->begin() + pv_bulk_mesh->size(), new_pv->end(), value);
89 return true;
90}
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition Mesh.h:91

References MeshLib::PropertyVector< PROP_VAL_TYPE >::begin(), MeshLib::PropertyVector< PROP_VAL_TYPE >::end(), MeshLib::Mesh::getNumberOfNodes(), MeshLib::getOrCreateMeshProperty(), MeshLib::Node, setSigma0(), and MeshLib::PropertyVector< PROP_VAL_TYPE >::size().

Referenced by createMergedPropertyVector().

◆ createNodesAndIDMapFromElements()

std::tuple< std::vector< MeshLib::Node * >, std::vector< std::size_t > > MeshToolsLib::createNodesAndIDMapFromElements ( std::vector< MeshLib::Element * > const & elements,
std::size_t const n_all_nodes )

Definition at line 168 of file MeshSurfaceExtraction.cpp.

170{
171 std::vector<MeshLib::Node const*> tmp_nodes(n_all_nodes, nullptr);
172 for (auto const* elem : elements)
173 {
174 auto const n_nodes = elem->getNumberOfNodes();
175 for (unsigned j = 0; j < n_nodes; ++j)
176 {
177 const MeshLib::Node* node(elem->getNode(j));
178 tmp_nodes[node->getID()] = node;
179 }
180 }
181
182 std::vector<MeshLib::Node*> nodes;
183 std::vector<std::size_t> node_id_map(n_all_nodes);
184 for (unsigned i = 0; i < n_all_nodes; ++i)
185 {
186 if (tmp_nodes[i])
187 {
188 node_id_map[i] = nodes.size();
189 nodes.push_back(new MeshLib::Node(*tmp_nodes[i]));
190 }
191 }
192 return {nodes, node_id_map};
193}

References MathLib::Point3dWithID::getID().

Referenced by MeshToolsLib::BoundaryExtraction::getBoundaryElementsAsMesh(), MeshToolsLib::MeshSurfaceExtraction::getMeshSurface(), and MeshToolsLib::MeshSurfaceExtraction::getSurfaceNodes().

◆ createQuadraticOrderMesh()

std::unique_ptr< MeshLib::Mesh > MeshToolsLib::createQuadraticOrderMesh ( MeshLib::Mesh const & linear_mesh,
bool const add_centre_node )

Create a quadratic order mesh from the linear order mesh. For some element types like Quad-4, a centre node might be added if the add_centre_node flag is set, yielding a Quad-9.

Definition at line 189 of file QuadraticMeshGenerator.cpp.

191{
192 // Clone the linear mesh nodes.
193 auto quadratic_mesh_nodes = MeshLib::copyNodeVector(linear_mesh.getNodes());
194
195 // Temporary container for unique quadratic nodes with O(log(n)) search.
196 std::set<MeshLib::Node*, nodeByCoordinatesComparator> unique_nodes;
197
198 // Create new elements with the quadratic nodes
199 std::vector<MeshLib::Element*> quadratic_elements;
200 auto const& linear_mesh_elements = linear_mesh.getElements();
201 for (MeshLib::Element const* e : linear_mesh_elements)
202 {
203 auto quadratic_element = createQuadraticElement(*e, add_centre_node);
204
205 // Replace the base nodes with cloned linear nodes.
206 int const number_base_nodes = quadratic_element->getNumberOfBaseNodes();
207 for (int i = 0; i < number_base_nodes; ++i)
208 {
209 quadratic_element->setNode(
210 i, quadratic_mesh_nodes[getNodeIndex(*quadratic_element, i)]);
211 }
212
213 // Make the new (middle-edge) nodes unique.
214 int const number_all_nodes = quadratic_element->getNumberOfNodes();
215 for (int i = number_base_nodes; i < number_all_nodes; ++i)
216 {
217 MeshLib::Node* original_node =
218 const_cast<MeshLib::Node*>(quadratic_element->getNode(i));
219
220 auto it = unique_nodes.insert(original_node);
221 if (!it.second) // same node was already inserted before, no
222 // insertion
223 {
224 // Replace the element's node with the unique node.
225 quadratic_element->setNode(i, *it.first);
226 // And delete the original node
227 delete original_node;
228 }
229 }
230
231 quadratic_elements.push_back(quadratic_element.release());
232 }
233
234 // Add the unique quadratic nodes to the cloned linear nodes.
235 quadratic_mesh_nodes.reserve(linear_mesh.getNodes().size() +
236 unique_nodes.size());
237 std::copy(unique_nodes.begin(), unique_nodes.end(),
238 std::back_inserter(quadratic_mesh_nodes));
239
240 return std::make_unique<MeshLib::Mesh>(
241 linear_mesh.getName(), quadratic_mesh_nodes, quadratic_elements,
242 true /* compute_element_neighbors */,
243 linear_mesh.getProperties().excludeCopyProperties(
244 std::vector<MeshLib::MeshItemType>(1,
246}
std::unique_ptr< MeshLib::Element > createQuadraticElement(MeshLib::Element const &e, bool const add_centre_node)
Return a new quadratic element corresponding to the linear element's type.

References MeshLib::copyNodeVector(), createQuadraticElement(), MeshLib::Properties::excludeCopyProperties(), MeshLib::Mesh::getElements(), MeshLib::Mesh::getName(), MeshLib::Mesh::getNodes(), MeshLib::Mesh::getProperties(), and MeshLib::Node.

Referenced by main().

◆ createSfcMeshProperties()

bool MeshToolsLib::createSfcMeshProperties ( MeshLib::Mesh & sfc_mesh,
MeshLib::Properties const & properties,
std::vector< std::size_t > const & node_ids_map,
std::vector< std::size_t > const & element_ids_map )

Definition at line 47 of file MeshSurfaceExtraction.cpp.

51{
52 std::size_t const n_elems(sfc_mesh.getNumberOfElements());
53 std::size_t const n_nodes(sfc_mesh.getNumberOfNodes());
54 if (node_ids_map.size() != n_nodes)
55 {
56 ERR("createSfcMeshProperties() - Incorrect number of node IDs ({:d}) "
57 "compared to actual number of surface nodes ({:d}).",
58 node_ids_map.size(), n_nodes);
59 return false;
60 }
61
62 if (element_ids_map.size() != n_elems)
63 {
64 ERR("createSfcMeshProperties() - Incorrect number of element IDs "
65 "({:d}) compared to actual number of surface elements ({:d}).",
66 element_ids_map.size(), n_elems);
67 return false;
68 }
69 std::map<MeshLib::MeshItemType, std::vector<std::size_t> const*> const
70 id_maps = {{MeshLib::MeshItemType::Cell, &element_ids_map},
71 {MeshLib::MeshItemType::Node, &node_ids_map}};
72
73 std::size_t vectors_copied(0);
74 std::size_t vectors_skipped(0);
75 for (auto [name, property] : properties)
76 {
77 if (property->getMeshItemType() != MeshLib::MeshItemType::Cell &&
78 property->getMeshItemType() != MeshLib::MeshItemType::Node)
79 {
80 WARN(
81 "Skipping property vector '{:s}' - not defined on cells or "
82 "nodes.",
83 name);
84 vectors_skipped++;
85 continue;
86 }
87
88 auto const& id_map = *id_maps.at(property->getMeshItemType());
89 if (auto const* p =
90 dynamic_cast<MeshLib::PropertyVector<double>*>(property))
91 {
92 processPropertyVector(*p, id_map, sfc_mesh);
93 vectors_copied++;
94 }
95 else if (auto const* p =
96 dynamic_cast<MeshLib::PropertyVector<float>*>(property))
97 {
98 processPropertyVector(*p, id_map, sfc_mesh);
99 vectors_copied++;
100 }
101 else if (auto const* p =
102 dynamic_cast<MeshLib::PropertyVector<int>*>(property))
103 {
104 processPropertyVector(*p, id_map, sfc_mesh);
105 vectors_copied++;
106 }
107 else if (auto const* p =
108 dynamic_cast<MeshLib::PropertyVector<unsigned>*>(property))
109 {
110 processPropertyVector(*p, id_map, sfc_mesh);
111 vectors_copied++;
112 }
113 else if (auto const* p =
114 dynamic_cast<MeshLib::PropertyVector<long>*>(property))
115 {
116 processPropertyVector(*p, id_map, sfc_mesh);
117 vectors_copied++;
118 }
119 else if (auto const* p =
120 dynamic_cast<MeshLib::PropertyVector<long long>*>(
121 property))
122 {
123 processPropertyVector(*p, id_map, sfc_mesh);
124 vectors_copied++;
125 }
126 else if (auto const* p =
127 dynamic_cast<MeshLib::PropertyVector<unsigned long>*>(
128 property))
129 {
130 processPropertyVector(*p, id_map, sfc_mesh);
131 vectors_copied++;
132 }
133 else if (auto const* p =
134 dynamic_cast<MeshLib::PropertyVector<unsigned long long>*>(
135 property))
136 {
137 processPropertyVector(*p, id_map, sfc_mesh);
138 vectors_copied++;
139 }
140 else if (auto const* p =
141 dynamic_cast<MeshLib::PropertyVector<std::size_t>*>(
142 property))
143 {
144 processPropertyVector(*p, id_map, sfc_mesh);
145 vectors_copied++;
146 }
147 else if (auto const* p =
148 dynamic_cast<MeshLib::PropertyVector<char>*>(property))
149 {
150 processPropertyVector(*p, id_map, sfc_mesh);
151 vectors_copied++;
152 }
153 else
154 {
155 WARN(
156 "Skipping property vector '{:s}' - no matching data type "
157 "'{:s}' found.",
158 name, BaseLib::typeToString(*property));
159 vectors_skipped++;
160 }
161 }
162 INFO("{:d} property vectors copied, {:d} vectors skipped.", vectors_copied,
163 vectors_skipped);
164 return true;
165}
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
std::string typeToString()
void processPropertyVector(MeshLib::PropertyVector< T > const &property, std::vector< std::size_t > const &id_map, MeshLib::Mesh &sfc_mesh)

References MeshLib::Cell, ERR(), MeshLib::Mesh::getNumberOfElements(), MeshLib::Mesh::getNumberOfNodes(), INFO(), MeshLib::Node, processPropertyVector(), BaseLib::typeToString(), and WARN().

Referenced by MeshToolsLib::BoundaryExtraction::getBoundaryElementsAsMesh(), and MeshToolsLib::MeshSurfaceExtraction::getMeshSurface().

◆ createSurfaceElementsFromElement()

void MeshToolsLib::createSurfaceElementsFromElement ( MeshLib::Element const & surface_element,
std::vector< MeshLib::Element * > & surface_elements,
std::vector< std::size_t > & element_to_bulk_element_id_map,
std::vector< std::size_t > & element_to_bulk_face_id_map )

Definition at line 413 of file MeshSurfaceExtraction.cpp.

418{
419 const unsigned n_faces(surface_element.getNumberOfBoundaries());
420 for (unsigned j = 0; j < n_faces; ++j)
421 {
422 if (surface_element.getNeighbor(j) != nullptr)
423 {
424 continue;
425 }
426
427 surface_elements.push_back(
428 const_cast<MeshLib::Element*>(surface_element.getBoundary(j)));
429 element_to_bulk_face_id_map.push_back(j);
430 element_to_bulk_element_id_map.push_back(surface_element.getID());
431 }
432}

References MeshLib::Element::getBoundary(), MeshLib::Element::getID(), MeshLib::Element::getNeighbor(), and MeshLib::Element::getNumberOfBoundaries().

Referenced by createBoundaryElements().

◆ extrudeElement()

MeshLib::Element * MeshToolsLib::extrudeElement ( std::vector< MeshLib::Node * > const & subsfc_nodes,
MeshLib::Element const & sfc_elem,
MeshLib::PropertyVector< std::size_t > const & sfc_to_subsfc_id_map,
std::map< std::size_t, std::size_t > const & subsfc_sfc_id_map )

Extrudes point, line, triangle or quad elements to its higher dimensional versions, i.e. line, quad, prism, hexahedron.

Parameters
subsfc_nodesthe nodes the elements are based on
sfc_elemthe element of the surface that will be extruded
sfc_to_subsfc_id_maprelation between the surface nodes of the surface element and the ids of the nodes of the subsurface mesh
subsfc_sfc_id_mapmapping of the surface nodes of the current mesh to the surface nodes of the extruded mesh
Returns
extruded element (point -> line, line -> quad, tri -> prism, quad -> hexahedron)

Definition at line 41 of file AddLayerToMesh.cpp.

46{
47 if (sfc_elem.getDimension() > 2)
48 {
49 return nullptr;
50 }
51
52 const unsigned nElemNodes(sfc_elem.getNumberOfBaseNodes());
53 auto new_nodes =
54 std::unique_ptr<MeshLib::Node*[]>{new MeshLib::Node*[2 * nElemNodes]};
55
56 for (unsigned j = 0; j < nElemNodes; ++j)
57 {
58 std::size_t const subsfc_id(
59 sfc_to_subsfc_id_map[sfc_elem.getNode(j)->getID()]);
60 new_nodes[j] = subsfc_nodes[subsfc_id];
61 std::size_t new_idx = (nElemNodes == 2) ? (3 - j) : (nElemNodes + j);
62 new_nodes[new_idx] = subsfc_nodes[subsfc_sfc_id_map.at(subsfc_id)];
63 }
64
65 if (sfc_elem.getGeomType() == MeshLib::MeshElemType::LINE)
66 {
67 return new MeshLib::Quad(new_nodes.release());
68 }
69 if (sfc_elem.getGeomType() == MeshLib::MeshElemType::TRIANGLE)
70 {
71 return new MeshLib::Prism(new_nodes.release());
72 }
73 if (sfc_elem.getGeomType() == MeshLib::MeshElemType::QUAD)
74 {
75 return new MeshLib::Hex(new_nodes.release());
76 }
77
78 return nullptr;
79}
TemplateElement< MeshLib::QuadRule4 > Quad
Definition Quad.h:17
TemplateElement< MeshLib::PrismRule6 > Prism
Definition Prism.h:14
TemplateElement< MeshLib::HexRule8 > Hex
Definition Hex.h:14

References MeshLib::Element::getDimension(), MeshLib::Element::getGeomType(), MathLib::Point3dWithID::getID(), MeshLib::Element::getNode(), MeshLib::Element::getNumberOfBaseNodes(), MeshLib::LINE, MeshLib::QUAD, and MeshLib::TRIANGLE.

Referenced by addLayerToMesh().

◆ findNodesInBoundedDomain()

std::vector< MeshLib::Node * > MeshToolsLib::findNodesInBoundedDomain ( std::vector< MeshLib::Node * > const & nodes,
GeoLib::AABB const & aabb )

Definition at line 207 of file MeshToolsLib/MeshEditing/MergeMeshToBulkMesh.cpp.

209{
210 return nodes |
211 ranges::views::filter(
212 [&](MeshLib::Node* n)
213 { return aabb.containsPoint(n->asEigenVector3d(), 1e-16); }) |
214 ranges::to<std::vector<MeshLib::Node*>>();
215}
Eigen::Vector3d const & asEigenVector3d() const
Definition Point3d.h:55

References MathLib::Point3d::asEigenVector3d(), and GeoLib::AABB::containsPoint().

Referenced by mergeMeshToBulkMesh().

◆ getIntegrationPointDataOffsetsOfMeshElements()

std::vector< std::size_t > MeshToolsLib::getIntegrationPointDataOffsetsOfMeshElements ( std::vector< MeshLib::Element * > const & mesh_elements,
MeshLib::PropertyVectorBase const & pv,
MeshLib::Properties const & properties )

Definition at line 90 of file IntegrationPointDataTools.cpp.

94{
95 // For special field data such as OGS_VERSION, IntegrationPointMetaData,
96 // etc., which are not "real" integration points:
97 if (pv.getPropertyName().find("_ip") == std::string::npos)
98 {
99 return {};
100 }
101
102 auto const n_components = pv.getNumberOfGlobalComponents();
103
104 std::vector<std::size_t> element_ip_data_offsets(mesh_elements.size() + 1);
105 std::size_t counter = 0;
106 auto const ip_meta_data = MeshLib::getIntegrationPointMetaDataSingleField(
107 MeshLib::getIntegrationPointMetaData(properties), pv.getPropertyName());
108 for (std::size_t i = 0; i < mesh_elements.size(); i++)
109 {
110 auto const* const element = mesh_elements[i];
111
112 // Assuming that the order of elements in mesh_elements is not touched.
113 element_ip_data_offsets[i] = counter;
114 counter += getNumberOfElementIntegrationPoints(ip_meta_data, *element) *
115 n_components;
116 }
117 element_ip_data_offsets[mesh_elements.size()] = counter;
118
119 return element_ip_data_offsets;
120}
std::optional< IntegrationPointMetaData > getIntegrationPointMetaData(MeshLib::Properties const &properties)

References MeshLib::getIntegrationPointMetaData(), MeshLib::getIntegrationPointMetaDataSingleField(), getNumberOfElementIntegrationPoints(), MeshLib::PropertyVectorBase::getNumberOfGlobalComponents(), and MeshLib::PropertyVectorBase::getPropertyName().

Referenced by ApplicationUtils::copyPropertyVector(), createPropertyVector(), and zeroMeshFieldDataByMaterialIDs().

◆ getNumberOfElementIntegrationPoints()

int MeshToolsLib::getNumberOfElementIntegrationPoints ( MeshLib::IntegrationPointMetaDataSingleField const & ip_meta_data,
MeshLib::Element const & e )

Definition at line 28 of file IntegrationPointDataTools.cpp.

31{
32 switch (e.getCellType())
33 {
36 ip_meta_data);
39 ip_meta_data);
42 ip_meta_data);
45 ip_meta_data);
48 ip_meta_data);
51 ip_meta_data);
54 ip_meta_data);
57 ip_meta_data);
60 ip_meta_data);
63 ip_meta_data);
66 ip_meta_data);
69 ip_meta_data);
72 ip_meta_data);
75 ip_meta_data);
78 MeshLib::Pyramid13>(ip_meta_data);
81 OGS_FATAL("Mesh element type {:s} is not supported",
82 MeshLib::CellType2String(e.getCellType()));
84 default:
85 OGS_FATAL("Invalid Element Type");
86 }
87 return 0;
88}
TemplateElement< MeshLib::PyramidRule13 > Pyramid13
Definition Pyramid.h:15
int getNumberOfElementIntegrationPointsGeneral(MeshLib::IntegrationPointMetaDataSingleField const &ip_meta_data)

References MeshLib::CellType2String(), MeshLib::Element::getCellType(), getNumberOfElementIntegrationPointsGeneral(), MeshLib::HEX20, MeshLib::HEX27, MeshLib::HEX8, MeshLib::INVALID, MeshLib::LINE2, MeshLib::LINE3, OGS_FATAL, MeshLib::PRISM15, MeshLib::PRISM18, MeshLib::PRISM6, MeshLib::PYRAMID13, MeshLib::PYRAMID5, MeshLib::QUAD4, MeshLib::QUAD8, MeshLib::QUAD9, MeshLib::TET10, MeshLib::TET4, MeshLib::TRI3, and MeshLib::TRI6.

Referenced by ApplicationUtils::checkFieldPropertyVectorSize(), ApplicationUtils::copyFieldPropertyDataToPartitions(), createIntegrationPointProperties(), createPropertyVector(), getIntegrationPointDataOffsetsOfMeshElements(), and ApplicationUtils::setIntegrationPointNumberOfPartition().

◆ getNumberOfElementIntegrationPointsGeneral()

template<typename ElementType>
int MeshToolsLib::getNumberOfElementIntegrationPointsGeneral ( MeshLib::IntegrationPointMetaDataSingleField const & ip_meta_data)

Definition at line 16 of file IntegrationPointDataTools.cpp.

18{
19 using IntegrationPolicy =
21 using NonGenericIntegrationMethod =
23 NonGenericIntegrationMethod int_met{
24 (unsigned int)ip_meta_data.integration_order};
25 return int_met.getNumberOfPoints();
26}
NumLib::GaussLegendreIntegrationPolicy< MeshElement > IntegrationPolicy
NumLib::IntegrationGaussLegendreRegular< MeshElement::dimension > IntegrationMethod

References MeshLib::IntegrationPointMetaDataSingleField::integration_order.

Referenced by getNumberOfElementIntegrationPoints().

◆ lutPrismThirdNode()

unsigned MeshToolsLib::lutPrismThirdNode ( unsigned const id1,
unsigned const id2 )

Lookup-table for returning the third node of bottom or top triangle given the other two.

Definition at line 25 of file MeshRevision.cpp.

26{
27 if ((id1 == 0 && id2 == 1) || (id1 == 1 && id2 == 0))
28 {
29 return 2;
30 }
31 if ((id1 == 1 && id2 == 2) || (id1 == 2 && id2 == 1))
32 {
33 return 0;
34 }
35 if ((id1 == 0 && id2 == 2) || (id1 == 2 && id2 == 0))
36 {
37 return 1;
38 }
39 if ((id1 == 3 && id2 == 4) || (id1 == 4 && id2 == 3))
40 {
41 return 5;
42 }
43 if ((id1 == 4 && id2 == 5) || (id1 == 5 && id2 == 4))
44 {
45 return 3;
46 }
47 if ((id1 == 3 && id2 == 5) || (id1 == 5 && id2 == 3))
48 {
49 return 4;
50 }
51 return std::numeric_limits<unsigned>::max();
52}

Referenced by anonymous_namespace{MeshRevision.cpp}::reducePrism().

◆ markUnusedNodes()

std::vector< bool > MeshToolsLib::markUnusedNodes ( std::vector< MeshLib::Element * > const & elements,
std::vector< MeshLib::Node * > const & nodes )

Marks nodes not used by any of the elements.

Definition at line 63 of file RemoveMeshComponents.cpp.

66{
67 std::vector<bool> unused_nodes(nodes.size(), true);
68 for (auto e : elements)
69 {
70 for (unsigned i = 0; i < e->getNumberOfNodes(); i++)
71 {
72 unused_nodes[getNodeIndex(*e, i)] = false;
73 }
74 }
75
76 return unused_nodes;
77}

Referenced by createMeshFromElements(), and removeNodes().

◆ mergeMeshToBulkMesh()

std::unique_ptr< MeshLib::Mesh > MeshToolsLib::mergeMeshToBulkMesh ( MeshLib::Mesh const & bulk_mesh,
MeshLib::Mesh const & other_mesh,
std::unordered_map< std::string, double > & initial_value_dict )

Merges the mesh other_mesh into the bulk mesh bulk_mesh. Optionally sets constant integration point stress and primary nodal variables in the bulk mesh to specified values for the merged part.

Note: This function moves nodes and elements from other_mesh to the merged mesh (bulk_mesh). It deletes the duplicate nodes of other_mesh at the mesh interface. The merged mesh manages memory deallocation for nodes and elements. The member function shallowClean must be called on bulk_mesh and other_mesh afterward to prevent memory leaks.

Parameters
bulk_meshBulk mesh.
other_meshMesh to be merged.
initial_value_dictInitial values to be specified for the merged part.
Returns

Definition at line 217 of file MeshToolsLib/MeshEditing/MergeMeshToBulkMesh.cpp.

220{
221 auto const& other_mesh_nodes = other_mesh.getNodes();
222 GeoLib::AABB aabb(other_mesh_nodes.begin(), other_mesh_nodes.end());
223
224 auto const& bulk_mesh_nodes = bulk_mesh.getNodes();
225 auto const bulk_nodes_in_aabb =
226 findNodesInBoundedDomain(bulk_mesh_nodes, aabb);
227
228 // Find the interface nodes in the bulk nodes
229 auto const pn_bulk_mesh = partitionNodesByCoordinateMatch(
230 bulk_nodes_in_aabb, other_mesh_nodes, aabb,
231 false /*return_non_paired_nodes*/);
232 auto interface_nodes_of_bulk_mesh = pn_bulk_mesh.paired_nodes;
233
234 // Partitioned node vector of the other mesh
235 auto const pn_other_mesh = partitionNodesByCoordinateMatch(
236 other_mesh_nodes, bulk_nodes_in_aabb, aabb);
237 auto const interface_nodes_of_other_mesh = pn_other_mesh.paired_nodes;
238 auto const internal_nodes_of_other_mesh = *(pn_other_mesh.non_paired_nodes);
239
240 // Interface node id mapping: from the other mesh to the bulk mesh
241 auto cn_id_mapping_m2b = *(pn_other_mesh.id_mapping);
242
243 std::unordered_map<std::size_t, std::size_t> other_mesh_node_id_dict;
244
245 for (auto const&& [id_mapping, node] :
246 ranges::views::zip(cn_id_mapping_m2b, interface_nodes_of_other_mesh))
247 {
248 other_mesh_node_id_dict.insert({node->getID(), id_mapping});
249 }
250
251 // Create new mesh node vector
252 std::vector<MeshLib::Node*> new_node_vector;
253 new_node_vector.reserve(bulk_mesh_nodes.size() +
254 internal_nodes_of_other_mesh.size());
255 // First, copy the nodes from the bulk mesh
256 new_node_vector.insert(new_node_vector.end(), bulk_mesh_nodes.begin(),
257 bulk_mesh_nodes.end());
258 // Second, append the inside nodes of the merge mesh
259 std::size_t new_node_id = bulk_mesh_nodes.size();
260 for (auto node : internal_nodes_of_other_mesh)
261 {
262 other_mesh_node_id_dict.insert({node->getID(), new_node_id});
263 new_node_vector.push_back(node);
264 new_node_id++;
265 }
266
267 // Create new mesh element vector
268 auto const elements_bulk = bulk_mesh.getElements();
269 auto const elements_other_mesh = other_mesh.getElements();
270 std::vector<MeshLib::Element*> new_element_vector;
271 new_element_vector.reserve(elements_bulk.size() +
272 elements_other_mesh.size());
273 // First, copy the elements from the bulk mesh
274 new_element_vector.insert(new_element_vector.end(), elements_bulk.begin(),
275 elements_bulk.end());
276 // Append the elements of the mesh to be merged to the element vector of the
277 // bulk mesh:
278 for (auto element : elements_other_mesh)
279 {
280 auto const nn = element->getNumberOfNodes();
281 for (unsigned i = 0; i < nn; ++i)
282 {
283 // `node` cannot be declared as `const` because `element` is not
284 // `const`.
285 MeshLib::Node* node = element->getNode(i);
286 auto const new_id = other_mesh_node_id_dict[node->getID()];
287 element->setNode(i, new_node_vector[new_id]);
288 }
289 new_element_vector.push_back(element);
290 }
291
292 // Node IDs are reset in the constructor of MeshLib::Mesh according to their
293 // order of appearance (see MeshLib::Mesh::resetNodeIDs()). Since the order
294 // of nodes in the bulk mesh remains unchanged, the corresponding segments
295 // of property vectors of the original bulk mesh are also preserved.
296 auto merged_mesh = std::make_unique<MeshLib::Mesh>(
297 "merged_mesh", new_node_vector, new_element_vector);
298
299 MeshLib::Properties const& properties_bulk_mesh = bulk_mesh.getProperties();
300 auto const integration_point_meta_data =
301 MeshLib::getIntegrationPointMetaData(properties_bulk_mesh);
302
304 properties_bulk_mesh,
305 [&](auto type, auto const& property)
306 {
308 *merged_mesh, initial_value_dict,
309 dynamic_cast<MeshLib::PropertyVector<decltype(type)> const*>(
310 property),
311 integration_point_meta_data);
312 });
313
314 for (auto node : interface_nodes_of_other_mesh)
315 {
316 delete node;
317 }
318
319 return merged_mesh;
320}
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
Definition AABB.h:45
std::size_t getID() const
void applyToPropertyVectors(Properties const &properties, Function f)
NodesPartitionResult partitionNodesByCoordinateMatch(std::vector< MeshLib::Node * > const &node_vector, std::vector< MeshLib::Node * > const &tool_node_vector, GeoLib::AABB const &aabb, bool const return_non_paired_nodes)
bool createMergedPropertyVector(MeshLib::Mesh &merged_mesh, std::unordered_map< std::string, double > &initial_value_dict, MeshLib::PropertyVector< T > const *const pv_bulk_mesh, std::optional< MeshLib::IntegrationPointMetaData > const &integration_point_meta_data)
std::vector< MeshLib::Node * > findNodesInBoundedDomain(std::vector< MeshLib::Node * > const &nodes, GeoLib::AABB const &aabb)

References MeshLib::applyToPropertyVectors(), createMergedPropertyVector(), findNodesInBoundedDomain(), MeshLib::Mesh::getElements(), MathLib::Point3dWithID::getID(), MeshLib::getIntegrationPointMetaData(), MeshLib::Mesh::getNodes(), MeshLib::Mesh::getProperties(), and partitionNodesByCoordinateMatch().

Referenced by main().

◆ moveMeshNodes()

template<typename Iterator>
void MeshToolsLib::moveMeshNodes ( Iterator begin,
Iterator end,
Eigen::Vector3d const & displacement )

Function that moves mesh nodes.

The function iterates over all mesh nodes between the begin and the end iterator and moves them using the given displacement.

Parameters
beginbegin iterator
endend iterator
displacementthe displacement to use

Definition at line 24 of file moveMeshNodes.h.

27{
28 std::for_each(begin, end,
29 [&displacement](MathLib::Point3d* node)
30 { node->asEigenVector3d() += displacement; });
31};

References MathLib::Point3d::asEigenVector3d().

Referenced by main(), TranslateDataDialog::moveGeometry(), and TranslateDataDialog::moveMesh().

◆ partitionNodesByCoordinateMatch()

NodesPartitionResult MeshToolsLib::partitionNodesByCoordinateMatch ( std::vector< MeshLib::Node * > const & node_vector,
std::vector< MeshLib::Node * > const & tool_node_vector,
GeoLib::AABB const & aabb,
bool const return_non_paired_nodes = true )

Assuming at least one element in node_vector can be paired with an element in tool_node_vector based on identical coordinates, this function partitions node_vector into two vectors: one containing nodes that can be paired with elements in tool_node_vector, and another containing the remaining nodes or empty depending on the argument return_non_paired_nodes.

Parameters
node_vectorNode vector to be partitioned.
tool_node_vectorNode vector as a tool for partitioning.
aabbAxis-aligned bounding box (AABB) for spatial filtering and the optional return of non-paired nodes.
return_non_paired_nodesIndicator whether to return unpaired nodes.
Returns
  1. paired nodes of node_vector,
  2. node ID mapping from the paired node of node_vector to its pair in tool_node_vector or nothing if return_non_paired_nodes is false,
  3. unpaired nodes of node_vector or nothing if return_non_paired_nodes is false.

Definition at line 12 of file PartitionNodesByCoordinateMatch.cpp.

17{
18 auto oct_tree = std::unique_ptr<GeoLib::OctTree<MeshLib::Node, 16>>(
20 aabb.getMinPoint(), aabb.getMaxPoint(), 1e-16));
21
22 // Push all tool nodes into oct_tree:
23 for (auto const node : tool_node_vector)
24 {
25 MeshLib::Node* node_ptr = nullptr;
26 oct_tree->addPoint(node, node_ptr);
27 }
28
29 // Find the paired nodes in the node_vector
30 std::vector<MeshLib::Node*> paired_nodes;
31 std::vector<MeshLib::Node*> other_nodes;
32 std::vector<std::size_t> ip_mapping;
33 for (auto node : node_vector)
34 {
35 MeshLib::Node* node_ptr = nullptr;
36 if (oct_tree->addPoint(node, node_ptr))
37 {
38 if (return_non_paired_nodes)
39 {
40 other_nodes.push_back(node);
41 }
42 continue;
43 }
44 paired_nodes.push_back(node);
45 ip_mapping.push_back(node_ptr->getID());
46 }
47
48 if (return_non_paired_nodes)
49 {
50 return {paired_nodes, ip_mapping, other_nodes};
51 }
52
53 return {paired_nodes, std::nullopt, std::nullopt};
54}
static OctTree< POINT, MAX_POINTS > * createOctTree(Eigen::Vector3d ll, Eigen::Vector3d ur, double eps=std::numeric_limits< double >::epsilon())
Definition OctTree-impl.h:7

References GeoLib::OctTree< POINT, MAX_POINTS >::createOctTree(), MathLib::Point3dWithID::getID(), GeoLib::AABB::getMaxPoint(), and GeoLib::AABB::getMinPoint().

Referenced by mergeMeshToBulkMesh().

◆ processPropertyVector()

template<typename T>
void MeshToolsLib::processPropertyVector ( MeshLib::PropertyVector< T > const & property,
std::vector< std::size_t > const & id_map,
MeshLib::Mesh & sfc_mesh )

Definition at line 28 of file MeshSurfaceExtraction.cpp.

31{
32 auto const number_of_components = property.getNumberOfGlobalComponents();
33
35 sfc_mesh, property.getPropertyName(), property.getMeshItemType(),
36 number_of_components);
37
38 auto get_components = [&](std::size_t const bulk_id)
39 {
40 return std::span(&property.getComponent(bulk_id, 0 /*component_id*/),
41 number_of_components);
42 };
43 sfc_prop->assign(id_map | ranges::views::transform(get_components) |
44 ranges::views::join);
45}
PROP_VAL_TYPE & getComponent(std::size_t tuple_index, int component)
Returns the value for the given component stored in the given tuple.

References MeshLib::PropertyVector< PROP_VAL_TYPE >::getComponent(), MeshLib::PropertyVectorBase::getMeshItemType(), MeshLib::getOrCreateMeshProperty(), and MeshLib::PropertyVectorBase::getPropertyName().

Referenced by createSfcMeshProperties().

◆ removeElements()

MeshLib::Mesh * MeshToolsLib::removeElements ( const MeshLib::Mesh & mesh,
const std::vector< std::size_t > & removed_element_ids,
const std::string & new_mesh_name )

Removes mesh elements and returns a new mesh object. The original mesh is kept unchanged.

Parameters
meshan original mesh whose elements are removed
removed_element_idsa vector of element indices to be removed
new_mesh_namea new mesh name
Returns
a new mesh object

Definition at line 14 of file RemoveMeshComponents.cpp.

18{
19 if (removed_element_ids.empty())
20 {
21 INFO("No elements to remove");
22 return nullptr;
23 }
24
25 INFO("Removing total {:d} elements...", removed_element_ids.size());
26 std::vector<MeshLib::Element*> tmp_elems =
27 BaseLib::excludeObjectCopy(mesh.getElements(), removed_element_ids);
28 INFO("{:d} elements remain in mesh.", tmp_elems.size());
29
30 // copy node and element objects
31 std::vector<MeshLib::Node*> new_nodes =
33 std::vector<MeshLib::Element*> new_elems =
34 MeshLib::copyElementVector(tmp_elems, new_nodes);
35
36 // delete unused nodes
37 MeshLib::NodeSearch ns(mesh);
38 ns.searchNodesConnectedToOnlyGivenElements(removed_element_ids);
39 auto& removed_node_ids(ns.getSearchedNodeIDs());
40 INFO("Removing total {:d} nodes...", removed_node_ids.size());
41 for (auto nodeid : removed_node_ids)
42 {
43 delete new_nodes[nodeid];
44 new_nodes[nodeid] = nullptr;
45 }
46 new_nodes.erase(std::remove(new_nodes.begin(), new_nodes.end(), nullptr),
47 new_nodes.end());
48
49 if (!new_elems.empty())
50 {
51 MeshLib::Mesh* new_mesh =
52 new MeshLib::Mesh(new_mesh_name, new_nodes, new_elems,
53 true /* compute_element_neighbors */,
55 removed_element_ids, removed_node_ids));
56 return new_mesh;
57 }
58
59 INFO("Current selection removes all elements.");
60 return nullptr;
61}
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
Definition Mesh.h:97
Properties & getProperties()
Definition Mesh.h:125
Node search class.
Definition NodeSearch.h:18
Properties excludeCopyProperties(std::vector< std::size_t > const &exclude_elem_ids, std::vector< std::size_t > const &exclude_node_ids) const
std::vector< T > excludeObjectCopy(std::vector< T > const &src_vec, std::vector< std::size_t > const &exclude_positions)
Definition Algorithm.h:35

References MeshLib::copyElementVector(), MeshLib::copyNodeVector(), MeshLib::Properties::excludeCopyProperties(), BaseLib::excludeObjectCopy(), MeshLib::Mesh::getElements(), MeshLib::Mesh::getNodes(), MeshLib::Mesh::getProperties(), MeshLib::NodeSearch::getSearchedNodeIDs(), INFO(), and MeshLib::NodeSearch::searchNodesConnectedToOnlyGivenElements().

Referenced by MeshElementRemovalDialog::accept(), MeshToolsLib::RasterToMesh::convert(), LayeredVolume::createRasterLayers(), MeshToolsLib::MeshGenerators::VoxelFromLayeredMeshes::createVoxelFromLayeredMesh(), extractMatGroup(), MeshToolsLib::MeshGenerator::generateRegularPrismMesh(), main(), MeshToolsLib::MeshGenerator::VoxelGridFromMesh::removeUnusedGridCells(), and writeBoundary().

◆ removeMarkedNodes()

void MeshToolsLib::removeMarkedNodes ( std::vector< bool > const & nodes_to_delete,
std::vector< MeshLib::Node * > & nodes )

Deallocates and removes nodes marked true.

Definition at line 79 of file RemoveMeshComponents.cpp.

81{
82 assert(nodes_to_delete.size() == nodes.size());
83
84 for (std::size_t i = 0; i < nodes.size(); i++)
85 {
86 if (nodes_to_delete[i])
87 {
88 delete nodes[i];
89 nodes[i] = nullptr;
90 }
91 }
92 nodes.erase(remove(begin(nodes), end(nodes), nullptr), end(nodes));
93}

Referenced by createMeshFromElements(), and removeNodes().

◆ removeNodes()

MeshLib::Mesh * MeshToolsLib::removeNodes ( const MeshLib::Mesh & mesh,
const std::vector< std::size_t > & del_nodes_idx,
const std::string & new_mesh_name )

Removes the mesh nodes (and connected elements) given in the nodes-list from the mesh.

Parameters
meshan original mesh whose elements are removed
del_nodes_idxa vector of node indices to be removed
new_mesh_namea new mesh name
Returns
a new mesh object

Definition at line 95 of file RemoveMeshComponents.cpp.

98{
99 if (del_nodes_idx.empty())
100 {
101 return nullptr;
102 }
103
104 // copy node and element objects
105 std::vector<MeshLib::Node*> new_nodes =
107 std::vector<MeshLib::Element*> new_elems =
108 MeshLib::copyElementVector(mesh.getElements(), new_nodes);
109
110 // delete elements
111 MeshLib::ElementSearch es(mesh);
112 es.searchByNodeIDs(del_nodes_idx);
113 auto& removed_element_ids = es.getSearchedElementIDs();
114 for (auto eid : removed_element_ids)
115 {
116 delete new_elems[eid];
117 new_elems[eid] = nullptr;
118 }
119 new_elems.erase(std::remove(new_elems.begin(), new_elems.end(), nullptr),
120 new_elems.end());
121
122 // check unused nodes due to element deletion
123 std::vector<bool> const node_delete_flag =
124 markUnusedNodes(new_elems, new_nodes);
125
126 // delete unused nodes
127 removeMarkedNodes(node_delete_flag, new_nodes);
128
129 if (!new_elems.empty())
130 {
131 MeshLib::Mesh* new_mesh =
132 new MeshLib::Mesh(new_mesh_name, new_nodes, new_elems,
133 true /* compute_element_neighbors */,
135 removed_element_ids, del_nodes_idx));
136 return new_mesh;
137 }
138
139 return nullptr;
140}
Element search class.
std::vector< bool > markUnusedNodes(std::vector< MeshLib::Element * > const &elements, std::vector< MeshLib::Node * > const &nodes)
Marks nodes not used by any of the elements.
void removeMarkedNodes(std::vector< bool > const &nodes_to_delete, std::vector< MeshLib::Node * > &nodes)
Deallocates and removes nodes marked true.

References MeshLib::copyElementVector(), MeshLib::copyNodeVector(), MeshLib::Properties::excludeCopyProperties(), MeshLib::Mesh::getElements(), MeshLib::Mesh::getNodes(), MeshLib::Mesh::getProperties(), MeshLib::ElementSearch::getSearchedElementIDs(), markUnusedNodes(), removeMarkedNodes(), and MeshLib::ElementSearch::searchByNodeIDs().

Referenced by LayeredMeshGenerator::getMesh().

◆ setSigma0()

template<typename T>
void MeshToolsLib::setSigma0 ( int const pv_num_components,
MeshLib::PropertyVector< T > const *const pv_bulk_mesh,
std::unordered_map< std::string, double > & initial_value_dict,
MeshLib::PropertyVector< T > & new_pv )

Definition at line 30 of file MeshToolsLib/MeshEditing/MergeMeshToBulkMesh.cpp.

34{
35 std::vector<double> sigma0(pv_num_components, 0.0);
36 sigma0[0] = initial_value_dict["sxx"];
37 sigma0[1] = initial_value_dict["syy"];
38 sigma0[2] = initial_value_dict["szz"];
39
40 std::transform(new_pv.begin() + pv_bulk_mesh->size(),
41 new_pv.end(),
42 new_pv.begin() + pv_bulk_mesh->size(),
43 [&, i = 0](T) mutable
44 { return static_cast<T>(sigma0[i++ % sigma0.size()]); });
45}

References MeshLib::PropertyVector< PROP_VAL_TYPE >::begin(), MeshLib::PropertyVector< PROP_VAL_TYPE >::end(), and MeshLib::PropertyVector< PROP_VAL_TYPE >::size().

Referenced by createIntegrationPointProperties(), and createNodeProperties().

◆ trackSurface()

void MeshToolsLib::trackSurface ( MeshLib::Element const *const element,
std::vector< unsigned > & sfc_idx,
unsigned const current_index )
static

Finds all surface elements that can be reached from element. All elements that are found in this way are marked in the global sfc_idx vector using the current_index.

Parameters
elementThe mesh element from which the search is started
sfc_idxThe global index vector notifying to which surface elements belong
current_indexThe index that all elements reachable from element will be assigned in sfc_idx

Definition at line 29 of file MeshValidation.cpp.

32{
33 std::stack<MeshLib::Element const*> elem_stack;
34 elem_stack.push(element);
35 while (!elem_stack.empty())
36 {
37 MeshLib::Element const* const elem = elem_stack.top();
38 elem_stack.pop();
39 sfc_idx[elem->getID()] = current_index;
40 std::size_t const n_neighbors(elem->getNumberOfNeighbors());
41 for (std::size_t i = 0; i < n_neighbors; ++i)
42 {
43 MeshLib::Element const* neighbor(elem->getNeighbor(i));
44 if (neighbor != nullptr && sfc_idx[neighbor->getID()] ==
45 std::numeric_limits<unsigned>::max())
46 {
47 elem_stack.push(neighbor);
48 }
49 }
50 }
51}
virtual unsigned getNumberOfNeighbors() const =0
Get the number of neighbors for this element.
std::size_t getID() const
Returns the ID of the element.
Definition Element.h:80
virtual const Element * getNeighbor(unsigned i) const =0
Get the specified neighbor.

References MeshLib::Element::getID(), MeshLib::Element::getNeighbor(), and MeshLib::Element::getNumberOfNeighbors().

Referenced by MeshToolsLib::MeshValidation::detectHoles().

◆ zeroMeshFieldDataByMaterialIDs()

void MeshToolsLib::zeroMeshFieldDataByMaterialIDs ( MeshLib::Mesh & mesh,
std::vector< int > const & selected_material_ids )

Definition at line 16 of file ZeroMeshFieldDataByMaterialIDs.cpp.

18{
19 auto const materialIds = materialIDs(mesh);
20 if (!materialIds)
21 {
23 "Mesh contains no int-property vector named 'MaterialIDs' needed "
24 "by the 'zero_mesh_field_data_by_materialIDs'");
25 }
26
27 std::vector<std::size_t> element_ids_for_selected_materials;
28 for (std::size_t i = 0; i < materialIds->size(); ++i)
29 {
30 if (std::find(selected_material_ids.begin(),
31 selected_material_ids.end(),
32 (*materialIds)[i]) != selected_material_ids.end())
33 {
34 element_ids_for_selected_materials.push_back(i);
35 }
36 }
37
38 MeshLib::Properties& properties = mesh.getProperties();
39
40 std::vector<std::size_t> element_ip_data_offsets;
41
42 for (auto const& [name, property] : properties)
43 {
44 if (auto const item_type = property->getMeshItemType();
46 {
47 continue;
48 }
49
50 // For special field data such as OGS_VERSION,
51 // IntegrationPointMetaData,
52 // etc., which are not "real" integration points:
53 if (!property->getPropertyName().ends_with("_ip"))
54 {
55 continue;
56 }
57
58 if (properties.template hasPropertyVector<double>(
60 {
61 auto& pv = *properties.template getPropertyVector<double>(name);
62 const int n_components = pv.getNumberOfGlobalComponents();
63
64 if (element_ip_data_offsets.empty())
65 {
66 // The returned values has already been multiplied with
67 // pv.getNumberOfGlobalComponents()
68 element_ip_data_offsets =
70 mesh.getElements(), pv, properties);
71
72 // element_ip_data_offsets / pv.getNumberOfGlobalComponents()
73 std::transform(element_ip_data_offsets.begin(),
74 element_ip_data_offsets.end(),
75 element_ip_data_offsets.begin(),
76 [n = n_components](std::size_t const v)
77 { return v / n; });
78 }
79
80 for (auto const element_id : element_ids_for_selected_materials)
81 {
82 std::fill(
83 pv.begin() +
84 n_components * element_ip_data_offsets[element_id],
85 pv.begin() +
86 n_components * element_ip_data_offsets[element_id + 1],
87 0.0);
88 }
89 }
90 }
91}
std::vector< std::size_t > getIntegrationPointDataOffsetsOfMeshElements(std::vector< MeshLib::Element * > const &mesh_elements, MeshLib::PropertyVectorBase const &pv, MeshLib::Properties const &properties)

References MeshLib::Mesh::getElements(), getIntegrationPointDataOffsetsOfMeshElements(), MeshLib::Mesh::getProperties(), MeshLib::IntegrationPoint, and OGS_FATAL.

Referenced by anonymous_namespace{ProjectData.cpp}::readMeshes().