mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-25 06:38:13 -05:00
Scripting: read GeoMech time steps, result names and values
This commit is contained in:
1 parent
9613251e9a
commit
7222d6360e
10 files changed
+495
-1
No files matched your search
@@ -20,12 +20,31 @@
|
||||
|
||||
#include "WellLogCommands/RicNewWellBoreStabilityPlotFeature.h"
|
||||
|
||||
#include "KeyValueStore/RiaKeyValueStoreUtil.h"
|
||||
#include "RiaApplication.h"
|
||||
|
||||
#include "RigFemPartResultsCollection.h"
|
||||
#include "RigGeoMechCaseData.h"
|
||||
|
||||
#include "RimGeoMechCase.h"
|
||||
#include "RimWbsParameters.h"
|
||||
#include "RimWellBoreStabilityPlot.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimcDataContainerString.h"
|
||||
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
#include "cafPdmScriptEnumNameRegistry.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct RegisterScriptEnumNames
|
||||
{
|
||||
RegisterScriptEnumNames() { caf::PdmScriptEnumNameRegistry::registerName<RigFemResultPosEnum>( "GeoMechResultPosition" ); }
|
||||
};
|
||||
const RegisterScriptEnumNames s_registerScriptEnumNames;
|
||||
} // namespace
|
||||
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimGeoMechCase, RimGeoMechCase_createWellBoreStabilityPlot, "createWellBoreStabilityPlot" );
|
||||
|
||||
@@ -97,3 +116,191 @@ QString RimGeoMechCase_createWellBoreStabilityPlot::classKeywordReturnedType() c
|
||||
{
|
||||
return RimWellBoreStabilityPlot::classKeywordStatic();
|
||||
}
|
||||
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimGeoMechCase, RimGeoMechCase_timeStepStrings, "TimeStepStringsInternal" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGeoMechCase_timeStepStrings::RimGeoMechCase_timeStepStrings( caf::PdmObjectHandle* self )
|
||||
: PdmObjectMethod( self, PdmObjectMethod::NullPointerType::NULL_IS_INVALID, PdmObjectMethod::ResultType::PERSISTENT_FALSE )
|
||||
{
|
||||
CAF_PDM_InitObject( "Time Step Strings", "", "", "Time step strings for this case." );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::expected<caf::PdmObjectHandle*, QString> RimGeoMechCase_timeStepStrings::execute()
|
||||
{
|
||||
auto* geoMechCase = self<RimGeoMechCase>();
|
||||
if ( !geoMechCase ) return std::unexpected( "No GeoMech case is available." );
|
||||
|
||||
auto* container = new RimcDataContainerString();
|
||||
|
||||
if ( geoMechCase->geoMechData() && geoMechCase->geoMechData()->femPartResults() )
|
||||
{
|
||||
// Filtered time step names match the time step index used by result_values()
|
||||
std::vector<QString> names;
|
||||
for ( const auto& name : geoMechCase->geoMechData()->femPartResults()->filteredTimeStepNames() )
|
||||
{
|
||||
names.push_back( QString::fromStdString( name ) );
|
||||
}
|
||||
container->m_stringValues = names;
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimGeoMechCase_timeStepStrings::classKeywordReturnedType() const
|
||||
{
|
||||
return RimcDataContainerString::classKeywordStatic();
|
||||
}
|
||||
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimGeoMechCase, RimGeoMechCase_resultNames, "ResultNamesInternal" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGeoMechCase_resultNames::RimGeoMechCase_resultNames( caf::PdmObjectHandle* self )
|
||||
: PdmObjectMethod( self, PdmObjectMethod::NullPointerType::NULL_IS_INVALID, PdmObjectMethod::ResultType::PERSISTENT_FALSE )
|
||||
{
|
||||
CAF_PDM_InitObject( "Result Names", "", "", "Result names for this case." );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_resultPosition,
|
||||
"ResultPosition",
|
||||
caf::AppEnum<RigFemResultPosEnum>( RIG_ELEMENT_NODAL ),
|
||||
"Result Position",
|
||||
"",
|
||||
"",
|
||||
"Result position, for example NODAL or ELEMENT_NODAL" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::expected<caf::PdmObjectHandle*, QString> RimGeoMechCase_resultNames::execute()
|
||||
{
|
||||
auto* geoMechCase = self<RimGeoMechCase>();
|
||||
if ( !geoMechCase ) return std::unexpected( "No GeoMech case is available." );
|
||||
|
||||
if ( !geoMechCase->geoMechData() || !geoMechCase->geoMechData()->femPartResults() )
|
||||
{
|
||||
return std::unexpected( "The GeoMech case has no result data. Open the case first." );
|
||||
}
|
||||
|
||||
const auto fieldsWithComponents = geoMechCase->geoMechData()->femPartResults()->scalarFieldAndComponentNames( m_resultPosition() );
|
||||
|
||||
std::vector<QString> names;
|
||||
for ( const auto& [field, components] : fieldsWithComponents )
|
||||
{
|
||||
const QString fieldName = QString::fromStdString( field );
|
||||
if ( components.empty() )
|
||||
{
|
||||
names.push_back( fieldName );
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( const auto& component : components )
|
||||
{
|
||||
names.push_back( fieldName + ":" + QString::fromStdString( component ) );
|
||||
}
|
||||
}
|
||||
|
||||
auto* container = new RimcDataContainerString();
|
||||
container->m_stringValues = std::move( names );
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimGeoMechCase_resultNames::classKeywordReturnedType() const
|
||||
{
|
||||
return RimcDataContainerString::classKeywordStatic();
|
||||
}
|
||||
|
||||
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimGeoMechCase, RimGeoMechCase_readResultValuesInternal, "ReadResultValuesInternal" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGeoMechCase_readResultValuesInternal::RimGeoMechCase_readResultValuesInternal( caf::PdmObjectHandle* self )
|
||||
: caf::PdmVoidObjectMethod( self )
|
||||
{
|
||||
CAF_PDM_InitObject( "Read Result Values", "", "", "Read GeoMech result values" );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_resultPosition,
|
||||
"ResultPosition",
|
||||
caf::AppEnum<RigFemResultPosEnum>( RIG_ELEMENT_NODAL ),
|
||||
"Result Position",
|
||||
"",
|
||||
"",
|
||||
"Result position, for example NODAL or ELEMENT_NODAL" );
|
||||
CAF_PDM_InitScriptableField( &m_fieldName, "FieldName", QString(), "Field Name" );
|
||||
CAF_PDM_InitScriptableField( &m_componentName, "ComponentName", QString(), "Component Name" );
|
||||
CAF_PDM_InitScriptableField( &m_timeStep, "TimeStep", 0, "Time Step", "", "", "Zero-based time step index" );
|
||||
CAF_PDM_InitScriptableField( &m_frameIndex, "FrameIndex", -1, "Frame Index", "", "", "Zero-based frame index. Negative selects the last frame" );
|
||||
CAF_PDM_InitScriptableField( &m_key, "Key", QString(), "Key" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::expected<caf::PdmObjectHandle*, QString> RimGeoMechCase_readResultValuesInternal::execute()
|
||||
{
|
||||
auto* geoMechCase = self<RimGeoMechCase>();
|
||||
if ( !geoMechCase ) return std::unexpected( "No GeoMech case is available." );
|
||||
|
||||
if ( m_key().isEmpty() ) return std::unexpected( "No key specified." );
|
||||
if ( m_fieldName().isEmpty() ) return std::unexpected( "No result field name specified." );
|
||||
|
||||
if ( !geoMechCase->geoMechData() || !geoMechCase->geoMechData()->femPartResults() )
|
||||
{
|
||||
return std::unexpected( "The GeoMech case has no result data. Open the case first." );
|
||||
}
|
||||
|
||||
auto* results = geoMechCase->geoMechData()->femPartResults();
|
||||
|
||||
if ( m_timeStep() < 0 || m_timeStep() >= results->timeStepCount() )
|
||||
{
|
||||
return std::unexpected( QString( "Time step %1 is out of range [0, %2)." ).arg( m_timeStep() ).arg( results->timeStepCount() ) );
|
||||
}
|
||||
|
||||
const int frameCount = results->frameCount( m_timeStep() );
|
||||
const int frameIndex = m_frameIndex() < 0 ? frameCount - 1 : m_frameIndex();
|
||||
if ( frameIndex < 0 || frameIndex >= frameCount )
|
||||
{
|
||||
return std::unexpected(
|
||||
QString( "Frame %1 (resolved to %2) is out of range [0, %3)." ).arg( m_frameIndex() ).arg( frameIndex ).arg( frameCount ) );
|
||||
}
|
||||
|
||||
const RigFemResultAddress address( m_resultPosition(), m_fieldName().toStdString(), m_componentName().toStdString() );
|
||||
if ( !address.isValid() ) return std::unexpected( QString( "Invalid result %1 %2." ).arg( m_fieldName(), m_componentName() ) );
|
||||
|
||||
const auto fieldsWithComponents = results->scalarFieldAndComponentNames( m_resultPosition() );
|
||||
const auto fieldIt = fieldsWithComponents.find( address.fieldName );
|
||||
if ( fieldIt == fieldsWithComponents.end() )
|
||||
{
|
||||
return std::unexpected( QString( "Unknown result field '%1'." ).arg( m_fieldName() ) );
|
||||
}
|
||||
const auto& components = fieldIt->second;
|
||||
const bool componentOk = components.empty()
|
||||
? address.componentName.empty()
|
||||
: std::find( components.begin(), components.end(), address.componentName ) != components.end();
|
||||
if ( !componentOk )
|
||||
{
|
||||
return std::unexpected( QString( "Unknown component '%1' for result field '%2'." ).arg( m_componentName(), m_fieldName() ) );
|
||||
}
|
||||
|
||||
std::vector<float> values;
|
||||
results->globalResultValues( address, m_timeStep(), frameIndex, values );
|
||||
|
||||
RiaApplication::instance()->keyValueStore()->set( m_key().toStdString(), RiaKeyValueStoreUtil::convertToByteVector( values ) );
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RigFemResultPosEnum.h"
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmObjectMethod.h"
|
||||
@@ -54,3 +57,60 @@ private:
|
||||
|
||||
const RimWbsParameters* m_parameters = nullptr;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Get the time step strings of this GeoMech case.
|
||||
//==================================================================================================
|
||||
class RimGeoMechCase_timeStepStrings : public caf::PdmObjectMethod
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimGeoMechCase_timeStepStrings( caf::PdmObjectHandle* self );
|
||||
|
||||
std::expected<caf::PdmObjectHandle*, QString> execute() override;
|
||||
QString classKeywordReturnedType() const override;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Get the result names of this GeoMech case for a result position.
|
||||
///
|
||||
/// Names are returned as "FIELD:COMPONENT", or "FIELD" for results without components.
|
||||
//==================================================================================================
|
||||
class RimGeoMechCase_resultNames : public caf::PdmObjectMethod
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimGeoMechCase_resultNames( caf::PdmObjectHandle* self );
|
||||
|
||||
std::expected<caf::PdmObjectHandle*, QString> execute() override;
|
||||
QString classKeywordReturnedType() const override;
|
||||
|
||||
private:
|
||||
caf::PdmField<caf::AppEnum<RigFemResultPosEnum>> m_resultPosition;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Read the values of a GeoMech result into the key-value store.
|
||||
///
|
||||
/// A negative frame index selects the last frame of the time step. The values of all parts are
|
||||
/// stored as a float array under the given key.
|
||||
//==================================================================================================
|
||||
class RimGeoMechCase_readResultValuesInternal : public caf::PdmVoidObjectMethod
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimGeoMechCase_readResultValuesInternal( caf::PdmObjectHandle* self );
|
||||
|
||||
std::expected<caf::PdmObjectHandle*, QString> execute() override;
|
||||
|
||||
private:
|
||||
caf::PdmField<caf::AppEnum<RigFemResultPosEnum>> m_resultPosition;
|
||||
caf::PdmField<QString> m_fieldName;
|
||||
caf::PdmField<QString> m_componentName;
|
||||
caf::PdmField<int> m_timeStep;
|
||||
caf::PdmField<int> m_frameIndex;
|
||||
caf::PdmField<QString> m_key;
|
||||
};
|
||||
Reference in new issue
Block a user