Split fem part results collection 5785 (#5871)

* #5785 Extract RigFemClosestResultIndexCalculator class to separate file.

* #5785 Move method implementation of RigFemClosestResutIndexCalculator to cpp file.

Also improve const correctness.

* #5785 Extract method for calculating normal SE, ie. SE:11/22/33.

* #5785 Extract method for calculating shear SE, ie. SE:12/13/23.

* #5785 Create a list of result calculators.

* #5785 Extract method for calculating timelapse, normalized, and gamma results.

* #5785 Extract method for calculating normal ST, ie. ST:11/22/33.

* #5785 Extract method for calculating shear ST, ie. ST:12/13/23.

* #5785 Extract method for calculating surface angles and aligned stress.

* #5785 Extract method for calculating principal strain and stress.

* #5785 Extract method for calculating FOS, SFI and DSM for SE.

* #5785 Extract method for calculating NE.EV, NE.ED, ST.Q and ST.STM.

* #5785 Extract method for calculating compaction.

* #5785 Extract method for calculating stress gradients.

* #5785 Extract method for calculating SE.SEM.

* #5785 Extract method for calculating NE.

* #5785 Extract method for calculating formation indices.

* #5785 Extract method for calculating nodal graidents, bar conversions, and EnIpPorBar.

* #5785 Use std::unique_ptr to calculators.

* Use std::vector<unique_ptr>

Co-authored-by: Magne Sjaastad <magne.sjaastad@ceetronsolutions.com>
This commit is contained in:
Kristian Bendiksen
2020-05-09 08:57:07 +02:00
committed by GitHub
parent 976d343f3b
commit b84e868564
62 changed files with 5207 additions and 2582 deletions

View File

@@ -23,6 +23,8 @@ add_library( ${PROJECT_NAME}
RigFemPartResultsCollection.cpp
RigFemScalarResultFrames.h
RigFemScalarResultFrames.cpp
RigFemClosestResultIndexCalculator.h
RigFemClosestResultIndexCalculator.cpp
RigFemNativeStatCalc.h
RigFemNativeStatCalc.cpp
RigFemNativeVisibleCellsStatCalc.h
@@ -36,6 +38,60 @@ add_library( ${PROJECT_NAME}
RimFemResultObserver.cpp
RigHexGradientTools.h
RigHexGradientTools.cpp
RigFemPartResultCalculator.h
RigFemPartResultCalculator.cpp
RigFemPartResultCalculatorNormalSE.h
RigFemPartResultCalculatorNormalSE.cpp
RigFemPartResultCalculatorShearSE.h
RigFemPartResultCalculatorShearSE.cpp
RigFemPartResultCalculatorNormalST.h
RigFemPartResultCalculatorNormalST.cpp
RigFemPartResultCalculatorShearST.h
RigFemPartResultCalculatorShearST.cpp
RigFemPartResultCalculatorTimeLapse.h
RigFemPartResultCalculatorTimeLapse.cpp
RigFemPartResultCalculatorGamma.h
RigFemPartResultCalculatorGamma.cpp
RigFemPartResultCalculatorNormalized.h
RigFemPartResultCalculatorNormalized.cpp
RigFemPartResultCalculatorSurfaceAngles.h
RigFemPartResultCalculatorSurfaceAngles.cpp
RigFemPartResultCalculatorSurfaceAlignedStress.h
RigFemPartResultCalculatorSurfaceAlignedStress.cpp
RigFemPartResultCalculatorPrincipalStrain.h
RigFemPartResultCalculatorPrincipalStrain.cpp
RigFemPartResultCalculatorPrincipalStress.h
RigFemPartResultCalculatorPrincipalStress.cpp
RigFemPartResultCalculatorSFI.h
RigFemPartResultCalculatorSFI.cpp
RigFemPartResultCalculatorDSM.h
RigFemPartResultCalculatorDSM.cpp
RigFemPartResultCalculatorFOS.h
RigFemPartResultCalculatorFOS.cpp
RigFemPartResultCalculatorED.h
RigFemPartResultCalculatorED.cpp
RigFemPartResultCalculatorEV.h
RigFemPartResultCalculatorEV.cpp
RigFemPartResultCalculatorQ.h
RigFemPartResultCalculatorQ.cpp
RigFemPartResultCalculatorSTM.h
RigFemPartResultCalculatorSTM.cpp
RigFemPartResultCalculatorCompaction.h
RigFemPartResultCalculatorCompaction.cpp
RigFemPartResultCalculatorStressGradients.h
RigFemPartResultCalculatorStressGradients.cpp
RigFemPartResultCalculatorSEM.h
RigFemPartResultCalculatorSEM.cpp
RigFemPartResultCalculatorNE.h
RigFemPartResultCalculatorNE.cpp
RigFemPartResultCalculatorFormationIndices.h
RigFemPartResultCalculatorFormationIndices.cpp
RigFemPartResultCalculatorBarConverted.h
RigFemPartResultCalculatorBarConverted.cpp
RigFemPartResultCalculatorEnIpPorBar.h
RigFemPartResultCalculatorEnIpPorBar.cpp
RigFemPartResultCalculatorNodalGradients.h
RigFemPartResultCalculatorNodalGradients.cpp
RimGeoMechGeometrySelectionItem.h
RimGeoMechGeometrySelectionItem.cpp
)

View File

@@ -0,0 +1,152 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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* elmentConn = femPart->connectivities( elementIndex );
int elmNodeCount = RigFemTypes::elmentNodeCount( elmType );
// Find the closest node
int closestLocalNode = -1;
float minDist = std::numeric_limits<float>::infinity();
for ( int lNodeIdx = 0; lNodeIdx < elmNodeCount; ++lNodeIdx )
{
int nodeIdx = elmentConn[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 = elmentConn[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;
}

View File

@@ -0,0 +1,45 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemResultAddress.h"
#include "cvfVector3.h"
class RigFemPart;
class RigFemClosestResultIndexCalculator
{
public:
RigFemClosestResultIndexCalculator( RigFemPart* femPart,
RigFemResultPosEnum resultPosition,
int elementIndex,
int m_face,
const cvf::Vec3d& intersectionPointInDomain );
int resultIndexToClosestResult() const;
int closestNodeId() const;
int closestElementNodeResIdx() const;
private:
int m_resultIndexToClosestResult;
int m_closestNodeId;
int m_closestElementNodeResIdx;
};

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculator.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
//==================================================================================================
///
//==================================================================================================
RigFemPartResultCalculator::RigFemPartResultCalculator( RigFemPartResultsCollection& collection )
: m_resultCollection( &collection )
{
}
//==================================================================================================
///
//==================================================================================================
RigFemPartResultCalculator::~RigFemPartResultCalculator()
{
}

View File

@@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
class RigFemPartResults;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculator
{
public:
RigFemPartResultCalculator( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculator();
virtual bool isMatching( const RigFemResultAddress& resVarAddr ) const = 0;
virtual RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) = 0;
protected:
RigFemPartResultsCollection* m_resultCollection;
};

View File

@@ -0,0 +1,103 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorBarConverted.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorBarConverted::RigFemPartResultCalculatorBarConverted( RigFemPartResultsCollection& collection,
const std::string& fieldName,
const std::string& fieldNameToConvert )
: RigFemPartResultCalculator( collection )
, m_fieldName( fieldName )
, m_fieldNameToConvert( fieldNameToConvert )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorBarConverted::~RigFemPartResultCalculatorBarConverted()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorBarConverted::isMatching( const RigFemResultAddress& resVarAddr ) const
{
// TODO: split in multiple classes??
if ( m_fieldName == "POR-Bar" )
{
return ( ( resVarAddr.fieldName == "POR-Bar" ) && ( resVarAddr.resultPosType == RIG_NODAL ) &&
!( resVarAddr.componentName == "X" || resVarAddr.componentName == "Y" || resVarAddr.componentName == "Z" ) );
}
else
{
return ( resVarAddr.fieldName == "S-Bar" );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorBarConverted::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 2, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemResultAddress unconvertedResultAddr( resVarAddr.resultPosType, m_fieldNameToConvert, resVarAddr.componentName );
RigFemScalarResultFrames* srcDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex, unconvertedResultAddr );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
int frameCount = srcDataFrames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& srcFrameData = srcDataFrames->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = srcFrameData.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
dstFrameData[vIdx] = 1.0e-5 * srcFrameData[vIdx];
}
frameCountProgress.incrementProgress();
}
m_resultCollection->deleteResult( unconvertedResultAddr );
return dstDataFrames;
}

View File

@@ -0,0 +1,45 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
#include <string>
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorBarConverted : public RigFemPartResultCalculator
{
public:
RigFemPartResultCalculatorBarConverted( RigFemPartResultsCollection& collection,
const std::string& fieldName,
const std::string& fieldNameToConvert );
virtual ~RigFemPartResultCalculatorBarConverted();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
protected:
std::string m_fieldName;
std::string m_fieldNameToConvert;
};

View File

@@ -0,0 +1,250 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorCompaction.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "RigHexIntersectionTools.h"
#include "cafProgressInfo.h"
#include "cvfBoundingBox.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
/// Internal definitions
//--------------------------------------------------------------------------------------------------
class RefElement
{
public:
size_t elementIdx;
float intersectionPointToCurrentNodeDistance;
cvf::Vec3f intersectionPoint;
std::vector<size_t> elementFaceNodeIdxs;
};
static std::vector<cvf::Vec3d> coordsFromNodeIndices( const RigFemPart& part, const std::vector<size_t>& nodeIdxs );
static std::vector<size_t> nodesForElement( const RigFemPart& part, size_t elementIdx );
static float horizontalDistance( const cvf::Vec3f& p1, const cvf::Vec3f& p2 );
static void findReferenceElementForNode( const RigFemPart& part, size_t nodeIdx, size_t kRefLayer, RefElement* refElement );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorCompaction::RigFemPartResultCalculatorCompaction( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorCompaction::~RigFemPartResultCalculatorCompaction()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorCompaction::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.fieldName == RigFemPartResultsCollection::FIELD_NAME_COMPACTION );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorCompaction::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.fieldName == RigFemPartResultsCollection::FIELD_NAME_COMPACTION );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() + 1, "" );
frameCountProgress.setProgressDescription( "Calculating " + QString::fromStdString( resVarAddr.fieldName ) );
RigFemScalarResultFrames* u3Frames =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( resVarAddr.resultPosType, "U", "U3" ) );
frameCountProgress.incrementProgress();
RigFemScalarResultFrames* compactionFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
const RigFemPart* part = m_resultCollection->parts()->part( partIndex );
part->ensureIntersectionSearchTreeIsBuilt();
for ( int t = 0; t < u3Frames->frameCount(); t++ )
{
std::vector<float>& compactionFrame = compactionFrames->frameData( t );
size_t nodeCount = part->nodes().nodeIds.size();
frameCountProgress.incrementProgress();
compactionFrame.resize( nodeCount );
{
// Make sure the AABB-tree is created before using OpenMP
cvf::BoundingBox bb;
std::vector<size_t> refElementCandidates;
part->findIntersectingCells( bb, &refElementCandidates );
// Also make sure the struct grid is created, as this is required before using OpenMP
part->getOrCreateStructGrid();
}
#pragma omp parallel for
for ( long n = 0; n < static_cast<long>( nodeCount ); n++ )
{
RefElement refElement;
findReferenceElementForNode( *part, n, resVarAddr.refKLayerIndex, &refElement );
if ( refElement.elementIdx != cvf::UNDEFINED_SIZE_T )
{
float shortestDist = std::numeric_limits<float>::infinity();
size_t closestRefNodeIdx = cvf::UNDEFINED_SIZE_T;
for ( size_t nodeIdx : refElement.elementFaceNodeIdxs )
{
float dist = horizontalDistance( refElement.intersectionPoint, part->nodes().coordinates[nodeIdx] );
if ( dist < shortestDist )
{
shortestDist = dist;
closestRefNodeIdx = nodeIdx;
}
}
cvf::Vec3f currentNodeCoord = part->nodes().coordinates[n];
if ( currentNodeCoord.z() >= refElement.intersectionPoint.z() )
compactionFrame[n] = -( u3Frames->frameData( t )[n] - u3Frames->frameData( t )[closestRefNodeIdx] );
else
compactionFrame[n] = -( u3Frames->frameData( t )[closestRefNodeIdx] - u3Frames->frameData( t )[n] );
}
else
{
compactionFrame[n] = HUGE_VAL;
}
}
}
RigFemScalarResultFrames* requestedPrincipal = m_resultCollection->findOrLoadScalarResult( partIndex, resVarAddr );
return requestedPrincipal;
}
//--------------------------------------------------------------------------------------------------
/// Internal functions
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void findReferenceElementForNode( const RigFemPart& part, size_t nodeIdx, size_t kRefLayer, RefElement* refElement )
{
static const double zMin = -1e6, zMax = 1e6;
cvf::BoundingBox bb;
cvf::Vec3f currentNodeCoord = part.nodes().coordinates[nodeIdx];
cvf::Vec3f p1 = cvf::Vec3f( currentNodeCoord.x(), currentNodeCoord.y(), zMin );
cvf::Vec3f p2 = cvf::Vec3f( currentNodeCoord.x(), currentNodeCoord.y(), zMax );
bb.add( p1 );
bb.add( p2 );
std::vector<size_t> refElementCandidates;
part.findIntersectingCells( bb, &refElementCandidates );
const RigFemPartGrid* grid = part.getOrCreateStructGrid();
refElement->elementIdx = cvf::UNDEFINED_SIZE_T;
refElement->intersectionPointToCurrentNodeDistance = std::numeric_limits<float>::infinity();
size_t i, j, k;
for ( const size_t elemIdx : refElementCandidates )
{
bool validIndex = grid->ijkFromCellIndex( elemIdx, &i, &j, &k );
if ( validIndex && k == kRefLayer )
{
const std::vector<size_t> nodeIndices = nodesForElement( part, elemIdx );
CVF_ASSERT( nodeIndices.size() == 8 );
std::vector<HexIntersectionInfo> intersections;
RigHexIntersectionTools::lineHexCellIntersection( cvf::Vec3d( p1 ),
cvf::Vec3d( p2 ),
coordsFromNodeIndices( part, nodeIndices ).data(),
elemIdx,
&intersections );
for ( const auto& intersection : intersections )
{
cvf::Vec3f intersectionPoint = cvf::Vec3f( intersection.m_intersectionPoint );
float nodeToIntersectionDistance = currentNodeCoord.pointDistance( intersectionPoint );
if ( nodeToIntersectionDistance < refElement->intersectionPointToCurrentNodeDistance )
{
cvf::ubyte faceNodes[4];
grid->cellFaceVertexIndices( intersection.m_face, faceNodes );
std::vector<size_t> topFaceCoords( {nodeIndices[faceNodes[0]],
nodeIndices[faceNodes[1]],
nodeIndices[faceNodes[2]],
nodeIndices[faceNodes[3]]} );
refElement->elementIdx = elemIdx;
refElement->intersectionPointToCurrentNodeDistance = nodeToIntersectionDistance;
refElement->intersectionPoint = intersectionPoint;
refElement->elementFaceNodeIdxs = topFaceCoords;
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> coordsFromNodeIndices( const RigFemPart& part, const std::vector<size_t>& nodeIdxs )
{
std::vector<cvf::Vec3d> out;
for ( const auto& nodeIdx : nodeIdxs )
out.push_back( cvf::Vec3d( part.nodes().coordinates[nodeIdx] ) );
return out;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> nodesForElement( const RigFemPart& part, size_t elementIdx )
{
std::vector<size_t> nodeIdxs;
const int* nodeConn = part.connectivities( elementIdx );
for ( int n = 0; n < 8; n++ )
nodeIdxs.push_back( nodeConn[n] );
return nodeIdxs;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float horizontalDistance( const cvf::Vec3f& p1, const cvf::Vec3f& p2 )
{
cvf::Vec3f p1_ = p1;
cvf::Vec3f p2_ = p2;
p1_.z() = p2_.z() = 0;
return p1_.pointDistance( p2_ );
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorCompaction : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorCompaction( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorCompaction();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,117 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorDSM.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorDSM::RigFemPartResultCalculatorDSM( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorDSM::~RigFemPartResultCalculatorDSM()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorDSM::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.fieldName == "SE" && resVarAddr.componentName == "DSM" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorDSM::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.fieldName == "SE" && resVarAddr.componentName == "DSM" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 3, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* se1Frames =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( resVarAddr.resultPosType, "SE", "S1" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* se3Frames =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( resVarAddr.resultPosType, "SE", "S3" ) );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
float tanFricAng = tan( m_resultCollection->parameterFrictionAngleRad() );
float cohPrTanFricAngle = (float)( m_resultCollection->parameterCohesion() / tanFricAng );
int frameCount = se1Frames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& se1Data = se1Frames->frameData( fIdx );
const std::vector<float>& se3Data = se3Frames->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = se1Data.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
dstFrameData[vIdx] = dsm( se1Data[vIdx], se3Data[vIdx], tanFricAng, cohPrTanFricAngle );
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float RigFemPartResultCalculatorDSM::dsm( float p1, float p3, float tanFricAng, float cohPrTanFricAngle )
{
if ( p1 == HUGE_VAL || p3 == HUGE_VAL )
{
return std::nan( "" );
}
CVF_ASSERT( p1 > p3 );
float pi_4 = 0.785398163397448309616f;
float rho = 2.0f * ( atan( sqrt( ( p1 + cohPrTanFricAngle ) / ( p3 + cohPrTanFricAngle ) ) ) - pi_4 );
return tan( rho ) / tanFricAng;
}

View File

@@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorDSM : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorDSM( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorDSM();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
static float dsm( float p1, float p3, float tanFricAng, float cohPrTanFricAngle );
};

View File

@@ -0,0 +1,101 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorED.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorED::RigFemPartResultCalculatorED( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorED::~RigFemPartResultCalculatorED()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorED::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.fieldName == "NE" && resVarAddr.componentName == "ED" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorED::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.fieldName == "NE" && resVarAddr.componentName == "ED" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 3, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* ea11 = nullptr;
RigFemScalarResultFrames* ea33 = nullptr;
{
ea11 = m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "NE", "E1" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
ea33 = m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "NE", "E3" ) );
}
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
int frameCount = ea11->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& ea11Data = ea11->frameData( fIdx );
const std::vector<float>& ea33Data = ea33->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = ea11Data.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
dstFrameData[vIdx] = 0.666666666666667f * ( ea11Data[vIdx] - ea33Data[vIdx] );
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorED : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorED( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorED();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,108 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorEV.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorEV::RigFemPartResultCalculatorEV( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorEV::~RigFemPartResultCalculatorEV()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorEV::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.fieldName == "NE" && resVarAddr.componentName == "EV" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorEV::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.fieldName == "NE" && resVarAddr.componentName == "EV" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 4, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* ea11 = nullptr;
RigFemScalarResultFrames* ea22 = nullptr;
RigFemScalarResultFrames* ea33 = nullptr;
{
ea11 = m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "NE", "E11" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
ea22 = m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "NE", "E22" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
ea33 = m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "NE", "E33" ) );
}
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
int frameCount = ea11->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& ea11Data = ea11->frameData( fIdx );
const std::vector<float>& ea22Data = ea22->frameData( fIdx );
const std::vector<float>& ea33Data = ea33->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = ea11Data.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
dstFrameData[vIdx] = ( ea11Data[vIdx] + ea22Data[vIdx] + ea33Data[vIdx] );
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorEV : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorEV( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorEV();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,110 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorEnIpPorBar.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorEnIpPorBar::RigFemPartResultCalculatorEnIpPorBar( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorEnIpPorBar::~RigFemPartResultCalculatorEnIpPorBar()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorEnIpPorBar::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.fieldName == "POR-Bar" && resVarAddr.resultPosType != RIG_NODAL );
}
//--------------------------------------------------------------------------------------------------
/// Convert POR NODAL result to POR-Bar Elment Nodal result
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorEnIpPorBar::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 2, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemResultAddress unconvertedResultAddr( RIG_NODAL, "POR", "" );
RigFemScalarResultFrames* srcDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex, unconvertedResultAddr );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
const RigFemPart* femPart = m_resultCollection->parts()->part( partIndex );
float inf = std::numeric_limits<float>::infinity();
int frameCount = srcDataFrames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& srcFrameData = srcDataFrames->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
if ( srcFrameData.empty() ) continue; // Create empty results if we have no POR result.
size_t valCount = femPart->elementNodeResultCount();
dstFrameData.resize( valCount, inf );
int elementCount = femPart->elementCount();
#pragma omp parallel for schedule( dynamic )
for ( int elmIdx = 0; elmIdx < elementCount; ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
if ( elmType == HEX8P )
{
int elmNodeCount = RigFemTypes::elmentNodeCount( elmType );
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx( elmNodResIdx );
dstFrameData[elmNodResIdx] = 1.0e-5 * srcFrameData[nodeIdx];
}
}
}
frameCountProgress.incrementProgress();
}
m_resultCollection->deleteResult( unconvertedResultAddr );
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorEnIpPorBar : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorEnIpPorBar( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorEnIpPorBar();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,94 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorFOS.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorFOS::RigFemPartResultCalculatorFOS( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorFOS::~RigFemPartResultCalculatorFOS()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorFOS::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.fieldName == "SE" && resVarAddr.componentName == "FOS" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorFOS::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.fieldName == "SE" && resVarAddr.componentName == "FOS" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 2, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* dsmFrames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "SE", "DSM" ) );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
int frameCount = dsmFrames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& dsmData = dsmFrames->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = dsmData.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
float dsm = dsmData[vIdx];
dstFrameData[vIdx] = 1.0f / dsm;
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorFOS : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorFOS( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorFOS();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,117 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorFormationIndices.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "RigFormationNames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorFormationIndices::RigFemPartResultCalculatorFormationIndices( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorFormationIndices::~RigFemPartResultCalculatorFormationIndices()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorFormationIndices::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.resultPosType == RIG_FORMATION_NAMES );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorFormationIndices::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
caf::ProgressInfo frameCountProgress( 2, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
RigFemScalarResultFrames* resFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
resFrames->enableAsSingleFrameResult();
const RigFemPart* femPart = m_resultCollection->parts()->part( partIndex );
std::vector<float>& dstFrameData = resFrames->frameData( 0 );
size_t valCount = femPart->elementNodeResultCount();
float inf = std::numeric_limits<float>::infinity();
dstFrameData.resize( valCount, inf );
const RigFormationNames* activeFormNames = m_resultCollection->activeFormationNames();
frameCountProgress.incrementProgress();
if ( activeFormNames )
{
// Has to be done before the parallel loop because the first call allocates.
const RigFemPartGrid* structGrid = femPart->getOrCreateStructGrid();
int elementCount = femPart->elementCount();
#pragma omp parallel for
for ( int elmIdx = 0; elmIdx < elementCount; ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
int elmNodeCount = RigFemTypes::elmentNodeCount( elmType );
size_t i, j, k;
bool validIndex = structGrid->ijkFromCellIndex( elmIdx, &i, &j, &k );
if ( validIndex )
{
int formNameIdx = activeFormNames->formationIndexFromKLayerIdx( k );
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
if ( formNameIdx != -1 )
{
dstFrameData[elmNodResIdx] = formNameIdx;
}
else
{
dstFrameData[elmNodResIdx] = HUGE_VAL;
}
}
}
}
}
return resFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorFormationIndices : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorFormationIndices( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorFormationIndices();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,173 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorGamma.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorGamma::RigFemPartResultCalculatorGamma( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorGamma::~RigFemPartResultCalculatorGamma()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorGamma::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.fieldName == "Gamma" &&
( resVarAddr.componentName == "Gamma1" || resVarAddr.componentName == "Gamma2" ||
resVarAddr.componentName == "Gamma3" || resVarAddr.componentName == "Gamma11" ||
resVarAddr.componentName == "Gamma22" || resVarAddr.componentName == "Gamma33" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorGamma::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 3, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemResultAddress totStressCompAddr( resVarAddr.resultPosType, "ST", "" );
{
std::string scomp;
std::string gcomp = resVarAddr.componentName;
if ( gcomp == "Gamma1" )
scomp = "S1";
else if ( gcomp == "Gamma2" )
scomp = "S2";
else if ( gcomp == "Gamma3" )
scomp = "S3";
else if ( gcomp == "Gamma11" )
scomp = "S11";
else if ( gcomp == "Gamma22" )
scomp = "S22";
else if ( gcomp == "Gamma33" )
scomp = "S33";
totStressCompAddr.componentName = scomp;
}
RigFemScalarResultFrames* srcDataFrames = m_resultCollection->findOrLoadScalarResult( partIndex, totStressCompAddr );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* srcPORDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( RIG_NODAL, "POR-Bar", "" ) );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
calculateGammaFromFrames( partIndex,
m_resultCollection->parts(),
srcDataFrames,
srcPORDataFrames,
dstDataFrames,
&frameCountProgress );
return dstDataFrames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFemPartResultCalculatorGamma::calculateGammaFromFrames( int partIndex,
const RigFemPartCollection* femParts,
const RigFemScalarResultFrames* totalStressComponentDataFrames,
const RigFemScalarResultFrames* srcPORDataFrames,
RigFemScalarResultFrames* dstDataFrames,
caf::ProgressInfo* frameCountProgress )
{
const RigFemPart* femPart = femParts->part( partIndex );
int frameCount = totalStressComponentDataFrames->frameCount();
float inf = std::numeric_limits<float>::infinity();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& srcSTFrameData = totalStressComponentDataFrames->frameData( fIdx );
const std::vector<float>& srcPORFrameData = srcPORDataFrames->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = srcSTFrameData.size();
dstFrameData.resize( valCount );
int elementCount = femPart->elementCount();
#pragma omp parallel for
for ( int elmIdx = 0; elmIdx < elementCount; ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
int elmNodeCount = RigFemTypes::elmentNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
if ( elmNodResIdx < srcSTFrameData.size() )
{
int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx( elmNodResIdx );
float por = srcPORFrameData[nodeIdx];
if ( por == inf || fabs( por ) < 0.01e6 * 1.0e-5 )
dstFrameData[elmNodResIdx] = inf;
else
dstFrameData[elmNodResIdx] = srcSTFrameData[elmNodResIdx] / por;
}
}
}
else
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
if ( elmNodResIdx < dstFrameData.size() )
{
dstFrameData[elmNodResIdx] = inf;
}
}
}
}
frameCountProgress->incrementProgress();
}
}

View File

@@ -0,0 +1,50 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemPartCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
namespace caf
{
class ProgressInfo;
};
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorGamma : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorGamma( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorGamma();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
static void calculateGammaFromFrames( int partIndex,
const RigFemPartCollection* femParts,
const RigFemScalarResultFrames* totalStressComponentDataFrames,
const RigFemScalarResultFrames* srcPORDataFrames,
RigFemScalarResultFrames* dstDataFrames,
caf::ProgressInfo* frameCountProgress );
};

View File

@@ -0,0 +1,94 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorNE.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorNE::RigFemPartResultCalculatorNE( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorNE::~RigFemPartResultCalculatorNE()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorNE::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( ( resVarAddr.fieldName == "NE" ) &&
( resVarAddr.componentName == "E11" || resVarAddr.componentName == "E22" ||
resVarAddr.componentName == "E33" || resVarAddr.componentName == "E12" ||
resVarAddr.componentName == "E13" || resVarAddr.componentName == "E23" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorNE::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 2, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* srcDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
"E",
resVarAddr.componentName ) );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
int frameCount = srcDataFrames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& srcFrameData = srcDataFrames->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = srcFrameData.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
dstFrameData[vIdx] = -srcFrameData[vIdx];
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorNE : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorNE( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorNE();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,175 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorNodalGradients.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "RigHexGradientTools.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorNodalGradients::RigFemPartResultCalculatorNodalGradients( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorNodalGradients::~RigFemPartResultCalculatorNodalGradients()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorNodalGradients::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( ( resVarAddr.fieldName == "POR-Bar" ) && ( resVarAddr.resultPosType == RIG_NODAL ) &&
( resVarAddr.componentName == "X" || resVarAddr.componentName == "Y" || resVarAddr.componentName == "Z" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorNodalGradients::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.fieldName == "POR-Bar" );
CVF_ASSERT( resVarAddr.componentName == "X" || resVarAddr.componentName == "Y" || resVarAddr.componentName == "Z" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 5, "" );
frameCountProgress.setProgressDescription(
"Calculating gradient: " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* dataFramesX =
m_resultCollection->createScalarResult( partIndex, RigFemResultAddress( RIG_NODAL, resVarAddr.fieldName, "X" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* dataFramesY =
m_resultCollection->createScalarResult( partIndex, RigFemResultAddress( RIG_NODAL, resVarAddr.fieldName, "Y" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* dataFramesZ =
m_resultCollection->createScalarResult( partIndex, RigFemResultAddress( RIG_NODAL, resVarAddr.fieldName, "Z" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemResultAddress porResultAddr( RIG_NODAL, "POR-Bar", "" );
RigFemScalarResultFrames* srcDataFrames = m_resultCollection->findOrLoadScalarResult( partIndex, porResultAddr );
frameCountProgress.incrementProgress();
const RigFemPart* femPart = m_resultCollection->parts()->part( partIndex );
float inf = std::numeric_limits<float>::infinity();
const std::vector<cvf::Vec3f>& nodeCoords = femPart->nodes().coordinates;
size_t nodeCount = femPart->nodes().nodeIds.size();
int frameCount = srcDataFrames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& srcFrameData = srcDataFrames->frameData( fIdx );
std::vector<float>& dstFrameDataX = dataFramesX->frameData( fIdx );
std::vector<float>& dstFrameDataY = dataFramesY->frameData( fIdx );
std::vector<float>& dstFrameDataZ = dataFramesZ->frameData( fIdx );
if ( srcFrameData.empty() ) continue; // Create empty results if we have no POR result.
size_t valCount = femPart->elementNodeResultCount();
dstFrameDataX.resize( valCount, inf );
dstFrameDataY.resize( valCount, inf );
dstFrameDataZ.resize( valCount, inf );
int elementCount = femPart->elementCount();
#pragma omp parallel for schedule( dynamic )
for ( long nodeIdx = 0; nodeIdx < static_cast<long>( nodeCount ); nodeIdx++ )
{
const std::vector<int> elements = femPart->elementsUsingNode( nodeIdx );
// Compute the average of the elements contributing to this node
cvf::Vec3d result = cvf::Vec3d::ZERO;
int nValidElements = 0;
for ( int elmIdx : elements )
{
RigElementType elmType = femPart->elementType( elmIdx );
if ( elmType == HEX8P )
{
// Find the corner coordinates and values for the node
std::array<cvf::Vec3d, 8> hexCorners;
std::array<double, 8> cornerValues;
int elmNodeCount = RigFemTypes::elmentNodeCount( elmType );
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
size_t resultValueIdx = femPart->resultValueIdxFromResultPosType( RIG_NODAL, elmIdx, elmNodIdx );
cornerValues[elmNodIdx] = srcFrameData[resultValueIdx];
hexCorners[elmNodIdx] = cvf::Vec3d( nodeCoords[resultValueIdx] );
}
std::array<cvf::Vec3d, 8> gradients = RigHexGradientTools::gradients( hexCorners, cornerValues );
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
size_t resultValueIdx = femPart->resultValueIdxFromResultPosType( RIG_NODAL, elmIdx, elmNodIdx );
// Only use the gradient for particular corner corresponding to the node
if ( static_cast<size_t>( nodeIdx ) == resultValueIdx )
{
result.add( gradients[elmNodIdx] );
}
}
nValidElements++;
}
}
if ( nValidElements > 0 )
{
// Round very small values to zero to avoid ugly coloring when gradients
// are dominated by floating point math artifacts.
double epsilon = 1.0e-6;
result /= static_cast<double>( nValidElements );
dstFrameDataX[nodeIdx] = std::abs( result.x() ) > epsilon ? result.x() : 0.0;
dstFrameDataY[nodeIdx] = std::abs( result.y() ) > epsilon ? result.y() : 0.0;
dstFrameDataZ[nodeIdx] = std::abs( result.z() ) > epsilon ? result.z() : 0.0;
}
}
frameCountProgress.incrementProgress();
}
RigFemScalarResultFrames* requestedGradient = m_resultCollection->findOrLoadScalarResult( partIndex, resVarAddr );
CVF_ASSERT( requestedGradient );
return requestedGradient;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorNodalGradients : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorNodalGradients( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorNodalGradients();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,183 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorNormalSE.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorNormalSE::RigFemPartResultCalculatorNormalSE( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorNormalSE::~RigFemPartResultCalculatorNormalSE()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorNormalSE::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( ( resVarAddr.fieldName == "SE" ) && ( resVarAddr.componentName == "S11" || resVarAddr.componentName == "S22" ||
resVarAddr.componentName == "S33" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorNormalSE::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 3, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* srcDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
"S-Bar",
resVarAddr.componentName ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* srcPORDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( RIG_NODAL, "POR-Bar", "" ) );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
// Biot porelastic coeffisient (alpha)
RigFemScalarResultFrames* biotCoefficient = nullptr;
if ( !m_resultCollection->biotResultAddress().isEmpty() )
{
biotCoefficient =
m_resultCollection
->findOrLoadScalarResult( partIndex,
RigFemResultAddress( RIG_ELEMENT,
m_resultCollection->biotResultAddress().toStdString(),
"" ) );
}
const RigFemPart* femPart = m_resultCollection->parts()->part( partIndex );
float inf = std::numeric_limits<float>::infinity();
int frameCount = srcDataFrames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& srcSFrameData = srcDataFrames->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = srcSFrameData.size();
dstFrameData.resize( valCount );
const std::vector<float>& initialPORFrameData = srcPORDataFrames->frameData( 0 );
int elementCount = femPart->elementCount();
std::vector<float> biotData;
if ( biotCoefficient )
{
biotData = biotCoefficient->frameData( fIdx );
if ( !m_resultCollection->isValidBiotData( biotData, elementCount ) )
{
m_resultCollection->deleteResult( resVarAddr );
return nullptr;
}
}
#pragma omp parallel for
for ( int elmIdx = 0; elmIdx < elementCount; ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
int elmNodeCount = RigFemTypes::elmentNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
if ( elmNodResIdx < srcSFrameData.size() )
{
double SE_abacus = -srcSFrameData[elmNodResIdx];
if ( fIdx == 0 )
{
// Geostatic step: biot coefficient == 1.0
dstFrameData[elmNodResIdx] = SE_abacus;
}
else
{
// Use biot coefficient for all other (not Geostatic) timesteps
double biotCoefficient = 1.0;
if ( biotData.empty() )
{
biotCoefficient = m_resultCollection->biotFixedFactor();
}
else
{
// Use coefficient from element property table
biotCoefficient = biotData[elmIdx];
}
// SE = St - alpha * porePressure - (1 - alpha) * initialPorePressure
// ST = SE_abaqus + alpha * porePressure
// Can be simplified:
// SE = SE_abaqus - (1-alpha) * initialPorePressure
// SE_abaqus is called S-Bar
int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx( elmNodResIdx );
double initialPorePressure = initialPORFrameData[nodeIdx];
if ( initialPorePressure == inf ) initialPorePressure = 0.0f;
dstFrameData[elmNodResIdx] = SE_abacus - ( 1.0 - biotCoefficient ) * initialPorePressure;
}
}
}
}
else
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
if ( elmNodResIdx < dstFrameData.size() )
{
dstFrameData[elmNodResIdx] = inf;
}
}
}
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorNormalSE : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorNormalSE( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorNormalSE();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,184 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorNormalST.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorNormalST::RigFemPartResultCalculatorNormalST( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorNormalST::~RigFemPartResultCalculatorNormalST()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorNormalST::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( ( resVarAddr.fieldName == "ST" ) && ( resVarAddr.componentName == "S11" || resVarAddr.componentName == "S22" ||
resVarAddr.componentName == "S33" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorNormalST::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 3, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* srcSDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
"S-Bar",
resVarAddr.componentName ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* srcPORDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( RIG_NODAL, "POR-Bar", "" ) );
// Biot porelastic coeffisient (alpha)
RigFemScalarResultFrames* biotCoefficient = nullptr;
if ( !m_resultCollection->biotResultAddress().isEmpty() )
{
biotCoefficient =
m_resultCollection
->findOrLoadScalarResult( partIndex,
RigFemResultAddress( RIG_ELEMENT,
m_resultCollection->biotResultAddress().toStdString(),
"" ) );
}
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
const RigFemPart* femPart = m_resultCollection->parts()->part( partIndex );
int frameCount = srcSDataFrames->frameCount();
frameCountProgress.incrementProgress();
const float inf = std::numeric_limits<float>::infinity();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& srcSFrameData = srcSDataFrames->frameData( fIdx );
const std::vector<float>& srcPORFrameData = srcPORDataFrames->frameData( fIdx );
int elementCount = femPart->elementCount();
std::vector<float> biotData;
if ( biotCoefficient )
{
biotData = biotCoefficient->frameData( fIdx );
if ( !m_resultCollection->isValidBiotData( biotData, elementCount ) )
{
m_resultCollection->deleteResult( resVarAddr );
return nullptr;
}
}
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = srcSFrameData.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( int elmIdx = 0; elmIdx < elementCount; ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
int elmNodeCount = RigFemTypes::elmentNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
if ( elmNodResIdx < srcSFrameData.size() )
{
int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx( elmNodResIdx );
float por = srcPORFrameData[nodeIdx];
if ( por == inf ) por = 0.0f;
// ST = SE_abacus + alpha * porePressure
// where alpha is biot coefficient, and porePressure is POR-Bar.
double SE_abacus = -srcSFrameData[elmNodResIdx];
if ( fIdx == 0 )
{
// Geostatic step: biot coefficient == 1.0
dstFrameData[elmNodResIdx] = SE_abacus + por;
}
else
{
// Use biot coefficient for all other (not Geostatic) timesteps
double biotCoefficient = 1.0;
if ( biotData.empty() )
{
biotCoefficient = m_resultCollection->biotFixedFactor();
}
else
{
// Use coefficient from element property table
biotCoefficient = biotData[elmIdx];
}
dstFrameData[elmNodResIdx] = SE_abacus + biotCoefficient * por;
}
}
}
}
else
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
if ( elmNodResIdx < srcSFrameData.size() )
{
dstFrameData[elmNodResIdx] = -srcSFrameData[elmNodResIdx];
}
}
}
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorNormalST : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorNormalST( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorNormalST();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,166 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorNormalized.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "RiaWellLogUnitTools.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorNormalized::RigFemPartResultCalculatorNormalized( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorNormalized::~RigFemPartResultCalculatorNormalized()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorNormalized::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.normalizeByHydrostaticPressure() &&
RigFemPartResultsCollection::isNormalizableResult( resVarAddr ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorNormalized::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.normalizeByHydrostaticPressure() && isNormalizableResult( resVarAddr ) );
RigFemResultAddress unscaledResult = resVarAddr;
if ( unscaledResult.resultPosType == RIG_NODAL && unscaledResult.fieldName == "POR-Bar" )
unscaledResult.resultPosType = RIG_ELEMENT_NODAL;
unscaledResult.normalizedByHydrostaticPressure = false;
CAF_ASSERT( unscaledResult.resultPosType == RIG_ELEMENT_NODAL );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 4, "Calculating Normalized Result" );
RigFemScalarResultFrames* porDataFrames = nullptr;
RigFemScalarResultFrames* srcDataFrames = nullptr;
RigFemScalarResultFrames* dstDataFrames = nullptr;
{
auto task = frameCountProgress.task( "Loading POR Result", m_resultCollection->frameCount() );
porDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( RIG_ELEMENT_NODAL, "POR-Bar", "" ) );
if ( !porDataFrames ) return nullptr;
}
{
auto task = frameCountProgress.task( "Loading Unscaled Result", m_resultCollection->frameCount() );
srcDataFrames = m_resultCollection->findOrLoadScalarResult( partIndex, unscaledResult );
if ( !srcDataFrames ) return nullptr;
}
{
auto task = frameCountProgress.task( "Creating Space for Normalized Result", m_resultCollection->frameCount() );
dstDataFrames = m_resultCollection->createScalarResult( partIndex, RigFemResultAddress( resVarAddr ) );
if ( !dstDataFrames ) return nullptr;
}
frameCountProgress.setProgressDescription( "Normalizing Result" );
frameCountProgress.setNextProgressIncrement( 1u );
const RigFemPart* femPart = m_resultCollection->parts()->part( partIndex );
const RigFemPartGrid* femPartGrid = femPart->getOrCreateStructGrid();
float inf = std::numeric_limits<float>::infinity();
int elmNodeCount = femPart->elementCount();
const std::vector<cvf::Vec3f>& nodeCoords = femPart->nodes().coordinates;
int frameCount = srcDataFrames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& porFrameData = porDataFrames->frameData( fIdx );
const std::vector<float>& srcFrameData = srcDataFrames->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t resultCount = srcFrameData.size();
dstFrameData.resize( resultCount );
if ( unscaledResult.resultPosType == RIG_ELEMENT_NODAL )
{
#pragma omp parallel for schedule( dynamic )
for ( int elmIdx = 0; elmIdx < femPart->elementCount(); ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
if ( !( elmType == HEX8 || elmType == HEX8P ) ) continue;
bool porRegion = false;
for ( int elmLocalNodeIdx = 0; elmLocalNodeIdx < 8; ++elmLocalNodeIdx )
{
size_t elmNodeResIdx = femPart->elementNodeResultIdx( elmIdx, elmLocalNodeIdx );
const int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx( elmNodeResIdx );
dstFrameData[elmNodeResIdx] = srcFrameData[elmNodeResIdx];
if ( porFrameData[elmNodeResIdx] != std::numeric_limits<float>::infinity() )
{
porRegion = true;
}
}
if ( porRegion )
{
// This is in the POR-region. Use hydrostatic pressure from the individual nodes
for ( int elmLocalNodeIdx = 0; elmLocalNodeIdx < 8; ++elmLocalNodeIdx )
{
size_t elmNodeResIdx = femPart->elementNodeResultIdx( elmIdx, elmLocalNodeIdx );
const int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx( elmNodeResIdx );
double tvdRKB = std::abs( nodeCoords[nodeIdx].z() ) + m_resultCollection->normalizationAirGap();
double hydrostaticPressure = RiaWellLogUnitTools<double>::hydrostaticPorePressureBar( tvdRKB );
dstFrameData[elmNodeResIdx] /= hydrostaticPressure;
}
}
else
{
// Over/under/sideburden. Use hydrostatic pressure from cell centroid.
cvf::Vec3d cellCentroid = femPartGrid->cellCentroid( elmIdx );
double cellCentroidTvdRKB = std::abs( cellCentroid.z() ) + m_resultCollection->normalizationAirGap();
double cellCenterHydroStaticPressure =
RiaWellLogUnitTools<double>::hydrostaticPorePressureBar( cellCentroidTvdRKB );
for ( int elmLocalNodeIdx = 0; elmLocalNodeIdx < 8; ++elmLocalNodeIdx )
{
size_t elmNodeResIdx = femPart->elementNodeResultIdx( elmIdx, elmLocalNodeIdx );
dstFrameData[elmNodeResIdx] /= cellCenterHydroStaticPressure;
}
}
}
}
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorNormalized : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorNormalized( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorNormalized();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,158 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorPrincipalStrain.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorPrincipalStrain::RigFemPartResultCalculatorPrincipalStrain( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorPrincipalStrain::~RigFemPartResultCalculatorPrincipalStrain()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorPrincipalStrain::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( ( resVarAddr.fieldName == "NE" ) && ( resVarAddr.componentName == "E1" || resVarAddr.componentName == "E2" ||
resVarAddr.componentName == "E3" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorPrincipalStrain::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.componentName == "E1" || resVarAddr.componentName == "E2" || resVarAddr.componentName == "E3" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 7, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s11Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"E11" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s22Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"E22" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s33Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"E33" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s12Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"E12" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s13Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"E13" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s23Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"E23" ) );
RigFemScalarResultFrames* s1Frames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "E1" ) );
RigFemScalarResultFrames* s2Frames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "E2" ) );
RigFemScalarResultFrames* s3Frames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "E3" ) );
frameCountProgress.incrementProgress();
int frameCount = s11Frames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& s11 = s11Frames->frameData( fIdx );
const std::vector<float>& s22 = s22Frames->frameData( fIdx );
const std::vector<float>& s33 = s33Frames->frameData( fIdx );
const std::vector<float>& s12 = s12Frames->frameData( fIdx );
const std::vector<float>& s13 = s13Frames->frameData( fIdx );
const std::vector<float>& s23 = s23Frames->frameData( fIdx );
std::vector<float>& s1 = s1Frames->frameData( fIdx );
std::vector<float>& s2 = s2Frames->frameData( fIdx );
std::vector<float>& s3 = s3Frames->frameData( fIdx );
size_t valCount = s11.size();
s1.resize( valCount );
s2.resize( valCount );
s3.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
caf::Ten3f T( s11[vIdx], s22[vIdx], s33[vIdx], s12[vIdx], s23[vIdx], s13[vIdx] );
cvf::Vec3f principalDirs[3];
cvf::Vec3f principals = T.calculatePrincipals( principalDirs );
s1[vIdx] = principals[0];
s2[vIdx] = principals[1];
s3[vIdx] = principals[2];
}
frameCountProgress.incrementProgress();
}
RigFemScalarResultFrames* requestedPrincipal = m_resultCollection->findOrLoadScalarResult( partIndex, resVarAddr );
return requestedPrincipal;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorPrincipalStrain : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorPrincipalStrain( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorPrincipalStrain();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,234 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorPrincipalStress.h"
#include "RiaOffshoreSphericalCoords.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorPrincipalStress::RigFemPartResultCalculatorPrincipalStress( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorPrincipalStress::~RigFemPartResultCalculatorPrincipalStress()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorPrincipalStress::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( ( resVarAddr.fieldName == "SE" || resVarAddr.fieldName == "ST" ) &&
( resVarAddr.componentName == "S1" || resVarAddr.componentName == "S2" || resVarAddr.componentName == "S3" ||
resVarAddr.componentName == "S1inc" || resVarAddr.componentName == "S1azi" ||
resVarAddr.componentName == "S2inc" || resVarAddr.componentName == "S2azi" ||
resVarAddr.componentName == "S3inc" || resVarAddr.componentName == "S3azi" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorPrincipalStress::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.componentName == "S1" || resVarAddr.componentName == "S2" || resVarAddr.componentName == "S3" ||
resVarAddr.componentName == "S1inc" || resVarAddr.componentName == "S1azi" ||
resVarAddr.componentName == "S2inc" || resVarAddr.componentName == "S2azi" ||
resVarAddr.componentName == "S3inc" || resVarAddr.componentName == "S3azi" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 7, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s11Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"S11" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s22Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"S22" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s33Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"S33" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s12Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"S12" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s13Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"S13" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s23Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"S23" ) );
RigFemScalarResultFrames* s1Frames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "S1" ) );
RigFemScalarResultFrames* s2Frames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "S2" ) );
RigFemScalarResultFrames* s3Frames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "S3" ) );
RigFemScalarResultFrames* s1IncFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "S1inc" ) );
RigFemScalarResultFrames* s1AziFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "S1azi" ) );
RigFemScalarResultFrames* s2IncFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "S2inc" ) );
RigFemScalarResultFrames* s2AziFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "S2azi" ) );
RigFemScalarResultFrames* s3IncFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "S3inc" ) );
RigFemScalarResultFrames* s3AziFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "S3azi" ) );
frameCountProgress.incrementProgress();
int frameCount = s11Frames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& s11 = s11Frames->frameData( fIdx );
const std::vector<float>& s22 = s22Frames->frameData( fIdx );
const std::vector<float>& s33 = s33Frames->frameData( fIdx );
const std::vector<float>& s12 = s12Frames->frameData( fIdx );
const std::vector<float>& s13 = s13Frames->frameData( fIdx );
const std::vector<float>& s23 = s23Frames->frameData( fIdx );
std::vector<float>& s1 = s1Frames->frameData( fIdx );
std::vector<float>& s2 = s2Frames->frameData( fIdx );
std::vector<float>& s3 = s3Frames->frameData( fIdx );
std::vector<float>& s1inc = s1IncFrames->frameData( fIdx );
std::vector<float>& s1azi = s1AziFrames->frameData( fIdx );
std::vector<float>& s2inc = s2IncFrames->frameData( fIdx );
std::vector<float>& s2azi = s2AziFrames->frameData( fIdx );
std::vector<float>& s3inc = s3IncFrames->frameData( fIdx );
std::vector<float>& s3azi = s3AziFrames->frameData( fIdx );
size_t valCount = s11.size();
s1.resize( valCount );
s2.resize( valCount );
s3.resize( valCount );
s1inc.resize( valCount );
s1azi.resize( valCount );
s2inc.resize( valCount );
s2azi.resize( valCount );
s3inc.resize( valCount );
s3azi.resize( valCount );
#pragma omp parallel for schedule( dynamic )
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
caf::Ten3f T( s11[vIdx], s22[vIdx], s33[vIdx], s12[vIdx], s23[vIdx], s13[vIdx] );
cvf::Vec3f principalDirs[3];
cvf::Vec3f principals = T.calculatePrincipals( principalDirs );
s1[vIdx] = principals[0];
s2[vIdx] = principals[1];
s3[vIdx] = principals[2];
if ( principals[0] != std::numeric_limits<float>::infinity() )
{
RiaOffshoreSphericalCoords sphCoord1( principalDirs[0] );
s1inc[vIdx] = cvf::Math::toDegrees( sphCoord1.inc() );
s1azi[vIdx] = cvf::Math::toDegrees( sphCoord1.azi() );
}
else
{
s1inc[vIdx] = std::numeric_limits<float>::infinity();
s1azi[vIdx] = std::numeric_limits<float>::infinity();
}
if ( principals[1] != std::numeric_limits<float>::infinity() )
{
RiaOffshoreSphericalCoords sphCoord2( principalDirs[1] );
s2inc[vIdx] = cvf::Math::toDegrees( sphCoord2.inc() );
s2azi[vIdx] = cvf::Math::toDegrees( sphCoord2.azi() );
}
else
{
s2inc[vIdx] = std::numeric_limits<float>::infinity();
s2azi[vIdx] = std::numeric_limits<float>::infinity();
}
if ( principals[2] != std::numeric_limits<float>::infinity() )
{
RiaOffshoreSphericalCoords sphCoord3( principalDirs[2] );
s3inc[vIdx] = cvf::Math::toDegrees( sphCoord3.inc() );
s3azi[vIdx] = cvf::Math::toDegrees( sphCoord3.azi() );
}
else
{
s3inc[vIdx] = std::numeric_limits<float>::infinity();
s3azi[vIdx] = std::numeric_limits<float>::infinity();
}
}
frameCountProgress.incrementProgress();
}
RigFemScalarResultFrames* requestedPrincipal = m_resultCollection->findOrLoadScalarResult( partIndex, resVarAddr );
return requestedPrincipal;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorPrincipalStress : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorPrincipalStress( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorPrincipalStress();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,115 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorQ.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorQ::RigFemPartResultCalculatorQ( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorQ::~RigFemPartResultCalculatorQ()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorQ::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.fieldName == "ST" && resVarAddr.componentName == "Q" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorQ::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.fieldName == "ST" && resVarAddr.componentName == "Q" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 5, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* st11 =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( resVarAddr.resultPosType, "ST", "S1" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* st22 =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( resVarAddr.resultPosType, "ST", "S2" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* st33 =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( resVarAddr.resultPosType, "ST", "S3" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* stm =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "ST", "STM" ) );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
int frameCount = st11->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& st11Data = st11->frameData( fIdx );
const std::vector<float>& st22Data = st22->frameData( fIdx );
const std::vector<float>& st33Data = st33->frameData( fIdx );
const std::vector<float>& stmData = stm->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = st11Data.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
float stmVal = stmData[vIdx];
float st11Corr = st11Data[vIdx] - stmVal;
float st22Corr = st22Data[vIdx] - stmVal;
float st33Corr = st33Data[vIdx] - stmVal;
dstFrameData[vIdx] = sqrt( 1.5 * ( st11Corr * st11Corr + st22Corr * st22Corr + st33Corr * st33Corr ) );
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorQ : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorQ( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorQ();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,105 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorSEM.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorSEM::RigFemPartResultCalculatorSEM( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorSEM::~RigFemPartResultCalculatorSEM()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorSEM::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.fieldName == "SE" && resVarAddr.componentName == "SEM" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorSEM::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.fieldName == "SE" && resVarAddr.componentName == "SEM" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 4, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* sa11 =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "SE", "S11" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* sa22 =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "SE", "S22" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* sa33 =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "SE", "S33" ) );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
int frameCount = sa11->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& sa11Data = sa11->frameData( fIdx );
const std::vector<float>& sa22Data = sa22->frameData( fIdx );
const std::vector<float>& sa33Data = sa33->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = sa11Data.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
dstFrameData[vIdx] = ( sa11Data[vIdx] + sa22Data[vIdx] + sa33Data[vIdx] ) / 3.0f;
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorSEM : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorSEM( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorSEM();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,112 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorSFI.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorSFI::RigFemPartResultCalculatorSFI( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorSFI::~RigFemPartResultCalculatorSFI()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorSFI::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.fieldName == "SE" && resVarAddr.componentName == "SFI" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorSFI::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.fieldName == "SE" && resVarAddr.componentName == "SFI" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 3, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* se1Frames =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( resVarAddr.resultPosType, "SE", "S1" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* se3Frames =
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( resVarAddr.resultPosType, "SE", "S3" ) );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
float cohPrFricAngle =
(float)( m_resultCollection->parameterCohesion() / tan( m_resultCollection->parameterFrictionAngleRad() ) );
float sinFricAng = sin( m_resultCollection->parameterFrictionAngleRad() );
int frameCount = se1Frames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& se1Data = se1Frames->frameData( fIdx );
const std::vector<float>& se3Data = se3Frames->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = se1Data.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
float se1 = se1Data[vIdx];
float se3 = se3Data[vIdx];
float se1Se3Diff = se1 - se3;
if ( fabs( se1Se3Diff ) < 1e-7 )
{
dstFrameData[vIdx] = std::numeric_limits<float>::infinity();
}
else
{
dstFrameData[vIdx] = ( ( cohPrFricAngle + 0.5 * ( se1Data[vIdx] + se3Data[vIdx] ) ) * sinFricAng ) /
( 0.5 * ( se1Data[vIdx] - se3Data[vIdx] ) );
}
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorSFI : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorSFI( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorSFI();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,105 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorSTM.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorSTM::RigFemPartResultCalculatorSTM( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorSTM::~RigFemPartResultCalculatorSTM()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorSTM::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.fieldName == "ST" && resVarAddr.componentName == "STM" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorSTM::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.fieldName == "ST" && resVarAddr.componentName == "STM" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 4, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* st11 =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "ST", "S11" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* st22 =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "ST", "S22" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* st33 =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, "ST", "S33" ) );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
int frameCount = st11->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& st11Data = st11->frameData( fIdx );
const std::vector<float>& st22Data = st22->frameData( fIdx );
const std::vector<float>& st33Data = st33->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = st11Data.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
dstFrameData[vIdx] = ( st11Data[vIdx] + st22Data[vIdx] + st33Data[vIdx] ) / 3.0f;
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorSTM : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorSTM( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorSTM();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,125 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorShearSE.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorShearSE::RigFemPartResultCalculatorShearSE( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorShearSE::~RigFemPartResultCalculatorShearSE()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorShearSE::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( ( resVarAddr.fieldName == "SE" ) && ( resVarAddr.componentName == "S12" || resVarAddr.componentName == "S13" ||
resVarAddr.componentName == "S23" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorShearSE::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 3, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* srcDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
"S-Bar",
resVarAddr.componentName ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
const RigFemPart* femPart = m_resultCollection->parts()->part( partIndex );
float inf = std::numeric_limits<float>::infinity();
int frameCount = srcDataFrames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& srcSFrameData = srcDataFrames->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = srcSFrameData.size();
dstFrameData.resize( valCount );
int elementCount = femPart->elementCount();
#pragma omp parallel for
for ( int elmIdx = 0; elmIdx < elementCount; ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
int elmNodeCount = RigFemTypes::elmentNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P )
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
if ( elmNodResIdx < srcSFrameData.size() )
{
dstFrameData[elmNodResIdx] = -srcSFrameData[elmNodResIdx];
}
}
}
else
{
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
if ( elmNodResIdx < dstFrameData.size() )
{
dstFrameData[elmNodResIdx] = inf;
}
}
}
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorShearSE : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorShearSE( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorShearSE();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,93 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorShearST.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorShearST::RigFemPartResultCalculatorShearST( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorShearST::~RigFemPartResultCalculatorShearST()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorShearST::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( ( resVarAddr.fieldName == "ST" ) && ( resVarAddr.componentName == "S12" || resVarAddr.componentName == "S13" ||
resVarAddr.componentName == "S23" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorShearST::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 2, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* srcSDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
"S-Bar",
resVarAddr.componentName ) );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
int frameCount = srcSDataFrames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& srcSFrameData = srcSDataFrames->frameData( fIdx );
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = srcSFrameData.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
dstFrameData[vIdx] = -srcSFrameData[vIdx];
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorShearST : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorShearST( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorShearST();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,169 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorStressGradients.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "RigHexGradientTools.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorStressGradients::RigFemPartResultCalculatorStressGradients( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorStressGradients::~RigFemPartResultCalculatorStressGradients()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorStressGradients::isMatching( const RigFemResultAddress& resVarAddr ) const
{
if ( resVarAddr.fieldName == "ST" || resVarAddr.fieldName == "SE" )
{
const std::vector<std::string> allowedComponentNames =
RigFemPartResultsCollection::getStressGradientComponentNames();
for ( auto& allowedComponentName : allowedComponentNames )
{
if ( resVarAddr.componentName == allowedComponentName )
{
return true;
}
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorStressGradients::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.fieldName == "ST" || resVarAddr.fieldName == "SE" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 2, "" );
frameCountProgress.setProgressDescription(
"Calculating gradient: " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
QString origFieldName = QString::fromStdString( resVarAddr.fieldName );
QString origComponentName = QString::fromStdString( resVarAddr.componentName );
// Split out the direction of the component name: SE-X => SE
QString componentName = origComponentName.left( origComponentName.lastIndexOf( QChar( '-' ) ) );
RigFemScalarResultFrames* inputResultFrames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
componentName.toStdString() ) );
RigFemScalarResultFrames* dataFramesX =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
componentName.toStdString() + "-X" ) );
RigFemScalarResultFrames* dataFramesY =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
componentName.toStdString() + "-Y" ) );
RigFemScalarResultFrames* dataFramesZ =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
componentName.toStdString() + "-Z" ) );
frameCountProgress.incrementProgress();
const RigFemPart* femPart = m_resultCollection->parts()->part( partIndex );
int elementCount = femPart->elementCount();
const std::vector<cvf::Vec3f>& nodeCoords = femPart->nodes().coordinates;
int frameCount = inputResultFrames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& inputData = inputResultFrames->frameData( fIdx );
std::vector<float>& dstFrameDataX = dataFramesX->frameData( fIdx );
std::vector<float>& dstFrameDataY = dataFramesY->frameData( fIdx );
std::vector<float>& dstFrameDataZ = dataFramesZ->frameData( fIdx );
size_t valCount = inputData.size();
dstFrameDataX.resize( valCount );
dstFrameDataY.resize( valCount );
dstFrameDataZ.resize( valCount );
#pragma omp parallel for schedule( dynamic )
for ( int elmIdx = 0; elmIdx < elementCount; ++elmIdx )
{
const int* cornerIndices = femPart->connectivities( elmIdx );
RigElementType elmType = femPart->elementType( elmIdx );
if ( !( elmType == HEX8P || elmType == HEX8 ) ) continue;
// Find the corner coordinates for element
std::array<cvf::Vec3d, 8> hexCorners;
for ( int i = 0; i < 8; i++ )
{
hexCorners[i] = cvf::Vec3d( nodeCoords[cornerIndices[i]] );
}
// Find the corresponding corner values for the element
std::array<double, 8> cornerValues;
int elmNodeCount = RigFemTypes::elmentNodeCount( elmType );
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
cornerValues[elmNodIdx] = inputData[elmNodResIdx];
}
std::array<cvf::Vec3d, 8> gradients = RigHexGradientTools::gradients( hexCorners, cornerValues );
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
{
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
dstFrameDataX[elmNodResIdx] = gradients[elmNodIdx].x();
dstFrameDataY[elmNodResIdx] = gradients[elmNodIdx].y();
dstFrameDataZ[elmNodResIdx] = gradients[elmNodIdx].z();
}
}
frameCountProgress.incrementProgress();
}
RigFemScalarResultFrames* requestedStress = m_resultCollection->findOrLoadScalarResult( partIndex, resVarAddr );
CVF_ASSERT( requestedStress );
return requestedStress;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorStressGradients : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorStressGradients( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorStressGradients();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,265 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorSurfaceAlignedStress.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cvfGeometryTools.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorSurfaceAlignedStress::RigFemPartResultCalculatorSurfaceAlignedStress(
RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorSurfaceAlignedStress::~RigFemPartResultCalculatorSurfaceAlignedStress()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorSurfaceAlignedStress::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( resVarAddr.resultPosType == RIG_ELEMENT_NODAL_FACE && resVarAddr.componentName != "Pazi" &&
resVarAddr.componentName != "Pinc" && !resVarAddr.componentName.empty() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames*
RigFemPartResultCalculatorSurfaceAlignedStress::calculate( int partIndex, const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.componentName == "STH" || resVarAddr.componentName == "STQV" ||
resVarAddr.componentName == "SN" || resVarAddr.componentName == "TPH" ||
resVarAddr.componentName == "TPQV" || resVarAddr.componentName == "THQV" ||
resVarAddr.componentName == "TP" || resVarAddr.componentName == "TPinc" ||
resVarAddr.componentName == "FAULTMOB" || resVarAddr.componentName == "PCRIT" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 7, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s11Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( RIG_ELEMENT_NODAL, resVarAddr.fieldName, "S11" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s22Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( RIG_ELEMENT_NODAL, resVarAddr.fieldName, "S22" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s33Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( RIG_ELEMENT_NODAL, resVarAddr.fieldName, "S33" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s12Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( RIG_ELEMENT_NODAL, resVarAddr.fieldName, "S12" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s23Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( RIG_ELEMENT_NODAL, resVarAddr.fieldName, "S23" ) );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* s13Frames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( RIG_ELEMENT_NODAL, resVarAddr.fieldName, "S13" ) );
RigFemScalarResultFrames* SNFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "SN" ) );
RigFemScalarResultFrames* STHFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "STH" ) );
RigFemScalarResultFrames* STQVFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "STQV" ) );
RigFemScalarResultFrames* TNHFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "TPH" ) );
RigFemScalarResultFrames* TNQVFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "TPQV" ) );
RigFemScalarResultFrames* THQVFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "THQV" ) );
RigFemScalarResultFrames* TPFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "TP" ) );
RigFemScalarResultFrames* TPincFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "TPinc" ) );
RigFemScalarResultFrames* FAULTMOBFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType,
resVarAddr.fieldName,
"FAULTMOB" ) );
RigFemScalarResultFrames* PCRITFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "PCRIT" ) );
frameCountProgress.incrementProgress();
const RigFemPart* femPart = m_resultCollection->parts()->part( partIndex );
const std::vector<cvf::Vec3f>& nodeCoordinates = femPart->nodes().coordinates;
float tanFricAng = tan( m_resultCollection->parameterFrictionAngleRad() );
float cohPrTanFricAngle = (float)( m_resultCollection->parameterCohesion() / tanFricAng );
int frameCount = s11Frames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& s11 = s11Frames->frameData( fIdx );
const std::vector<float>& s22 = s22Frames->frameData( fIdx );
const std::vector<float>& s33 = s33Frames->frameData( fIdx );
const std::vector<float>& s12 = s12Frames->frameData( fIdx );
const std::vector<float>& s23 = s23Frames->frameData( fIdx );
const std::vector<float>& s13 = s13Frames->frameData( fIdx );
std::vector<float>& SNDat = SNFrames->frameData( fIdx );
std::vector<float>& STHDat = STHFrames->frameData( fIdx );
std::vector<float>& STQVDat = STQVFrames->frameData( fIdx );
std::vector<float>& TNHDat = TNHFrames->frameData( fIdx );
std::vector<float>& TNQVDat = TNQVFrames->frameData( fIdx );
std::vector<float>& THQVDat = THQVFrames->frameData( fIdx );
std::vector<float>& TPDat = TPFrames->frameData( fIdx );
std::vector<float>& TincDat = TPincFrames->frameData( fIdx );
std::vector<float>& FAULTMOBDat = FAULTMOBFrames->frameData( fIdx );
std::vector<float>& PCRITDat = PCRITFrames->frameData( fIdx );
// HACK ! Todo : make it robust against other elements than Hex8
size_t valCount = s11.size() * 3; // Number of Elm Node Face results 24 = 4 * num faces = 3* numElmNodes
SNDat.resize( valCount );
STHDat.resize( valCount );
STQVDat.resize( valCount );
TNHDat.resize( valCount );
TNQVDat.resize( valCount );
THQVDat.resize( valCount );
TPDat.resize( valCount );
TincDat.resize( valCount );
FAULTMOBDat.resize( valCount );
PCRITDat.resize( valCount );
int elementCount = femPart->elementCount();
#pragma omp parallel for
for ( int elmIdx = 0; elmIdx < elementCount; ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
int faceCount = RigFemTypes::elmentFaceCount( elmType );
const int* elmNodeIndices = femPart->connectivities( elmIdx );
int elmNodFaceResIdxElmStart = elmIdx * 24; // HACK should get from part
for ( int lfIdx = 0; lfIdx < faceCount; ++lfIdx )
{
int faceNodeCount = 0;
const int* localElmNodeIndicesForFace =
RigFemTypes::localElmNodeIndicesForFace( elmType, lfIdx, &faceNodeCount );
if ( faceNodeCount == 4 )
{
int elmNodFaceResIdxFaceStart = elmNodFaceResIdxElmStart + lfIdx * 4; // HACK
cvf::Vec3f quadVxs[4];
quadVxs[0] = ( nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[0]]] );
quadVxs[1] = ( nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[1]]] );
quadVxs[2] = ( nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[2]]] );
quadVxs[3] = ( nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[3]]] );
cvf::Mat3f rotMx = cvf::GeometryTools::computePlaneHorizontalRotationMx( quadVxs[2] - quadVxs[0],
quadVxs[3] - quadVxs[1] );
size_t qElmNodeResIdx[4];
qElmNodeResIdx[0] = femPart->elementNodeResultIdx( elmIdx, localElmNodeIndicesForFace[0] );
qElmNodeResIdx[1] = femPart->elementNodeResultIdx( elmIdx, localElmNodeIndicesForFace[1] );
qElmNodeResIdx[2] = femPart->elementNodeResultIdx( elmIdx, localElmNodeIndicesForFace[2] );
qElmNodeResIdx[3] = femPart->elementNodeResultIdx( elmIdx, localElmNodeIndicesForFace[3] );
for ( int qIdx = 0; qIdx < 4; ++qIdx )
{
size_t elmNodResIdx = qElmNodeResIdx[qIdx];
float t11 = s11[elmNodResIdx];
float t22 = s22[elmNodResIdx];
float t33 = s33[elmNodResIdx];
float t12 = s12[elmNodResIdx];
float t23 = s23[elmNodResIdx];
float t13 = s13[elmNodResIdx];
caf::Ten3f tensor( t11, t22, t33, t12, t23, t13 );
caf::Ten3f xfTen = tensor.rotated( rotMx );
int elmNodFaceResIdx = elmNodFaceResIdxFaceStart + qIdx;
float szx = xfTen[caf::Ten3f::SZX];
float syz = xfTen[caf::Ten3f::SYZ];
float szz = xfTen[caf::Ten3f::SZZ];
STHDat[elmNodFaceResIdx] = xfTen[caf::Ten3f::SXX];
STQVDat[elmNodFaceResIdx] = xfTen[caf::Ten3f::SYY];
SNDat[elmNodFaceResIdx] = xfTen[caf::Ten3f::SZZ];
TNHDat[elmNodFaceResIdx] = xfTen[caf::Ten3f::SZX];
TNQVDat[elmNodFaceResIdx] = xfTen[caf::Ten3f::SYZ];
THQVDat[elmNodFaceResIdx] = xfTen[caf::Ten3f::SXY];
float TP = sqrt( szx * szx + syz * syz );
TPDat[elmNodFaceResIdx] = TP;
if ( TP > 1e-5 )
{
TincDat[elmNodFaceResIdx] = cvf::Math::toDegrees( acos( syz / TP ) );
}
else
{
TincDat[elmNodFaceResIdx] = std::numeric_limits<float>::infinity();
}
FAULTMOBDat[elmNodFaceResIdx] = TP / ( tanFricAng * ( szz + cohPrTanFricAngle ) );
PCRITDat[elmNodFaceResIdx] = szz - TP / tanFricAng;
}
}
}
}
frameCountProgress.incrementProgress();
}
RigFemScalarResultFrames* requestedSurfStress = m_resultCollection->findOrLoadScalarResult( partIndex, resVarAddr );
return requestedSurfStress;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorSurfaceAlignedStress : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorSurfaceAlignedStress( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorSurfaceAlignedStress();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,144 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorSurfaceAngles.h"
#include "RiaOffshoreSphericalCoords.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include "cvfGeometryTools.h"
#include "cvfMath.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorSurfaceAngles::RigFemPartResultCalculatorSurfaceAngles( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorSurfaceAngles::~RigFemPartResultCalculatorSurfaceAngles()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorSurfaceAngles::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return ( ( resVarAddr.resultPosType == RIG_ELEMENT_NODAL_FACE ) &&
( resVarAddr.componentName == "Pazi" || resVarAddr.componentName == "Pinc" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorSurfaceAngles::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.componentName == "Pazi" || resVarAddr.componentName == "Pinc" );
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 1, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
RigFemScalarResultFrames* PaziFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "Pazi" ) );
RigFemScalarResultFrames* PincFrames =
m_resultCollection->createScalarResult( partIndex,
RigFemResultAddress( resVarAddr.resultPosType, resVarAddr.fieldName, "Pinc" ) );
const RigFemPart* femPart = m_resultCollection->parts()->part( partIndex );
const std::vector<cvf::Vec3f>& nodeCoordinates = femPart->nodes().coordinates;
int frameCount = m_resultCollection->frameCount();
// HACK ! Todo : make it robust against other elements than Hex8
size_t valCount = femPart->elementCount() * 24; // Number of Elm Node Face results 24 = 4 * num faces = 3*
// numElmNodes
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
std::vector<float>& Pazi = PaziFrames->frameData( fIdx );
std::vector<float>& Pinc = PincFrames->frameData( fIdx );
Pazi.resize( valCount );
Pinc.resize( valCount );
int elementCount = femPart->elementCount();
#pragma omp parallel for
for ( int elmIdx = 0; elmIdx < elementCount; ++elmIdx )
{
RigElementType elmType = femPart->elementType( elmIdx );
int faceCount = RigFemTypes::elmentFaceCount( elmType );
const int* elmNodeIndices = femPart->connectivities( elmIdx );
int elmNodFaceResIdxElmStart = elmIdx * 24; // HACK should get from part
for ( int lfIdx = 0; lfIdx < faceCount; ++lfIdx )
{
int faceNodeCount = 0;
const int* localElmNodeIndicesForFace =
RigFemTypes::localElmNodeIndicesForFace( elmType, lfIdx, &faceNodeCount );
if ( faceNodeCount == 4 )
{
int elmNodFaceResIdxFaceStart = elmNodFaceResIdxElmStart + lfIdx * 4; // HACK
cvf::Vec3f quadVxs[4];
quadVxs[0] = ( nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[0]]] );
quadVxs[1] = ( nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[1]]] );
quadVxs[2] = ( nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[2]]] );
quadVxs[3] = ( nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[3]]] );
cvf::Mat3f rotMx = cvf::GeometryTools::computePlaneHorizontalRotationMx( quadVxs[2] - quadVxs[0],
quadVxs[3] - quadVxs[1] );
RiaOffshoreSphericalCoords sphCoord(
cvf::Vec3f( rotMx.rowCol( 0, 2 ), rotMx.rowCol( 1, 2 ), rotMx.rowCol( 2, 2 ) ) ); // Use Ez
// from the
// matrix
// as plane
// normal
for ( int qIdx = 0; qIdx < 4; ++qIdx )
{
int elmNodFaceResIdx = elmNodFaceResIdxFaceStart + qIdx;
Pazi[elmNodFaceResIdx] = cvf::Math::toDegrees( sphCoord.azi() );
Pinc[elmNodFaceResIdx] = cvf::Math::toDegrees( sphCoord.inc() );
}
}
}
}
frameCountProgress.incrementProgress();
}
RigFemScalarResultFrames* requestedPlaneAngle = m_resultCollection->findOrLoadScalarResult( partIndex, resVarAddr );
return requestedPlaneAngle;
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorSurfaceAngles : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorSurfaceAngles( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorSurfaceAngles();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -0,0 +1,164 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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 "RigFemPartResultCalculatorTimeLapse.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartResultCalculatorGamma.h"
#include "RigFemPartResultCalculatorNormalized.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigFemScalarResultFrames.h"
#include "cafProgressInfo.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorTimeLapse::RigFemPartResultCalculatorTimeLapse( RigFemPartResultsCollection& collection )
: RigFemPartResultCalculator( collection )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartResultCalculatorTimeLapse::~RigFemPartResultCalculatorTimeLapse()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFemPartResultCalculatorTimeLapse::isMatching( const RigFemResultAddress& resVarAddr ) const
{
return resVarAddr.isTimeLapse();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultCalculatorTimeLapse::calculate( int partIndex,
const RigFemResultAddress& resVarAddr )
{
CVF_ASSERT( resVarAddr.isTimeLapse() );
if ( resVarAddr.fieldName != "Gamma" )
{
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 2, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemResultAddress resVarNative( resVarAddr.resultPosType,
resVarAddr.fieldName,
resVarAddr.componentName,
RigFemResultAddress::noTimeLapseValue(),
resVarAddr.refKLayerIndex );
RigFemScalarResultFrames* srcDataFrames = m_resultCollection->findOrLoadScalarResult( partIndex, resVarNative );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
int frameCount = srcDataFrames->frameCount();
int baseFrameIdx = resVarAddr.timeLapseBaseFrameIdx;
if ( baseFrameIdx >= frameCount ) return dstDataFrames;
const std::vector<float>& baseFrameData = srcDataFrames->frameData( baseFrameIdx );
if ( baseFrameData.empty() ) return dstDataFrames;
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& srcFrameData = srcDataFrames->frameData( fIdx );
if ( srcFrameData.empty() ) continue; // Create empty results
std::vector<float>& dstFrameData = dstDataFrames->frameData( fIdx );
size_t valCount = srcFrameData.size();
dstFrameData.resize( valCount );
#pragma omp parallel for
for ( long vIdx = 0; vIdx < static_cast<long>( valCount ); ++vIdx )
{
dstFrameData[vIdx] = srcFrameData[vIdx] - baseFrameData[vIdx];
}
frameCountProgress.incrementProgress();
}
return dstDataFrames;
}
else
{
// Gamma time lapse needs to be calculated as ST_dt / POR_dt and not Gamma - Gamma_baseFrame see github
// issue #937
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * 3, "" );
frameCountProgress.setProgressDescription(
"Calculating " + QString::fromStdString( resVarAddr.fieldName + ": " + resVarAddr.componentName ) );
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemResultAddress totStressCompAddr( resVarAddr.resultPosType, "ST", "", resVarAddr.timeLapseBaseFrameIdx );
{
std::string scomp;
std::string gcomp = resVarAddr.componentName;
if ( gcomp == "Gamma1" )
scomp = "S1";
else if ( gcomp == "Gamma2" )
scomp = "S2";
else if ( gcomp == "Gamma3" )
scomp = "S3";
else if ( gcomp == "Gamma11" )
scomp = "S11";
else if ( gcomp == "Gamma22" )
scomp = "S22";
else if ( gcomp == "Gamma33" )
scomp = "S33";
totStressCompAddr.componentName = scomp;
}
RigFemScalarResultFrames* srcDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex, totStressCompAddr );
frameCountProgress.incrementProgress();
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
RigFemScalarResultFrames* srcPORDataFrames =
m_resultCollection->findOrLoadScalarResult( partIndex,
RigFemResultAddress( RIG_NODAL,
"POR-Bar",
"",
resVarAddr.timeLapseBaseFrameIdx ) );
RigFemScalarResultFrames* dstDataFrames = m_resultCollection->createScalarResult( partIndex, resVarAddr );
frameCountProgress.incrementProgress();
RigFemPartResultCalculatorGamma::calculateGammaFromFrames( partIndex,
m_resultCollection->parts(),
srcDataFrames,
srcPORDataFrames,
dstDataFrames,
&frameCountProgress );
if ( resVarAddr.normalizeByHydrostaticPressure() && RigFemPartResultsCollection::isNormalizableResult( resVarAddr ) )
{
RigFemPartResultCalculatorNormalized normalizedCalculator( *m_resultCollection );
dstDataFrames = normalizedCalculator.calculate( partIndex, resVarAddr );
}
return dstDataFrames;
}
}

