From 76dba19d99d2d2d2b2b16e4f2ca375541056fac3 Mon Sep 17 00:00:00 2001
From: Thomas Fischer <thomas.fischer@ufz.de>
Date: Tue, 28 Feb 2017 13:17:04 +0100
Subject: [PATCH] Check that PropertyVector exists before fetching.

---
 .../DataView/ElementTreeModel.cpp             |  7 +++++--
 .../DataView/MeshElementRemovalDialog.cpp     | 12 +++++------
 Applications/FileIO/SHPInterface.cpp          |  8 ++++---
 Applications/FileIO/TetGenInterface.cpp       |  9 ++++----
 .../generateMatPropsFromMatID.cpp             |  4 ++--
 .../ResetPropertiesInPolygonalRegion.cpp      | 13 ++++++++----
 Applications/Utils/MeshEdit/queryMesh.cpp     |  6 ++++--
 .../ComputeNodeAreasFromSurfaceMesh.cpp       | 13 ++++++++----
 .../ModelPreparation/createNeumannBc.cpp      |  7 +++----
 MeshGeoToolsLib/AppendLinesAlongPolyline.cpp  | 11 +++++-----
 MeshLib/ElementStatus.cpp                     |  6 ++++--
 MeshLib/IO/Legacy/MeshIO.cpp                  | 14 +++++++++----
 MeshLib/Mesh.cpp                              |  6 ++++++
 MeshLib/MeshEditing/AddLayerToMesh.cpp        | 20 +++++++++---------
 MeshLib/MeshEditing/ConvertToLinearMesh.cpp   |  4 ++--
 .../MeshEditing/ElementValueModification.cpp  |  7 +++----
 .../Mesh2MeshPropertyInterpolation.cpp        | 16 ++++++++------
 MeshLib/MeshEditing/MeshRevision.cpp          | 15 ++++++-------
 MeshLib/MeshInformation.h                     |  4 ++--
 MeshLib/MeshSearch/ElementSearch.h            |  9 ++++----
 MeshLib/Vtk/VtkMappedMeshSource.h             |  4 ++--
 MeshLib/convertMeshToGeo.cpp                  |  5 ++++-
 ProcessLib/HT/CreatePorousMediaProperties.cpp |  6 +++---
 ProcessLib/LIE/Common/PostUtils.cpp           | 10 ++++-----
 .../LiquidFlow/CreateLiquidFlowProcess.cpp    |  6 +++---
 .../CreateTwoPhaseFlowWithPPProcess.cpp       |  7 +++----
 .../CreateTwoPhaseFlowWithPrhoProcess.cpp     | 11 ++++------
 Tests/MeshLib/MeshProperties.cpp              | 21 +++++++------------
 28 files changed, 145 insertions(+), 116 deletions(-)

