Skip to content

Commit

Permalink
GRIDEDIT-778 Added check if edge could not be found
Browse files Browse the repository at this point in the history
  • Loading branch information
BillSenior committed May 14, 2024
1 parent efce2b2 commit b52a940
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 42 deletions.
40 changes: 21 additions & 19 deletions libs/MeshKernel/include/MeshKernel/CasulliDeRefinement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ namespace meshkernel
/// @brief Compute the Casulli de-refinement for the entire mesh.
///
/// @param [in, out] mesh Mesh to be de-refined
std::unique_ptr<meshkernel::UndoAction> Compute(Mesh2D& mesh);
[[nodiscard]] std::unique_ptr<UndoAction> Compute(Mesh2D& mesh);

/// @brief Compute the Casulli de-refinement for the part of the mesh inside the polygon
///
/// @param [in, out] mesh Mesh to be de-refined
/// @param [in] polygon Area within which the mesh will be de-refined
std::unique_ptr<meshkernel::UndoAction> Compute(Mesh2D& mesh, const Polygons& polygon);
[[nodiscard]] std::unique_ptr<UndoAction> Compute(Mesh2D& mesh, const Polygons& polygon);

/// @brief Compute centres of elements to be deleted.
///
Expand Down Expand Up @@ -119,10 +119,10 @@ namespace meshkernel
const UInt nodeId);

/// @brief Update the mesh members for the mesh description and connectivity.
void UpdateDirectlyConnectedElements(Mesh2D& mesh,
const UInt elementId,
const std::vector<UInt>& directlyConnected,
const std::vector<std::array<int, 2>>& kne);
[[nodiscard]] bool UpdateDirectlyConnectedElements(Mesh2D& mesh,
const UInt elementId,
const std::vector<UInt>& directlyConnected,
const std::vector<std::array<int, 2>>& kne);

/// @brief Get the most significant node type for all nodes of the element.
int GetNodeCode(const Mesh2D& mesh,
Expand All @@ -138,30 +138,32 @@ namespace meshkernel
void RedirectNodesOfConnectedElements(Mesh2D& mesh, const UInt elementId, const UInt nodeId, const std::vector<UInt>& indirectlyConnected);

/// @brief Removes nodes from the boundary that will not be part of the de-refined mesh.
void RemoveUnwantedBoundaryNodes(Mesh2D& mesh,
const std::vector<int>& nodeTypes,
const Polygons& polygon,
const std::vector<UInt>& indirectlyConnected);
[[nodiscard]] bool RemoveUnwantedBoundaryNodes(Mesh2D& mesh,
const std::vector<int>& nodeTypes,
const Polygons& polygon,
const std::vector<UInt>& indirectlyConnected);

/// @brief Delete an element
void DeleteElement(Mesh2D& mesh,
std::vector<int>& nodeTypes,
const Polygons& polygon,
const UInt elementId,
const std::vector<UInt>& directlyConnected,
const std::vector<UInt>& indirectlyConnected,
const std::vector<std::array<int, 2>>& kne);
[[nodiscard]] bool DeleteElement(Mesh2D& mesh,
std::vector<int>& nodeTypes,
const Polygons& polygon,
const UInt elementId,
const std::vector<UInt>& directlyConnected,
const std::vector<UInt>& indirectlyConnected,
const std::vector<std::array<int, 2>>& kne);

/// @brief Clean up the edge
void CleanUpEdge(Mesh2D& mesh, const UInt edgeId);
///
/// @returns Indicates if the cleanp-up was successful or not
[[nodiscard]] bool CleanUpEdge(Mesh2D& mesh, const UInt edgeId);

/// @brief Find the id of the shared node for two edges.
///
/// If no node is shared then return null value
UInt FindCommonNode(const Mesh2D& mesh, const UInt edgeId1, const UInt edgeId2);

/// @brief Do the Casullu de-refinement
void DoDeRefinement(Mesh2D& mesh, const Polygons& polygon);
[[nodiscard]] bool DoDeRefinement(Mesh2D& mesh, const Polygons& polygon);

/// @brief Compute the mesh node types.
///
Expand Down
92 changes: 69 additions & 23 deletions libs/MeshKernel/src/CasulliDeRefinement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
//------------------------------------------------------------------------------

#include <algorithm>
#include <iostream> // REMOVE
using namespace std;

#include "MeshKernel/CasulliDeRefinement.hpp"
#include "MeshKernel/Exceptions.hpp"
Expand All @@ -48,10 +46,19 @@ std::unique_ptr<meshkernel::UndoAction> meshkernel::CasulliDeRefinement::Compute
const std::vector<Point> meshNodes(mesh.Nodes());
const std::vector<Edge> meshEdges(mesh.Edges());

DoDeRefinement(mesh, polygon);

mesh.DeleteInvalidNodesAndEdges();
mesh.Administrate();
if (DoDeRefinement(mesh, polygon))
{
mesh.DeleteInvalidNodesAndEdges();
mesh.Administrate();
}
else
{
// The de-refinement failed, restore the original mesh
refinementAction->Restore();
// Reset the undo action to a null action
refinementAction.reset(nullptr);
throw AlgorithmError("Unable to compute the Casulli de-refinement");
}

return refinementAction;
}
Expand Down Expand Up @@ -407,7 +414,7 @@ std::vector<meshkernel::CasulliDeRefinement::ElementMask> meshkernel::CasulliDeR
return cellMask;
}

