mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-01 03:37:15 -06:00
244 lines
9.4 KiB
C++
244 lines
9.4 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) Statoil ASA
|
|
//
|
|
// 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 "RiuGeoMechXfTensorResultAccessor.h"
|
|
#include "RigFemPartResultsCollection.h"
|
|
#include "RivIntersectionVertexWeights.h"
|
|
#include "cvfAssert.h"
|
|
#include "cvfGeometryTools.h"
|
|
|
|
float RiuGeoMechXfTensorResultAccessor::SN( const caf::Ten3f& t ) const
|
|
{
|
|
return t[caf::Ten3f::SZZ];
|
|
}
|
|
float RiuGeoMechXfTensorResultAccessor::STH( const caf::Ten3f& t ) const
|
|
{
|
|
return t[caf::Ten3f::SXX];
|
|
}
|
|
float RiuGeoMechXfTensorResultAccessor::STQV( const caf::Ten3f& t ) const
|
|
{
|
|
return t[caf::Ten3f::SYY];
|
|
}
|
|
float RiuGeoMechXfTensorResultAccessor::TNH( const caf::Ten3f& t ) const
|
|
{
|
|
return t[caf::Ten3f::SZX];
|
|
}
|
|
float RiuGeoMechXfTensorResultAccessor::TNQV( const caf::Ten3f& t ) const
|
|
{
|
|
return t[caf::Ten3f::SYZ];
|
|
}
|
|
float RiuGeoMechXfTensorResultAccessor::THQV( const caf::Ten3f& t ) const
|
|
{
|
|
return t[caf::Ten3f::SXY];
|
|
}
|
|
|
|
float RiuGeoMechXfTensorResultAccessor::TP( const caf::Ten3f& t ) const
|
|
{
|
|
float szx = t[caf::Ten3f::SZX];
|
|
float szy = t[caf::Ten3f::SYZ];
|
|
float tp = sqrt( szx * szx + szy * szy );
|
|
|
|
return tp;
|
|
}
|
|
|
|
float RiuGeoMechXfTensorResultAccessor::TPinc( const caf::Ten3f& t ) const
|
|
{
|
|
float szy = t[caf::Ten3f::SYZ];
|
|
|
|
float tp = TP( t );
|
|
|
|
if ( tp > 1e-5 )
|
|
{
|
|
return cvf::Math::toDegrees( acos( szy / tp ) );
|
|
}
|
|
else
|
|
{
|
|
return std::numeric_limits<float>::infinity();
|
|
}
|
|
}
|
|
|
|
float RiuGeoMechXfTensorResultAccessor::FAULTMOB( const caf::Ten3f& t ) const
|
|
{
|
|
float szz = t[caf::Ten3f::SZZ];
|
|
float tp = TP( t );
|
|
|
|
return tp / ( m_tanFricAng * ( szz + m_cohPrTanFricAngle ) );
|
|
}
|
|
|
|
float RiuGeoMechXfTensorResultAccessor::PCRIT( const caf::Ten3f& t ) const
|
|
{
|
|
float szz = t[caf::Ten3f::SZZ];
|
|
float tp = TP( t );
|
|
|
|
return szz - tp / m_tanFricAng;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiuGeoMechXfTensorResultAccessor::RiuGeoMechXfTensorResultAccessor( RigFemPartResultsCollection* femResCollection,
|
|
const RigFemResultAddress& resVarAddress,
|
|
int partIdx,
|
|
int timeStepIdx,
|
|
int frameIdx )
|
|
{
|
|
RigFemResultAddress tensComp = resVarAddress;
|
|
tensComp.resultPosType = RIG_ELEMENT_NODAL;
|
|
|
|
tensComp.componentName = "S11";
|
|
tens11 = &femResCollection->resultValues( tensComp, partIdx, timeStepIdx, frameIdx );
|
|
tensComp.componentName = "S22";
|
|
tens22 = &femResCollection->resultValues( tensComp, partIdx, timeStepIdx, frameIdx );
|
|
tensComp.componentName = "S33";
|
|
tens33 = &femResCollection->resultValues( tensComp, partIdx, timeStepIdx, frameIdx );
|
|
tensComp.componentName = "S12";
|
|
tens12 = &femResCollection->resultValues( tensComp, partIdx, timeStepIdx, frameIdx );
|
|
tensComp.componentName = "S23";
|
|
tens23 = &femResCollection->resultValues( tensComp, partIdx, timeStepIdx, frameIdx );
|
|
tensComp.componentName = "S13";
|
|
tens13 = &femResCollection->resultValues( tensComp, partIdx, timeStepIdx, frameIdx );
|
|
|
|
if ( resVarAddress.componentName == "SN" )
|
|
{
|
|
m_tensorOperation = &RiuGeoMechXfTensorResultAccessor::SN;
|
|
}
|
|
if ( resVarAddress.componentName == "STH" )
|
|
{
|
|
m_tensorOperation = &RiuGeoMechXfTensorResultAccessor::STH;
|
|
}
|
|
if ( resVarAddress.componentName == "STQV" )
|
|
{
|
|
m_tensorOperation = &RiuGeoMechXfTensorResultAccessor::STQV;
|
|
}
|
|
if ( resVarAddress.componentName == "TPH" )
|
|
{
|
|
m_tensorOperation = &RiuGeoMechXfTensorResultAccessor::TNH;
|
|
}
|
|
if ( resVarAddress.componentName == "TPQV" )
|
|
{
|
|
m_tensorOperation = &RiuGeoMechXfTensorResultAccessor::TNQV;
|
|
}
|
|
if ( resVarAddress.componentName == "THQV" )
|
|
{
|
|
m_tensorOperation = &RiuGeoMechXfTensorResultAccessor::THQV;
|
|
}
|
|
if ( resVarAddress.componentName == "TP" )
|
|
{
|
|
m_tensorOperation = &RiuGeoMechXfTensorResultAccessor::TP;
|
|
}
|
|
if ( resVarAddress.componentName == "TPinc" )
|
|
{
|
|
m_tensorOperation = &RiuGeoMechXfTensorResultAccessor::TPinc;
|
|
}
|
|
if ( resVarAddress.componentName == "FAULTMOB" )
|
|
{
|
|
m_tensorOperation = &RiuGeoMechXfTensorResultAccessor::FAULTMOB;
|
|
}
|
|
if ( resVarAddress.componentName == "PCRIT" )
|
|
{
|
|
m_tensorOperation = &RiuGeoMechXfTensorResultAccessor::PCRIT;
|
|
}
|
|
|
|
m_tanFricAng = tan( (float)femResCollection->parameterFrictionAngleRad() );
|
|
m_cohPrTanFricAngle = (float)( (float)femResCollection->parameterCohesion() / m_tanFricAng );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RiuGeoMechXfTensorResultAccessor::calculateInterpolatedValue( const cvf::Vec3f triangle[3],
|
|
const RivIntersectionVertexWeights vertexWeights[3],
|
|
float returnValues[3] )
|
|
{
|
|
if ( tens11->empty() )
|
|
{
|
|
returnValues[0] = returnValues[1] = returnValues[2] = std::numeric_limits<float>::infinity();
|
|
return;
|
|
}
|
|
|
|
cvf::Mat3f triangleXf = cvf::GeometryTools::computePlaneHorizontalRotationMx( triangle[1] - triangle[0], triangle[2] - triangle[0] );
|
|
|
|
for ( int triangleVxIdx = 0; triangleVxIdx < 3; ++triangleVxIdx )
|
|
{
|
|
float ipT11 = 0;
|
|
float ipT22 = 0;
|
|
float ipT33 = 0;
|
|
float ipT12 = 0;
|
|
float ipT23 = 0;
|
|
float ipT13 = 0;
|
|
|
|
int weightCount = vertexWeights[triangleVxIdx].size();
|
|
for ( int wIdx = 0; wIdx < weightCount; ++wIdx )
|
|
{
|
|
size_t resIdx = vertexWeights[triangleVxIdx].vxId( wIdx );
|
|
float interpolationWeight = vertexWeights[triangleVxIdx].weight( wIdx );
|
|
ipT11 += ( *tens11 )[resIdx] * interpolationWeight;
|
|
ipT22 += ( *tens22 )[resIdx] * interpolationWeight;
|
|
ipT33 += ( *tens33 )[resIdx] * interpolationWeight;
|
|
ipT12 += ( *tens12 )[resIdx] * interpolationWeight;
|
|
ipT23 += ( *tens23 )[resIdx] * interpolationWeight;
|
|
ipT13 += ( *tens13 )[resIdx] * interpolationWeight;
|
|
}
|
|
|
|
if ( ipT11 == HUGE_VAL || ipT11 != ipT11 || ipT22 == HUGE_VAL || ipT22 != ipT22 || ipT33 == HUGE_VAL || ipT33 != ipT33 ||
|
|
ipT12 == HUGE_VAL || ipT12 != ipT12 || ipT23 == HUGE_VAL || ipT23 != ipT23 || ipT13 == HUGE_VAL ||
|
|
ipT13 != ipT13 ) // a != a is true for NAN's
|
|
{
|
|
returnValues[triangleVxIdx] = std::numeric_limits<float>::infinity();
|
|
}
|
|
else
|
|
{
|
|
caf::Ten3f tensor( ipT11, ipT22, ipT33, ipT12, ipT23, ipT13 );
|
|
caf::Ten3f xfTen = tensor.rotated( triangleXf );
|
|
|
|
returnValues[triangleVxIdx] = m_tensorOperation( *this, xfTen );
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
float RiuGeoMechXfTensorResultAccessor::calculateElmNodeValue( const std::array<cvf::Vec3f, 3>& triangle, int globalElmNodeResIndex )
|
|
{
|
|
if ( tens11->empty() ) return std::numeric_limits<float>::infinity();
|
|
|
|
cvf::Mat3f triangleXf = cvf::GeometryTools::computePlaneHorizontalRotationMx( triangle[1] - triangle[0], triangle[2] - triangle[0] );
|
|
|
|
float ipT11 = ( *tens11 )[globalElmNodeResIndex];
|
|
float ipT22 = ( *tens22 )[globalElmNodeResIndex];
|
|
float ipT33 = ( *tens33 )[globalElmNodeResIndex];
|
|
float ipT12 = ( *tens12 )[globalElmNodeResIndex];
|
|
float ipT23 = ( *tens23 )[globalElmNodeResIndex];
|
|
float ipT13 = ( *tens13 )[globalElmNodeResIndex];
|
|
|
|
if ( ipT11 == HUGE_VAL || ipT11 != ipT11 || ipT22 == HUGE_VAL || ipT22 != ipT22 || ipT33 == HUGE_VAL || ipT33 != ipT33 ||
|
|
ipT12 == HUGE_VAL || ipT12 != ipT12 || ipT23 == HUGE_VAL || ipT23 != ipT23 || ipT13 == HUGE_VAL || ipT13 != ipT13 )
|
|
{
|
|
return std::numeric_limits<float>::infinity();
|
|
}
|
|
else
|
|
{
|
|
caf::Ten3f tensor( ipT11, ipT22, ipT33, ipT12, ipT23, ipT13 );
|
|
caf::Ten3f xfTen = tensor.rotated( triangleXf );
|
|
|
|
float scalarValue = m_tensorOperation( *this, xfTen );
|
|
return scalarValue;
|
|
}
|
|
}
|