diff --git a/Applications/DataExplorer/DataView/ElementTreeModel.cpp b/Applications/DataExplorer/DataView/ElementTreeModel.cpp
index 4580f83e2e4..5e184e87993 100644
--- a/Applications/DataExplorer/DataView/ElementTreeModel.cpp
+++ b/Applications/DataExplorer/DataView/ElementTreeModel.cpp
@@ -67,9 +67,12 @@ void ElementTreeModel::setElement(vtkUnstructuredGridAlgorithm const*const grid,
     TreeItem* typeItem = new TreeItem(typeData, elemItem);
     elemItem->appendChild(typeItem);
 
+    MeshLib::PropertyVector<int> const*const mat_ids =
+        mesh->getProperties().existsPropertyVector<int>("MaterialIDs")
+            ? mesh->getProperties().getPropertyVector<int>("MaterialIDs")
+            : nullptr;
+    QString matIdString = !mat_ids ? QString("not defined") : QString::number((*mat_ids)[elem->getID()]);
     QList<QVariant> materialData;
-    auto materialIds = mesh->getProperties().getPropertyVector<int>("MaterialIDs");
-    QString matIdString = !materialIds ? QString("not defined") : QString::number((*materialIds)[elem->getID()]);
     materialData << "MaterialID: " << matIdString;
     TreeItem* matItem = new TreeItem(materialData, elemItem);
     elemItem->appendChild(matItem);
diff --git a/Applications/DataExplorer/DataView/MeshElementRemovalDialog.cpp b/Applications/DataExplorer/DataView/MeshElementRemovalDialog.cpp
index 39083a92677..043b6f31e8d 100644
--- a/Applications/DataExplorer/DataView/MeshElementRemovalDialog.cpp
+++ b/Applications/DataExplorer/DataView/MeshElementRemovalDialog.cpp
@@ -171,14 +171,14 @@ void MeshElementRemovalDialog::on_materialIDCheckBox_toggled(bool is_checked)
         materialListWidget->clear();
         _matIDIndex = _currentIndex;
         auto mesh = _project.getMesh(meshNameComboBox->currentText().toStdString());
-        auto const* const mat_ids =
-            mesh->getProperties().getPropertyVector<int>("MaterialIDs");
-        if (!mat_ids)
+        if (!mesh->getProperties().existsPropertyVector<int>("MaterialIDs"))
         {
             INFO("Properties \"MaterialIDs\" not found in the mesh \"%s\".",
                 mesh->getName().c_str());
             return;
         }
+        auto const* const mat_ids =
+            mesh->getProperties().getPropertyVector<int>("MaterialIDs");
         if (mat_ids->size() != mesh->getNumberOfElements())
         {
             INFO(
@@ -205,10 +205,10 @@ void MeshElementRemovalDialog::on_meshNameComboBox_currentIndexChanged(int idx)
     this->materialListWidget->clearSelection();
     if (this->boundingBoxCheckBox->isChecked()) this->on_boundingBoxCheckBox_toggled(true);
     auto mesh = _project.getMesh(meshNameComboBox->currentText().toStdString());
-    auto const* const materialIds =
-        mesh->getProperties().getPropertyVector<int>("MaterialIDs");
-    if (materialIds)
+    if (mesh->getProperties().existsPropertyVector<int>("MaterialIDs"))
     {
+        auto const* const materialIds =
+            mesh->getProperties().getPropertyVector<int>("MaterialIDs");
         if (materialIds->size() != mesh->getNumberOfElements())
         {
             ERR ("Incorrect mesh structure: Number of Material IDs does not match number of mesh elements.");
diff --git a/Applications/FileIO/SHPInterface.cpp b/Applications/FileIO/SHPInterface.cpp
index 7c9377f8c19..c1589b7f95d 100644
--- a/Applications/FileIO/SHPInterface.cpp
+++ b/Applications/FileIO/SHPInterface.cpp
@@ -237,10 +237,12 @@ bool SHPInterface::write2dMeshToSHP(const std::string &file_name, const MeshLib:
         {
             // write element ID and material group to DBF-file
             DBFWriteIntegerAttribute(hDBF, polygon_id, elem_id_field, i);
-            auto materialIds = mesh.getProperties().getPropertyVector<int>("MaterialIDs");
-            if (materialIds)
+            if (mesh.getProperties().existsPropertyVector<int>("MaterialIDs"))
+            {
+                auto const* const materialIds =
+                    mesh.getProperties().getPropertyVector<int>("MaterialIDs");
                 DBFWriteIntegerAttribute(hDBF, polygon_id, mat_field, (*materialIds)[i]);
-
+            }
             unsigned nNodes (e->getNumberOfBaseNodes());
             padfX = new double[nNodes+1];
             padfY = new double[nNodes+1];
diff --git a/Applications/FileIO/TetGenInterface.cpp b/Applications/FileIO/TetGenInterface.cpp
index 0508d87b454..215a6f91b48 100644
--- a/Applications/FileIO/TetGenInterface.cpp
+++ b/Applications/FileIO/TetGenInterface.cpp
@@ -614,14 +614,15 @@ void TetGenInterface::write2dElements(std::ofstream &out,
     out << nTotalTriangles << " 1\n";
 
     const std::vector<MeshLib::Element*> &elements = mesh.getElements();
-    auto const* const materialIds =
-        mesh.getProperties().getPropertyVector<int>("MaterialIDs");
+    MeshLib::PropertyVector<int> const*const mat_ids =
+        mesh.getProperties().existsPropertyVector<int>("MaterialIDs")
+            ? mesh.getProperties().getPropertyVector<int>("MaterialIDs")
+            : nullptr;
     const std::size_t nElements (elements.size());
     unsigned element_count(0);
     for (std::size_t i=0; i<nElements; ++i)
     {
-        std::string matId =
-            materialIds ? std::to_string((*materialIds)[i]) : "";
+        std::string const matId = mat_ids ? std::to_string((*mat_ids)[i]) : "";
         this->writeElementToFacets(out, *elements[i], element_count, matId);
     }
 }
diff --git a/Applications/Utils/FileConverter/generateMatPropsFromMatID.cpp b/Applications/Utils/FileConverter/generateMatPropsFromMatID.cpp
index 0cfc5639a62..2153f4bec4c 100644
--- a/Applications/Utils/FileConverter/generateMatPropsFromMatID.cpp
+++ b/Applications/Utils/FileConverter/generateMatPropsFromMatID.cpp
@@ -51,12 +51,12 @@ int main (int argc, char* argv[])
         INFO("Could not read mesh from file \"%s\".", mesh_arg.getValue().c_str());
         return EXIT_FAILURE;
     }
-    auto materialIds = mesh->getProperties().getPropertyVector<int>("MaterialIDs");
-    if (!materialIds)
+    if (!mesh->getProperties().existsPropertyVector<int>("MaterialIDs"))
     {
         ERR("Mesh contains no int-property vector named \"MaterialIds\".");
         return EXIT_FAILURE;
     }
+    auto materialIds = mesh->getProperties().getPropertyVector<int>("MaterialIDs");
 
     std::size_t const n_properties(materialIds->size());
     if (n_properties != mesh->getNumberOfElements()) {
diff --git a/Applications/Utils/MeshEdit/ResetPropertiesInPolygonalRegion.cpp b/Applications/Utils/MeshEdit/ResetPropertiesInPolygonalRegion.cpp
index 9a0b181d4ba..68d9b2e949f 100644
--- a/Applications/Utils/MeshEdit/ResetPropertiesInPolygonalRegion.cpp
+++ b/Applications/Utils/MeshEdit/ResetPropertiesInPolygonalRegion.cpp
@@ -79,12 +79,13 @@ template <typename PT>
 void resetMeshElementProperty(MeshLib::Mesh &mesh, GeoLib::Polygon const& polygon,
     std::string const& property_name, PT new_property_value)
 {
-    auto* const pv = mesh.getProperties().getPropertyVector<PT>(property_name);
-    if (!pv) {
+    if (!mesh.getProperties().existsPropertyVector<PT>(property_name))
+    {
         WARN("Did not find a PropertyVector with name \"%s\".",
             property_name.c_str());
         return;
     }
+    auto* const pv = mesh.getProperties().getPropertyVector<PT>(property_name);
 
     if (pv->getMeshItemType() != MeshLib::MeshItemType::Cell)
     {
@@ -204,8 +205,12 @@ int main (int argc, char* argv[])
         char new_property_val(char_property_arg.getValue());
 
         // check if PropertyVector exists
-        auto* pv = mesh->getProperties().getPropertyVector<char>(property_name);
-        if (!pv)
+        MeshLib::PropertyVector<char>* pv(nullptr);
+        if (mesh->getProperties().existsPropertyVector<char>(property_name))
+        {
+            pv = mesh->getProperties().getPropertyVector<char>(property_name);
+        }
+        else
         {
             pv = mesh->getProperties().createNewPropertyVector<char>(
                 property_name, MeshLib::MeshItemType::Cell, 1);
diff --git a/Applications/Utils/MeshEdit/queryMesh.cpp b/Applications/Utils/MeshEdit/queryMesh.cpp
index 35cfb60ff6e..f545d5f7761 100644
--- a/Applications/Utils/MeshEdit/queryMesh.cpp
+++ b/Applications/Utils/MeshEdit/queryMesh.cpp
@@ -48,8 +48,6 @@ int main(int argc, char *argv[])
     if (!mesh)
         return EXIT_FAILURE;
 
-    auto materialIds = mesh->getProperties().getPropertyVector<int>("MaterialIDs");
-
     std::vector<std::size_t> selected_node_ids;
     if  (showNodeWithMaxEle_arg.getValue())
     {
@@ -63,6 +61,10 @@ int main(int argc, char *argv[])
     }
     selected_node_ids.insert(selected_node_ids.end(), nodeId_arg.getValue().begin(), nodeId_arg.getValue().end());
 
+    MeshLib::PropertyVector<int> const*const materialIds =
+        mesh->getProperties().existsPropertyVector<int>("MaterialIDs")
+            ? mesh->getProperties().getPropertyVector<int>("MaterialIDs")
+            : nullptr;
     for (auto ele_id : eleId_arg.getValue())
     {
         std::stringstream out;
diff --git a/Applications/Utils/ModelPreparation/ComputeNodeAreasFromSurfaceMesh.cpp b/Applications/Utils/ModelPreparation/ComputeNodeAreasFromSurfaceMesh.cpp
index dbfbd24a204..0fae44f72fa 100644
--- a/Applications/Utils/ModelPreparation/ComputeNodeAreasFromSurfaceMesh.cpp
+++ b/Applications/Utils/ModelPreparation/ComputeNodeAreasFromSurfaceMesh.cpp
@@ -82,12 +82,11 @@ int main (int argc, char* argv[])
          surface_mesh->getNumberOfElements());
     // ToDo check if mesh is read correct and if the mesh is a surface mesh
 
+    MeshLib::PropertyVector<std::size_t>* orig_node_ids(nullptr);
     // check if a node property containing the subsurface ids is available
-    auto* orig_node_ids =
-        surface_mesh->getProperties().getPropertyVector<std::size_t>(
-            id_prop_name.getValue());
     // if the node property is not available generate it
-    if (!orig_node_ids)
+    if (!surface_mesh->getProperties().existsPropertyVector<std::size_t>(
+            id_prop_name.getValue()))
     {
         orig_node_ids =
             surface_mesh->getProperties().createNewPropertyVector<std::size_t>(
@@ -100,6 +99,12 @@ int main (int argc, char* argv[])
         orig_node_ids->resize(surface_mesh->getNumberOfNodes());
         std::iota(orig_node_ids->begin(), orig_node_ids->end(), 0);
     }
+    else
+    {
+        orig_node_ids =
+            surface_mesh->getProperties().getPropertyVector<std::size_t>(
+                id_prop_name.getValue());
+    }
 
     std::vector<double> areas(
         MeshLib::MeshSurfaceExtraction::getSurfaceAreaForNodes(*surface_mesh));
diff --git a/Applications/Utils/ModelPreparation/createNeumannBc.cpp b/Applications/Utils/ModelPreparation/createNeumannBc.cpp
index 42fecaec905..fd6ea0a8856 100644
--- a/Applications/Utils/ModelPreparation/createNeumannBc.cpp
+++ b/Applications/Utils/ModelPreparation/createNeumannBc.cpp
@@ -38,16 +38,15 @@ std::vector<double> getSurfaceIntegratedValuesForNodes(
         return std::vector<double>();
     }
 
-    auto const* const elem_pv =
-        mesh.getProperties().getPropertyVector<double>(prop_name);
-    if (!elem_pv)
+    if (!mesh.getProperties().existsPropertyVector<double>(prop_name))
     {
         ERR("Need element property, but the property \"%s\" is not "
             "available.",
             prop_name.c_str());
         return std::vector<double>();
     }
-
+    auto const* const elem_pv =
+        mesh.getProperties().getPropertyVector<double>(prop_name);
 
     std::vector<double> integrated_node_area_vec;
     double total_area(0);
diff --git a/MeshGeoToolsLib/AppendLinesAlongPolyline.cpp b/MeshGeoToolsLib/AppendLinesAlongPolyline.cpp
index 1d4cdf9792a..ec658fe74a5 100644
--- a/MeshGeoToolsLib/AppendLinesAlongPolyline.cpp
+++ b/MeshGeoToolsLib/AppendLinesAlongPolyline.cpp
@@ -34,11 +34,12 @@ std::unique_ptr<MeshLib::Mesh> appendLinesAlongPolylines(
 
     std::vector<int> new_mat_ids;
     {
-        auto mat_ids = mesh.getProperties().getPropertyVector<int>("MaterialIDs");
-        if (mat_ids) {
-            new_mat_ids.reserve((*mat_ids).size());
-            std::copy((*mat_ids).cbegin(), (*mat_ids).cend(),
-                std::back_inserter(new_mat_ids));
+        if (mesh.getProperties().existsPropertyVector<int>("MaterialIDs")) {
+            auto ids =
+                mesh.getProperties().getPropertyVector<int>("MaterialIDs");
+            new_mat_ids.reserve(ids->size());
+            std::copy(ids->cbegin(), ids->cend(),
+                      std::back_inserter(new_mat_ids));
         }
     }
     int max_matID(0);
diff --git a/MeshLib/ElementStatus.cpp b/MeshLib/ElementStatus.cpp
index 17fa4542354..3beef299edc 100644
--- a/MeshLib/ElementStatus.cpp
+++ b/MeshLib/ElementStatus.cpp
@@ -34,8 +34,10 @@ ElementStatus::ElementStatus(Mesh const* const mesh,
                              std::vector<int> const& vec_inactive_matIDs)
     : ElementStatus(mesh, !vec_inactive_matIDs.empty())
 {
-    auto materialIds = mesh->getProperties().getPropertyVector<int>("MaterialIDs");
-    if (materialIds) {
+    if (mesh->getProperties().existsPropertyVector<int>("MaterialIDs"))
+    {
+        auto* const materialIds =
+            mesh->getProperties().getPropertyVector<int>("MaterialIDs");
         for (auto material_id : vec_inactive_matIDs) {
             for (auto e : _mesh->getElements()) {
                 if ((*materialIds)[e->getID()] == material_id) {
diff --git a/MeshLib/IO/Legacy/MeshIO.cpp b/MeshLib/IO/Legacy/MeshIO.cpp
index edbce896d2b..f68335d9133 100644
--- a/MeshLib/IO/Legacy/MeshIO.cpp
+++ b/MeshLib/IO/Legacy/MeshIO.cpp
@@ -281,10 +281,16 @@ bool MeshIO::write()
     _out << "$ELEMENTS\n"
         << "  ";
 
-    auto const* const materials =
-        _mesh->getProperties().getPropertyVector<int>("MaterialIDs");
-    writeElements(_mesh->getElements(), materials, _out);
-
+    if (!_mesh->getProperties().existsPropertyVector<int>("MaterialIDs"))
+    {
+        writeElements(_mesh->getElements(), nullptr, _out);
+    }
+    else
+    {
+        writeElements(
+            _mesh->getElements(),
+            _mesh->getProperties().getPropertyVector<int>("MaterialIDs"), _out);
+    }
     _out << "#STOP\n";
 
     return true;
diff --git a/MeshLib/Mesh.cpp b/MeshLib/Mesh.cpp
index c811bc3ab9c..a3a0b0e6420 100644
--- a/MeshLib/Mesh.cpp
+++ b/MeshLib/Mesh.cpp
@@ -323,6 +323,12 @@ void scaleMeshPropertyVector(MeshLib::Mesh & mesh,
                              std::string const& property_name,
                              double factor)
 {
+    if (!mesh.getProperties().existsPropertyVector<double>(property_name))
+    {
+        WARN("Did not find PropertyVector '%s' for scaling.",
+             property_name.c_str());
+        return;
+    }
     for (auto& v :
          *mesh.getProperties().getPropertyVector<double>(property_name))
         v *= factor;
diff --git a/MeshLib/MeshEditing/AddLayerToMesh.cpp b/MeshLib/MeshEditing/AddLayerToMesh.cpp
index c650d24c211..594c0e81d21 100644
--- a/MeshLib/MeshEditing/AddLayerToMesh.cpp
+++ b/MeshLib/MeshEditing/AddLayerToMesh.cpp
@@ -131,16 +131,17 @@ MeshLib::Mesh* addLayerToMesh(MeshLib::Mesh const& mesh, double thickness,
     std::vector<MeshLib::Node*> const& sfc_nodes(sfc_mesh->getNodes());
     std::size_t const n_sfc_nodes(sfc_nodes.size());
 
-    // fetch subsurface node ids PropertyVector
-    auto const* const node_id_pv =
-        sfc_mesh->getProperties().getPropertyVector<std::size_t>(prop_name);
-    if (!node_id_pv) {
+    if (!sfc_mesh->getProperties().existsPropertyVector<std::size_t>(prop_name))
+    {
         ERR(
             "Need subsurface node ids, but the property \"%s\" is not "
             "available.",
             prop_name.c_str());
         return nullptr;
     }
+    // fetch subsurface node ids PropertyVector
+    auto const* const node_id_pv =
+        sfc_mesh->getProperties().getPropertyVector<std::size_t>(prop_name);
 
     // *** copy sfc nodes to subsfc mesh node
     std::map<std::size_t, std::size_t> subsfc_sfc_id_map;
@@ -162,14 +163,14 @@ MeshLib::Mesh* addLayerToMesh(MeshLib::Mesh const& mesh, double thickness,
 
     auto new_mesh = new MeshLib::Mesh(name, subsfc_nodes, subsfc_elements);
 
-    auto const* const opt_materials =
-        mesh.getProperties().getPropertyVector<int>("MaterialIDs");
-    if (!opt_materials)
+    if (!mesh.getProperties().existsPropertyVector<int>("MaterialIDs"))
     {
         ERR("Could not copy the property \"MaterialIDs\" since the original "
             "mesh does not contain such a property.");
         return new_mesh;
     }
+    auto const* const materials =
+        mesh.getProperties().getPropertyVector<int>("MaterialIDs");
 
     auto* const new_materials =
         new_mesh->getProperties().createNewPropertyVector<int>(
@@ -182,9 +183,8 @@ MeshLib::Mesh* addLayerToMesh(MeshLib::Mesh const& mesh, double thickness,
 
     new_materials->reserve(subsfc_elements.size());
     int new_layer_id(
-        *(std::max_element(opt_materials->cbegin(), opt_materials->cend())) +
-        1);
-    std::copy(opt_materials->cbegin(), opt_materials->cend(),
+        *(std::max_element(materials->cbegin(), materials->cend())) + 1);
+    std::copy(materials->cbegin(), materials->cend(),
               std::back_inserter(*new_materials));
     auto const n_new_props(subsfc_elements.size() - mesh.getNumberOfElements());
     std::fill_n(std::back_inserter(*new_materials), n_new_props, new_layer_id);
diff --git a/MeshLib/MeshEditing/ConvertToLinearMesh.cpp b/MeshLib/MeshEditing/ConvertToLinearMesh.cpp
index 4be6af9a2af..235b063cfba 100644
--- a/MeshLib/MeshEditing/ConvertToLinearMesh.cpp
+++ b/MeshLib/MeshEditing/ConvertToLinearMesh.cpp
@@ -74,9 +74,9 @@ std::unique_ptr<MeshLib::Mesh> convertToLinearMesh(MeshLib::Mesh const& org_mesh
     MeshLib::Properties const& src_properties = org_mesh.getProperties();
     for (auto name : src_properties.getPropertyVectorNames())
     {
-        auto const* src_prop = src_properties.getPropertyVector<double>(name);
-        if (!src_prop)
+        if (!src_properties.existsPropertyVector<double>(name))
             continue;
+        auto const* src_prop = src_properties.getPropertyVector<double>(name);
         if (src_prop->getMeshItemType() != MeshLib::MeshItemType::Node)
             continue;
 
diff --git a/MeshLib/MeshEditing/ElementValueModification.cpp b/MeshLib/MeshEditing/ElementValueModification.cpp
index fc8bf6f6538..8cdbbb71b3a 100644
--- a/MeshLib/MeshEditing/ElementValueModification.cpp
+++ b/MeshLib/MeshEditing/ElementValueModification.cpp
@@ -28,13 +28,12 @@ bool ElementValueModification::replace(MeshLib::Mesh &mesh,
     std::string const& property_name, int const old_value, int const new_value,
     bool replace_if_exists)
 {
-    auto* const property_value_vec =
-        mesh.getProperties().getPropertyVector<int>(property_name);
-
-    if (!property_value_vec)
+    if (!mesh.getProperties().existsPropertyVector<int>(property_name))
     {
         return false;
     }
+    auto* const property_value_vec =
+        mesh.getProperties().getPropertyVector<int>(property_name);
 
     const std::size_t n_property_tuples(
         property_value_vec->getNumberOfTuples());
diff --git a/MeshLib/MeshEditing/Mesh2MeshPropertyInterpolation.cpp b/MeshLib/MeshEditing/Mesh2MeshPropertyInterpolation.cpp
index 41197cc4658..1736ad6159d 100644
--- a/MeshLib/MeshEditing/Mesh2MeshPropertyInterpolation.cpp
+++ b/MeshLib/MeshEditing/Mesh2MeshPropertyInterpolation.cpp
@@ -51,9 +51,13 @@ bool Mesh2MeshPropertyInterpolation::setPropertiesForMesh(Mesh& dest_mesh) const
         return false;
     }
 
-    auto* dest_properties =
-        dest_mesh.getProperties().getPropertyVector<double>(_property_name);
-    if (!dest_properties)
+    MeshLib::PropertyVector<double>* dest_properties;
+    if (dest_mesh.getProperties().existsPropertyVector<double>(_property_name))
+    {
+        dest_properties =
+            dest_mesh.getProperties().getPropertyVector<double>(_property_name);
+    }
+    else
     {
         INFO("Create new PropertyVector \"%s\" of type double.",
              _property_name.c_str());
@@ -140,14 +144,14 @@ void Mesh2MeshPropertyInterpolation::interpolateElementPropertiesToNodePropertie
     std::vector<double> &interpolated_properties) const
 {
     // fetch the source of property values
-    auto const* elem_props =
-        _src_mesh.getProperties().getPropertyVector<double>(_property_name);
-    if (!elem_props)
+    if (!_src_mesh.getProperties().existsPropertyVector<double>(_property_name))
     {
         WARN("Did not find PropertyVector<double> \"%s\".",
              _property_name.c_str());
         return;
     }
+    auto const* elem_props =
+        _src_mesh.getProperties().getPropertyVector<double>(_property_name);
 
     std::vector<MeshLib::Node*> const& src_nodes(_src_mesh.getNodes());
     const std::size_t n_src_nodes(src_nodes.size());
diff --git a/MeshLib/MeshEditing/MeshRevision.cpp b/MeshLib/MeshEditing/MeshRevision.cpp
index d322b4746d5..3d53c0df144 100644
--- a/MeshLib/MeshEditing/MeshRevision.cpp
+++ b/MeshLib/MeshEditing/MeshRevision.cpp
@@ -63,15 +63,16 @@ MeshLib::Mesh* MeshRevision::simplifyMesh(const std::string &new_mesh_name,
     // original data
     std::vector<MeshLib::Element*> const& elements(this->_mesh.getElements());
     MeshLib::Properties const& properties(_mesh.getProperties());
-    auto const* const material_vec =
-        properties.getPropertyVector<int>("MaterialIDs");
 
     // data structures for the new mesh
     std::vector<MeshLib::Node*> new_nodes = this->constructNewNodesArray(this->collapseNodeIndices(eps));
     std::vector<MeshLib::Element*> new_elements;
     MeshLib::Properties new_properties;
     PropertyVector<int>* new_material_vec = nullptr;
-    if (material_vec) {
+    PropertyVector<int> const* material_vec = nullptr;
+    if (properties.existsPropertyVector<int>("MaterialIDs"))
+    {
+        material_vec = properties.getPropertyVector<int>("MaterialIDs");
         new_material_vec = new_properties.createNewPropertyVector<int>(
             "MaterialIDs", MeshItemType::Cell, 1);
     }
@@ -94,10 +95,10 @@ MeshLib::Mesh* MeshRevision::simplifyMesh(const std::string &new_mesh_name,
                     this->cleanUp(new_nodes, new_elements);
                     return nullptr;
                 }
-                if (!material_vec)
-                    continue;
-                new_material_vec->insert(new_material_vec->end(),
-                    n_new_elements, (*material_vec)[k]);
+                if (material_vec)
+                    new_material_vec->insert(new_material_vec->end(),
+                                             n_new_elements,
+                                             (*material_vec)[k]);
             } else {
                 new_elements.push_back(MeshLib::copyElement(elem, new_nodes));
                 // copy material values
diff --git a/MeshLib/MeshInformation.h b/MeshLib/MeshInformation.h
index 867b4d9f2d5..659c97ba672 100644
--- a/MeshLib/MeshInformation.h
+++ b/MeshLib/MeshInformation.h
@@ -37,10 +37,10 @@ public:
     static std::pair<T, T> const
         getValueBounds(MeshLib::Mesh const& mesh, std::string const& name)
     {
+        if (!mesh.getProperties().existsPropertyVector<T>(name))
+            return {std::numeric_limits<T>::max(), std::numeric_limits<T>::max()};
         auto const* const data_vec =
             mesh.getProperties().getPropertyVector<T>(name);
-        if (!data_vec)
-            return {std::numeric_limits<T>::max(), std::numeric_limits<T>::max()};
         if (data_vec->empty()) {
             INFO("Mesh does not contain values for the property \"%s\".", name.c_str());
             return {std::numeric_limits<T>::max(), std::numeric_limits<T>::max()};
diff --git a/MeshLib/MeshSearch/ElementSearch.h b/MeshLib/MeshSearch/ElementSearch.h
index 80b48055953..d18d9f10d5a 100644
--- a/MeshLib/MeshSearch/ElementSearch.h
+++ b/MeshLib/MeshSearch/ElementSearch.h
@@ -47,14 +47,15 @@ public:
         PROPERTY_TYPE const property_value,
         std::string const& property_name = "MaterialIDs")
     {
-        auto const* const pv =
-            _mesh.getProperties().getPropertyVector<PROPERTY_TYPE>(
-                property_name);
-        if (!pv)
+        if (!_mesh.getProperties().existsPropertyVector<PROPERTY_TYPE>(
+                property_name))
         {
             WARN("Property \"%s\" not found in mesh.", property_name.c_str());
             return 0;
         }
+        auto const* const pv =
+            _mesh.getProperties().getPropertyVector<PROPERTY_TYPE>(
+                property_name);
 
         if (pv->getMeshItemType() != MeshLib::MeshItemType::Cell)
         {
diff --git a/MeshLib/Vtk/VtkMappedMeshSource.h b/MeshLib/Vtk/VtkMappedMeshSource.h
index b3ec4cfae48..43fc037a2f9 100644
--- a/MeshLib/Vtk/VtkMappedMeshSource.h
+++ b/MeshLib/Vtk/VtkMappedMeshSource.h
@@ -76,9 +76,9 @@ private:
     bool addProperty(MeshLib::Properties const& properties,
                      std::string const& prop_name) const
     {
-        auto* const propertyVector = properties.getPropertyVector<T>(prop_name);
-        if(!propertyVector)
+        if (!properties.existsPropertyVector<T>(prop_name))
             return false;
+        auto* const propertyVector = properties.getPropertyVector<T>(prop_name);
 
         vtkNew<VtkMappedPropertyVectorTemplate<T> > dataArray;
         dataArray->SetPropertyVector(const_cast<MeshLib::PropertyVector<T> &>(*propertyVector));
diff --git a/MeshLib/convertMeshToGeo.cpp b/MeshLib/convertMeshToGeo.cpp
index 7d77314bfed..7b1f2b2562b 100644
--- a/MeshLib/convertMeshToGeo.cpp
+++ b/MeshLib/convertMeshToGeo.cpp
@@ -63,7 +63,10 @@ bool convertMeshToGeo(const MeshLib::Mesh &mesh, GeoLib::GEOObjects &geo_objects
     const std::vector<MeshLib::Element*> &elements = mesh.getElements();
     const std::size_t nElems (mesh.getNumberOfElements());
 
-    auto const materialIds = mesh.getProperties().getPropertyVector<int>(mat_name);
+    MeshLib::PropertyVector<int> const*const materialIds =
+        mesh.getProperties().existsPropertyVector<int>("MaterialIDs")
+            ? mesh.getProperties().getPropertyVector<int>("MaterialIDs")
+            : nullptr;
 
     for (unsigned i=0; i<nElems; ++i)
     {
diff --git a/ProcessLib/HT/CreatePorousMediaProperties.cpp b/ProcessLib/HT/CreatePorousMediaProperties.cpp
index d10e7392eb4..cc18b29f5ff 100644
--- a/ProcessLib/HT/CreatePorousMediaProperties.cpp
+++ b/ProcessLib/HT/CreatePorousMediaProperties.cpp
@@ -72,10 +72,10 @@ PorousMediaProperties createPorousMediaProperties(
     BaseLib::reorderVector(storage_models, mat_ids);
 
     std::vector<int> material_ids(mesh.getNumberOfElements());
-    auto const& mesh_material_ids =
-        mesh.getProperties().getPropertyVector<int>("MaterialIDs");
-    if (mesh_material_ids)
+    if (mesh.getProperties().existsPropertyVector<int>("MaterialIDs"))
     {
+        auto const& mesh_material_ids =
+            mesh.getProperties().getPropertyVector<int>("MaterialIDs");
         material_ids.reserve(mesh_material_ids->size());
         std::copy(mesh_material_ids->cbegin(), mesh_material_ids->cend(),
                   material_ids.begin());
diff --git a/ProcessLib/LIE/Common/PostUtils.cpp b/ProcessLib/LIE/Common/PostUtils.cpp
index 9f320c54af5..7e08cd88d57 100644
--- a/ProcessLib/LIE/Common/PostUtils.cpp
+++ b/ProcessLib/LIE/Common/PostUtils.cpp
@@ -121,9 +121,10 @@ void PostProcessTool::createProperties()
     MeshLib::Properties const& src_properties = _org_mesh.getProperties();
     for (auto name : src_properties.getPropertyVectorNames())
     {
-        auto const* src_prop = src_properties.getPropertyVector<T>(name);
-        if (!src_prop)
+        if (!src_properties.existsPropertyVector<T>(name))
             continue;
+        auto const* src_prop = src_properties.getPropertyVector<T>(name);
+
         auto const n_src_comp = src_prop->getNumberOfComponents();
         // convert 2D vector to 3D. Otherwise Paraview Calculator filter does not recognize
         // it as a vector
@@ -159,11 +160,10 @@ void PostProcessTool::copyProperties()
     MeshLib::Properties const& src_properties = _org_mesh.getProperties();
     for (auto name : src_properties.getPropertyVectorNames())
     {
-        auto const* src_prop = src_properties.getPropertyVector<T>(name);
-        if (!src_prop)
+        if (!src_properties.existsPropertyVector<T>(name))
             continue;
+        auto const* src_prop = src_properties.getPropertyVector<T>(name);
         auto* dest_prop = _output_mesh->getProperties().getPropertyVector<T>(name);
-        assert(dest_prop);
 
         if (src_prop->getMeshItemType() == MeshLib::MeshItemType::Node)
         {
diff --git a/ProcessLib/LiquidFlow/CreateLiquidFlowProcess.cpp b/ProcessLib/LiquidFlow/CreateLiquidFlowProcess.cpp
index e81a4749bb6..1259fd97584 100644
--- a/ProcessLib/LiquidFlow/CreateLiquidFlowProcess.cpp
+++ b/ProcessLib/LiquidFlow/CreateLiquidFlowProcess.cpp
@@ -78,12 +78,12 @@ std::unique_ptr<Process> createLiquidFlowProcess(
     //! \ogs_file_param{prj__processes__process__LIQUID_FLOW__material_property}
     auto const& mat_config = config.getConfigSubtree("material_property");
 
-    auto const& mat_ids =
-        mesh.getProperties().getPropertyVector<int>("MaterialIDs");
-    if (mat_ids)
+    if (mesh.getProperties().existsPropertyVector<int>("MaterialIDs"))
     {
         INFO("The liquid flow is in heterogeneous porous media.");
         const bool has_material_ids = true;
+        auto const& mat_ids =
+            mesh.getProperties().getPropertyVector<int>("MaterialIDs");
         return std::unique_ptr<Process>{new LiquidFlowProcess{
             mesh, std::move(jacobian_assembler), parameters, integration_order,
             std::move(process_variables), std::move(secondary_variables),
diff --git a/ProcessLib/TwoPhaseFlowWithPP/CreateTwoPhaseFlowWithPPProcess.cpp b/ProcessLib/TwoPhaseFlowWithPP/CreateTwoPhaseFlowWithPPProcess.cpp
index cfbf98b8730..460edafca73 100644
--- a/ProcessLib/TwoPhaseFlowWithPP/CreateTwoPhaseFlowWithPPProcess.cpp
+++ b/ProcessLib/TwoPhaseFlowWithPP/CreateTwoPhaseFlowWithPPProcess.cpp
@@ -75,17 +75,16 @@ std::unique_ptr<Process> CreateTwoPhaseFlowWithPPProcess(
     //! \ogs_file_param{prj__processes__process__TWOPHASE_FLOW_PP__material_property}
     auto const& mat_config = config.getConfigSubtree("material_property");
 
-    auto const& mat_ids =
-        mesh.getProperties().getPropertyVector<int>("MaterialIDs");
-
     std::unique_ptr<
         MaterialLib::TwoPhaseFlowWithPP::TwoPhaseFlowWithPPMaterialProperties>
         material = nullptr;
 
-    if (mat_ids)
+    if (mesh.getProperties().existsPropertyVector<int>("MaterialIDs"))
     {
         INFO("The twophase flow is in heterogeneous porous media.");
         const bool has_material_ids = true;
+        auto const& mat_ids =
+            mesh.getProperties().getPropertyVector<int>("MaterialIDs");
         material = MaterialLib::TwoPhaseFlowWithPP::
             CreateTwoPhaseFlowMaterialProperties(mat_config, has_material_ids,
                                                  *mat_ids);
diff --git a/ProcessLib/TwoPhaseFlowWithPrho/CreateTwoPhaseFlowWithPrhoProcess.cpp b/ProcessLib/TwoPhaseFlowWithPrho/CreateTwoPhaseFlowWithPrhoProcess.cpp
index 81a42ce819d..62288cf12b3 100644
--- a/ProcessLib/TwoPhaseFlowWithPrho/CreateTwoPhaseFlowWithPrhoProcess.cpp
+++ b/ProcessLib/TwoPhaseFlowWithPrho/CreateTwoPhaseFlowWithPrhoProcess.cpp
@@ -83,15 +83,12 @@ std::unique_ptr<Process> createTwoPhaseFlowWithPrhoProcess(
     //! \ogs_file_param{prj__processes__process__TWOPHASE_FLOW_PRHO__material_property}
     auto const& mat_config = config.getConfigSubtree("material_property");
 
-    auto const& mat_ids =
-        mesh.getProperties().getPropertyVector<int>("MaterialIDs");
-
-    std::unique_ptr<TwoPhaseFlowWithPrhoMaterialProperties> material = nullptr;
-
     boost::optional<MeshLib::PropertyVector<int> const&> material_ids;
-    if (mat_ids != nullptr)
+    if (mesh.getProperties().existsPropertyVector<int>("MaterialIDs"))
     {
         INFO("The twophase flow is in heterogeneous porous media.");
+        auto const& mat_ids =
+            mesh.getProperties().getPropertyVector<int>("MaterialIDs");
         material_ids = *mat_ids;
     }
     else
@@ -99,7 +96,7 @@ std::unique_ptr<Process> createTwoPhaseFlowWithPrhoProcess(
         INFO("The twophase flow is in homogeneous porous media.");
     }
 
-    material =
+    std::unique_ptr<TwoPhaseFlowWithPrhoMaterialProperties> material =
         createTwoPhaseFlowPrhoMaterialProperties(mat_config, material_ids);
 
     TwoPhaseFlowWithPrhoProcessData process_data{
diff --git a/Tests/MeshLib/MeshProperties.cpp b/Tests/MeshLib/MeshProperties.cpp
index 14b24478a14..db3a116880e 100644
--- a/Tests/MeshLib/MeshProperties.cpp
+++ b/Tests/MeshLib/MeshProperties.cpp
@@ -122,19 +122,15 @@ TEST_F(MeshLibProperties, AddDoubleProperties)
         ASSERT_EQ(static_cast<double>(k+1), (*double_properties)[k]);
     }
 
+    ASSERT_TRUE(mesh->getProperties().existsPropertyVector<double>(prop_name));
     auto* const double_properties_cpy =
         mesh->getProperties().getPropertyVector<double>(prop_name);
-    ASSERT_FALSE(!double_properties_cpy);
-
     for (std::size_t k(0); k<size; k++) {
         ASSERT_EQ((*double_properties)[k], (*double_properties_cpy)[k]);
     }
 
     mesh->getProperties().removePropertyVector(prop_name);
-    auto* const removed_double_properties =
-        mesh->getProperties().getPropertyVector<double>(prop_name);
-
-    ASSERT_TRUE(!removed_double_properties);
+    ASSERT_FALSE(mesh->getProperties().existsPropertyVector<double>(prop_name));
 }
 
 TEST_F(MeshLibProperties, AddDoublePointerProperties)
@@ -204,10 +200,8 @@ TEST_F(MeshLibProperties, AddDoublePointerProperties)
     }
 
     mesh->getProperties().removePropertyVector(prop_name);
-    auto const* const removed_group_properties =
-        mesh->getProperties().getPropertyVector<double*>(prop_name);
-
-    ASSERT_TRUE(!removed_group_properties);
+    ASSERT_FALSE(
+        mesh->getProperties().existsPropertyVector<double*>(prop_name));
 }
 
 TEST_F(MeshLibProperties, AddArrayPointerProperties)
@@ -285,11 +279,10 @@ TEST_F(MeshLibProperties, AddArrayPointerProperties)
     }
 
     mesh->getProperties().removePropertyVector(prop_name);
-    auto const* const removed_group_properties =
-        mesh->getProperties().getPropertyVector<std::array<double, 3>*>(
+    auto exists =
+        mesh->getProperties().existsPropertyVector<std::array<double, 3>*>(
             prop_name);
-
-    ASSERT_TRUE(!removed_group_properties);
+    ASSERT_FALSE(exists);
 }
 
 TEST_F(MeshLibProperties, AddVariousDifferentProperties)
-- 
GitLab