mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-10 23:46:00 -06:00
153 lines
6.5 KiB
C++
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;
|
|
}
|