View File

@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPartResultCalculator.h"
class RigFemPartResultsCollection;
class RigFemScalarResultFrames;
class RigFemResultAddress;
//==================================================================================================
///
//==================================================================================================
class RigFemPartResultCalculatorTimeLapse : public RigFemPartResultCalculator
{
public:
explicit RigFemPartResultCalculatorTimeLapse( RigFemPartResultsCollection& collection );
virtual ~RigFemPartResultCalculatorTimeLapse();
bool isMatching( const RigFemResultAddress& resVarAddr ) const override;
RigFemScalarResultFrames* calculate( int partIndex, const RigFemResultAddress& resVarAddr ) override;
};

View File

@@ -29,6 +29,7 @@
#include <QString>
#include <map>
#include <memory>
#include <string>
#include <vector>
@@ -40,6 +41,7 @@ class RigFemPartResults;
class RigStatisticsDataCache;
class RigFemPartCollection;
class RigFormationNames;
class RigFemPartResultCalculator;
namespace caf
{
@@ -67,7 +69,9 @@ public:
double parameterCohesion() const { return m_cohesion; }
double parameterFrictionAngleRad() const { return m_frictionAngleRad; }
void setBiotCoefficientParameters( double fixedFactor, const QString& biotResultAddress );
void setBiotCoefficientParameters( double fixedFactor, const QString& biotResultAddress );
double biotFixedFactor() const { return m_biotFixedFactor; }
QString biotResultAddress() const { return m_biotResultAddress; }
std::map<std::string, std::vector<std::string>> scalarFieldAndComponentNames( RigFemResultPosEnum resPos );
std::vector<std::string> filteredStepNames() const;
@@ -78,10 +82,10 @@ public:
const std::vector<float>& resultValues( const RigFemResultAddress& resVarAddr, int partIndex, int frameIndex );
std::vector<caf::Ten3f> tensors( const RigFemResultAddress& resVarAddr, int partIndex, int frameIndex );
int partCount() const;
int frameCount();
static float dsm( float p1, float p3, float tanFricAng, float cohPrTanFricAngle );
const RigFemPartCollection* parts() const;
int partCount() const;
int frameCount();
void minMaxScalarValues( const RigFemResultAddress& resVarAddr, int frameIndex, double* localMin, double* localMax );
void minMaxScalarValues( const RigFemResultAddress& resVarAddr, double* globalMin, double* globalMax );
@@ -121,52 +125,20 @@ public:
static std::set<RigFemResultAddress> normalizedResults();
static bool isNormalizableResult( const RigFemResultAddress& result );
void setNormalizationAirGap( double normalizationAirGap );
void setNormalizationAirGap( double normalizationAirGap );
double normalizationAirGap() const;
RigFemScalarResultFrames* findOrLoadScalarResult( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* createScalarResult( int partIndex, const RigFemResultAddress& resVarAddr );
bool isValidBiotData( const std::vector<float>& biotData, size_t elementCount ) const;
static std::vector<std::string> getStressComponentNames( bool includeShear = true );
static std::vector<std::string> getStressGradientComponentNames( bool includeShear = true );
const RigFormationNames* activeFormationNames() const;
private:
RigFemScalarResultFrames* findOrLoadScalarResult( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateDerivedResult( int partIndex, const RigFemResultAddress& resVarAddr );
void calculateGammaFromFrames( int partIndex,
const RigFemScalarResultFrames* totalStressComponentDataFrames,
const RigFemScalarResultFrames* srcPORDataFrames,
RigFemScalarResultFrames* dstDataFrames,
caf::ProgressInfo* frameCountProgress );
RigFemScalarResultFrames* calculateBarConvertedResult( int partIndex,
const RigFemResultAddress& convertedResultAddr,
const std::string& fieldNameToConvert );
RigFemScalarResultFrames* calculateEnIpPorBarResult( int partIndex, const RigFemResultAddress& convertedResultAddr );
RigFemScalarResultFrames* calculateTimeLapseResult( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateMeanStressSEM( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateSFI( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateDSM( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateFOS( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateMeanStressSTM( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateDeviatoricStress( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateVolumetricStrain( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateDeviatoricStrain( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateSurfaceAlignedStress( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateSurfaceAngles( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculatePrincipalStressValues( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculatePrincipalStrainValues( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateCompactionValues( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateNE( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateSE_11_22_33( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateSE_12_13_23( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateST_11_22_33( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateST_12_13_23( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateGamma( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateFormationIndices( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateStressGradients( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateNodalGradients( int partIndex, const RigFemResultAddress& resVarAddr );
RigFemScalarResultFrames* calculateNormalizedResult( int partIndex, const RigFemResultAddress& resVarAddr );
const RigFormationNames* activeFormationNames() const;
bool isValidBiotData( const std::vector<float>& biotData, size_t elementCount ) const;
private:
cvf::Collection<RigFemPartResults> m_femPartResults;
cvf::ref<RifGeoMechReaderInterface> m_readerInterface;
@@ -181,31 +153,9 @@ private:
double m_biotFixedFactor;
QString m_biotResultAddress;
std::vector<std::unique_ptr<RigFemPartResultCalculator>> m_resultCalculators;
RigStatisticsDataCache* statistics( const RigFemResultAddress& resVarAddr );
std::vector<RigFemResultAddress> getResAddrToComponentsToRead( const RigFemResultAddress& resVarAddr );
std::map<RigFemResultAddress, cvf::ref<RigStatisticsDataCache>> m_resultStatistics;
static std::vector<std::string> getStressComponentNames( bool includeShear = true );
static std::vector<std::string> getStressGradientComponentNames( bool includeShear = true );
};
class RigFemPart;
class RigFemClosestResultIndexCalculator
{
public:
RigFemClosestResultIndexCalculator( RigFemPart* femPart,
RigFemResultPosEnum resultPosition,
int elementIndex,
int m_face,
const cvf::Vec3d& intersectionPointInDomain );
int resultIndexToClosestResult() { return m_resultIndexToClosestResult; }
int closestNodeId() { return m_closestNodeId; }
int closestElementNodeResIdx() { return m_closestElementNodeResIdx; }
private:
int m_resultIndexToClosestResult;
int m_closestNodeId;
int m_closestElementNodeResIdx;
};

View File

@@ -19,6 +19,7 @@
#include "RiuFemResultTextBuilder.h"
#include "RigFemClosestResultIndexCalculator.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"

View File

@@ -19,6 +19,7 @@
#include "RiuFemTimeHistoryResultAccessor.h"
#include "RigFemClosestResultIndexCalculator.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"

View File

@@ -26,6 +26,7 @@
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"
#include "RigFemPartResultCalculatorDSM.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultPosEnum.h"
#include "RigGeoMechCaseData.h"
@@ -567,7 +568,7 @@ float RiuMohrsCirclePlot::calculateFOS( const cvf::Vec3f& principals, double fri
float tanFricAng = cvf::Math::tan( cvf::Math::toRadians( frictionAngle ) );
float cohPrTanFricAngle = 1.0f * cohesion / tanFricAng;
float dsm = RigFemPartResultsCollection::dsm( se1, se3, tanFricAng, cohPrTanFricAngle );
float dsm = RigFemPartResultCalculatorDSM::dsm( se1, se3, tanFricAng, cohPrTanFricAngle );
return 1.0f / dsm;
}