void meshkernel::CasulliDeRefinement::DoDeRefinement(Mesh2D& mesh, const Polygons& polygon)
bool meshkernel::CasulliDeRefinement::DoDeRefinement(Mesh2D& mesh, const Polygons& polygon)
{
UInt nMax = 1000;
std::vector<UInt> directlyConnected;
Expand All @@ -425,9 +432,15 @@ void meshkernel::CasulliDeRefinement::DoDeRefinement(Mesh2D& mesh, const Polygon
if (cellMask[k] == ElementMask::NotA && mesh.m_numFacesNodes[k] > 0)
{
FindSurroundingCells(mesh, k, directlyConnected, indirectlyConnected, kne);
DeleteElement(mesh, nodeTypes, polygon, k, directlyConnected, indirectlyConnected, kne);

if (!DeleteElement(mesh, nodeTypes, polygon, k, directlyConnected, indirectlyConnected, kne))
{
return false;
}
}
}

return true;
}

bool meshkernel::CasulliDeRefinement::ElementCannotBeDeleted(const Mesh2D& mesh,
Expand Down Expand Up @@ -527,7 +540,7 @@ meshkernel::Point meshkernel::CasulliDeRefinement::ComputeNewNodeCoordinates(con
return newNode;
}

void meshkernel::CasulliDeRefinement::UpdateDirectlyConnectedElements(Mesh2D& mesh,
bool meshkernel::CasulliDeRefinement::UpdateDirectlyConnectedElements(Mesh2D& mesh,
const UInt elementId,
const std::vector<UInt>& directlyConnected,
const std::vector<std::array<int, 2>>& kne)
Expand All @@ -545,7 +558,10 @@ void meshkernel::CasulliDeRefinement::UpdateDirectlyConnectedElements(Mesh2D& me

if (mesh.m_edgesNumFaces[edgeId] < 2)
{
CleanUpEdge(mesh, edgeId);
if (!CleanUpEdge(mesh, edgeId))
{
return false;
}
}
}

Expand Down Expand Up @@ -616,7 +632,11 @@ void meshkernel::CasulliDeRefinement::UpdateDirectlyConnectedElements(Mesh2D& me
if (otherEdgeId != constants::missing::uintValue)
{
mesh.m_facesEdges[leftElementId][j] = otherEdgeId;
CleanUpEdge(mesh, edgeId);

if (!CleanUpEdge(mesh, edgeId))
{
return false;
}
}

otherEdgeId = edgeId;
Expand Down Expand Up @@ -673,6 +693,8 @@ void meshkernel::CasulliDeRefinement::UpdateDirectlyConnectedElements(Mesh2D& me
}
}
}

return true;
}

int meshkernel::CasulliDeRefinement::GetNodeCode(const Mesh2D& mesh,
Expand Down Expand Up @@ -716,7 +738,7 @@ void meshkernel::CasulliDeRefinement::RedirectNodesOfConnectedElements(Mesh2D& m
}
}

