ResInsight/ApplicationLibCode/GeoMech/GeoMechDataModel/RigFemClosestResultIndexCalculator.cpp
2021-01-11 15:27:45 +01:00

153 lines
6.5 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigFemClosestResultIndexCalculator.h"
#include "RigFemPart.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemClosestResultIndexCalculator::RigFemClosestResultIndexCalculator( RigFemPart* femPart,
RigFemResultPosEnum resultPosition,
int elementIndex,
int m_face,
const cvf::Vec3d& intersectionPointInDomain )
{
m_resultIndexToClosestResult = -1;
m_closestNodeId = -1;
m_closestElementNodeResIdx = -1;
if ( resultPosition != RIG_ELEMENT_NODAL_FACE || m_face == -1 )
{
RigElementType elmType = femPart->elementType( elementIndex );
const int* elementConn = femPart->connectivities( elementIndex );
int elmNodeCount = RigFemTypes::elementNodeCount( elmType );
// Find the closest node
int closestLocalNode = -1;
float minDist = std::numeric_limits<float>::infinity();
for ( int lNodeIdx = 0; lNodeIdx < elmNodeCount; ++lNodeIdx )
{
int nodeIdx = elementConn[lNodeIdx];
cvf::Vec3f nodePosInDomain = femPart->nodes().coordinates[nodeIdx];
float dist = ( nodePosInDomain - cvf::Vec3f( intersectionPointInDomain ) ).lengthSquared();
if ( dist < minDist )
{
closestLocalNode = lNodeIdx;
minDist = dist;
}
}
if ( closestLocalNode >= 0 )
{
int nodeIdx = elementConn[closestLocalNode];
m_closestElementNodeResIdx =
static_cast<int>( femPart->elementNodeResultIdx( elementIndex, closestLocalNode ) );
if ( resultPosition == RIG_NODAL )
{
m_resultIndexToClosestResult = nodeIdx;
}
else if ( resultPosition == RIG_ELEMENT_NODAL_FACE )
{
m_resultIndexToClosestResult = -1;
}
else if ( resultPosition == RIG_ELEMENT )
{
m_resultIndexToClosestResult = elementIndex;
}
else
{
m_resultIndexToClosestResult = m_closestElementNodeResIdx;
}
m_closestNodeId = femPart->nodes().nodeIds[nodeIdx];
}
}
else if ( m_face != -1 )
{
int elmNodFaceResIdx = -1;
int closestNodeIdx = -1;
{
int closestLocFaceNode = -1;
int closestLocalElmNode = -1;
{
RigElementType elmType = femPart->elementType( elementIndex );
const int* elmNodeIndices = femPart->connectivities( elementIndex );
int faceNodeCount = 0;
const int* localElmNodeIndicesForFace =
RigFemTypes::localElmNodeIndicesForFace( elmType, m_face, &faceNodeCount );
float minDist = std::numeric_limits<float>::infinity();
for ( int faceNodIdx = 0; faceNodIdx < faceNodeCount; ++faceNodIdx )
{
int nodeIdx = elmNodeIndices[localElmNodeIndicesForFace[faceNodIdx]];
cvf::Vec3f nodePosInDomain = femPart->nodes().coordinates[nodeIdx];
float dist = ( nodePosInDomain - cvf::Vec3f( intersectionPointInDomain ) ).lengthSquared();
if ( dist < minDist )
{
closestLocFaceNode = faceNodIdx;
closestNodeIdx = nodeIdx;
closestLocalElmNode = localElmNodeIndicesForFace[faceNodIdx];
minDist = dist;
}
}
}
int elmNodFaceResIdxElmStart = elementIndex * 24; // HACK should get from part
int elmNodFaceResIdxFaceStart = elmNodFaceResIdxElmStart + 4 * m_face;
if ( closestLocFaceNode >= 0 )
{
elmNodFaceResIdx = elmNodFaceResIdxFaceStart + closestLocFaceNode;
m_closestElementNodeResIdx =
static_cast<int>( femPart->elementNodeResultIdx( elementIndex, closestLocalElmNode ) );
}
}
m_resultIndexToClosestResult = elmNodFaceResIdx;
m_closestNodeId = femPart->nodes().nodeIds[closestNodeIdx];
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RigFemClosestResultIndexCalculator::resultIndexToClosestResult() const
{
return m_resultIndexToClosestResult;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RigFemClosestResultIndexCalculator::closestNodeId() const
{
return m_closestNodeId;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RigFemClosestResultIndexCalculator::closestElementNodeResIdx() const
{
return m_closestElementNodeResIdx;
}