///////////////////////////////////////////////////////////////////////////////// // // 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 // 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::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( 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::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( 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; }