void meshkernel::CasulliDeRefinement::RemoveUnwantedBoundaryNodes(Mesh2D& mesh,
bool meshkernel::CasulliDeRefinement::RemoveUnwantedBoundaryNodes(Mesh2D& mesh,
const std::vector<int>& nodeTypes,
const Polygons& polygon,
const std::vector<UInt>& indirectlyConnected)
Expand Down Expand Up @@ -773,16 +795,24 @@ void meshkernel::CasulliDeRefinement::RemoveUnwantedBoundaryNodes(Mesh2D& mesh,

// delete other link

CleanUpEdge(mesh, edgeId);
if (CleanUpEdge(mesh, edgeId))
{
return false;
}

mesh.SetNode(nodeId, {constants::missing::doubleValue, constants::missing::doubleValue});
continueOuterLoop = true;
break;
}
else
{
mesh.m_numFacesNodes[connectedElementId] = 0;
CleanUpEdge(mesh, edgeId);
CleanUpEdge(mesh, previousEdgeId);

if (!CleanUpEdge(mesh, edgeId) || !CleanUpEdge(mesh, previousEdgeId))
{
return false;
}

// previous-previous edgeId (not a real word)
UInt antePreviousEdgeId = std::accumulate(mesh.m_facesEdges[connectedElementId].begin(), mesh.m_facesEdges[connectedElementId].begin() + 3, 0) - edgeId - previousEdgeId;

Expand Down Expand Up @@ -812,9 +842,11 @@ void meshkernel::CasulliDeRefinement::RemoveUnwantedBoundaryNodes(Mesh2D& mesh,
continue;
}
}

return true;
}

void meshkernel::CasulliDeRefinement::DeleteElement(Mesh2D& mesh,
bool meshkernel::CasulliDeRefinement::DeleteElement(Mesh2D& mesh,
std::vector<int>& nodeTypes,
const Polygons& polygon,
const UInt elementId,
Expand All @@ -824,12 +856,12 @@ void meshkernel::CasulliDeRefinement::DeleteElement(Mesh2D& mesh,
{
if (directlyConnected.size() == 0 || indirectlyConnected.size() == 0)
{
return;
return true;
}

if (ElementCannotBeDeleted(mesh, nodeTypes, polygon, elementId))
{
return;
return true;
}

Point newNode(ComputeNewNodeCoordinates(mesh, nodeTypes, elementId));
Expand All @@ -840,7 +872,11 @@ void meshkernel::CasulliDeRefinement::DeleteElement(Mesh2D& mesh,
}

UInt N = mesh.m_numFacesNodes[elementId];
UpdateDirectlyConnectedElements(mesh, elementId, directlyConnected, kne);

if (!UpdateDirectlyConnectedElements(mesh, elementId, directlyConnected, kne))
{
return false;
}

//--------------------------------
// Set the node code
Expand All @@ -858,20 +894,29 @@ void meshkernel::CasulliDeRefinement::DeleteElement(Mesh2D& mesh,

// redirect nodes of indirectly connected cells, deactivate polygons of degree smaller than three
RedirectNodesOfConnectedElements(mesh, elementId, nodeId, indirectlyConnected);

// remove unwanted boundary node: a non-corner node that is shared by two boundary links
RemoveUnwantedBoundaryNodes(mesh, nodeTypes, polygon, indirectlyConnected);
if (!RemoveUnwantedBoundaryNodes(mesh, nodeTypes, polygon, indirectlyConnected))
{
return false;
}
// redirect nodes of directly connected cells and deactivate polygons of degree smaller than three
RedirectNodesOfConnectedElements(mesh, elementId, nodeId, directlyConnected);

// deactivate links
for (UInt i = 0; i < mesh.m_numFacesNodes[elementId]; ++i)
{
UInt L = mesh.m_facesEdges[elementId][i];
CleanUpEdge(mesh, L);

if (!CleanUpEdge(mesh, L))
{
return false;
}
}

// deactivate cell
mesh.m_numFacesNodes[elementId] = 0;
return true;
}

meshkernel::UInt meshkernel::CasulliDeRefinement::FindCommonNode(const Mesh2D& mesh, const UInt edgeId1, const UInt edgeId2)
Expand All @@ -892,7 +937,7 @@ meshkernel::UInt meshkernel::CasulliDeRefinement::FindCommonNode(const Mesh2D& m
return constants::missing::uintValue;
}

void meshkernel::CasulliDeRefinement::CleanUpEdge(Mesh2D& mesh, const UInt edgeId)
bool meshkernel::CasulliDeRefinement::CleanUpEdge(Mesh2D& mesh, const UInt edgeId)
{

for (UInt i = 0; i < 2; ++i)
Expand Down Expand Up @@ -923,14 +968,15 @@ void meshkernel::CasulliDeRefinement::CleanUpEdge(Mesh2D& mesh, const UInt edgeI
else
{
// Error: no link found
return;
return false;
}

--mesh.m_nodesNumEdges[nodeId];
}

mesh.GetEdge(edgeId).first = constants::missing::uintValue;
mesh.GetEdge(edgeId).second = constants::missing::uintValue;
return true;
}

std::vector<int> meshkernel::CasulliDeRefinement::ComputeNodeTypes(const Mesh2D& mesh, const Polygons& polygon)
Expand Down

0 comments on commit b52a940

Please sign in to comment.