diff --git a/ApplicationLibCode/Application/RiaPreferencesGeoMech.cpp b/ApplicationLibCode/Application/RiaPreferencesGeoMech.cpp index ca0a353bed..d2a9c15aba 100644 --- a/ApplicationLibCode/Application/RiaPreferencesGeoMech.cpp +++ b/ApplicationLibCode/Application/RiaPreferencesGeoMech.cpp @@ -42,6 +42,10 @@ RiaPreferencesGeoMech::RiaPreferencesGeoMech() m_geomechWIACommand.uiCapability()->setUiEditorTypeName( caf::PdmUiFilePathEditor::uiEditorTypeName() ); m_geomechWIACommand.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP ); + CAF_PDM_InitFieldNoDefault( &m_geomechFRMDefaultXML, "geomechFRMDefaultXML", "Default Parameter XML File" ); + m_geomechFRMDefaultXML.uiCapability()->setUiEditorTypeName( caf::PdmUiFilePathEditor::uiEditorTypeName() ); + m_geomechFRMDefaultXML.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP ); + CAF_PDM_InitFieldNoDefault( &m_geomechFRMCommand, "geomechFRMCommand", "Command to run" ); m_geomechFRMCommand.uiCapability()->setUiEditorTypeName( caf::PdmUiFilePathEditor::uiEditorTypeName() ); m_geomechFRMCommand.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP ); @@ -72,6 +76,7 @@ void RiaPreferencesGeoMech::appendItems( caf::PdmUiOrdering& uiOrdering ) const caf::PdmUiGroup* faultRMGroup = uiOrdering.addNewGroup( "Fault Reactivation Modeling" ); faultRMGroup->add( &m_geomechFRMCommand ); + faultRMGroup->add( &m_geomechFRMDefaultXML ); caf::PdmUiGroup* commonGroup = uiOrdering.addNewGroup( "Common Settings" ); commonGroup->add( &m_keepTemporaryFiles ); @@ -102,6 +107,14 @@ QString RiaPreferencesGeoMech::geomechFRMCommand() const return m_geomechFRMCommand; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaPreferencesGeoMech::geomechFRMDefaultXML() const +{ + return m_geomechFRMDefaultXML; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Application/RiaPreferencesGeoMech.h b/ApplicationLibCode/Application/RiaPreferencesGeoMech.h index e040e0a64a..b3f30bfc71 100644 --- a/ApplicationLibCode/Application/RiaPreferencesGeoMech.h +++ b/ApplicationLibCode/Application/RiaPreferencesGeoMech.h @@ -43,6 +43,7 @@ public: QString geomechWIADefaultXML() const; QString geomechWIACommand() const; + QString geomechFRMDefaultXML() const; QString geomechFRMCommand() const; bool waitBeforeRun() const; @@ -54,6 +55,7 @@ private: caf::PdmField m_geomechWIADefaultXML; caf::PdmField m_geomechWIACommand; + caf::PdmField m_geomechFRMDefaultXML; caf::PdmField m_geomechFRMCommand; caf::PdmField m_waitForInputFileEdit; diff --git a/ApplicationLibCode/Commands/GeoMechCommands/RicNewFaultReactModelingFeature.cpp b/ApplicationLibCode/Commands/GeoMechCommands/RicNewFaultReactModelingFeature.cpp index 1f4adc7724..9591b0a2b3 100644 --- a/ApplicationLibCode/Commands/GeoMechCommands/RicNewFaultReactModelingFeature.cpp +++ b/ApplicationLibCode/Commands/GeoMechCommands/RicNewFaultReactModelingFeature.cpp @@ -43,6 +43,7 @@ #include "cvfStructGrid.h" #include +#include CAF_CMD_SOURCE_INIT( RicNewFaultReactModelingFeature, "RicNewFaultReactModelingFeature" ); @@ -110,13 +111,18 @@ void RicNewFaultReactModelingFeature::onActionTriggered( bool isChecked ) QString baseDir = RiuFileDialogTools::getExistingDirectory( nullptr, tr( "Select Working Directory" ), defaultDir ); if ( baseDir.isNull() || baseDir.isEmpty() ) return; - auto model = eclView->faultReactivationModelCollection()->addNewModel( rimFault, target1, target2, baseDir ); + QString errMsg; + auto model = eclView->faultReactivationModelCollection()->addNewModel( rimFault, target1, target2, baseDir, errMsg ); if ( model != nullptr ) { model->updateTimeSteps(); view->updateAllRequiredEditors(); Riu3DMainWindowTools::selectAsCurrentItem( model ); } + else + { + QMessageBox::critical( nullptr, "Fault Reactivation Modeling", errMsg ); + } } } } diff --git a/ApplicationLibCode/Commands/GeoMechCommands/RicShowFaultReactModelFeature.cpp b/ApplicationLibCode/Commands/GeoMechCommands/RicShowFaultReactModelFeature.cpp index 3bbd380a7f..c69214e435 100644 --- a/ApplicationLibCode/Commands/GeoMechCommands/RicShowFaultReactModelFeature.cpp +++ b/ApplicationLibCode/Commands/GeoMechCommands/RicShowFaultReactModelFeature.cpp @@ -56,6 +56,12 @@ void RicShowFaultReactModelFeature::onActionTriggered( bool isChecked ) const QString frmTitle( "Fault Reactivation Modeling" ); const QString exportFile = model->inputFilename(); + if ( !model->extractAndExportModelData() ) + { + QMessageBox::critical( nullptr, frmTitle, "Unable to get necessary data from the input case." ); + return; + } + auto [result, errText] = RifFaultReactivationModelExporter::exportToFile( exportFile.toStdString(), *model ); if ( !result ) { diff --git a/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.cpp b/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.cpp index 8c37afa6c9..ca15e65075 100644 --- a/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.cpp +++ b/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.cpp @@ -39,13 +39,13 @@ std::pair RifFaultReactivationModelExporter::exportToStream( { std::string applicationNameAndVersion = std::string( RI_APPLICATION_NAME ) + " " + std::string( STRPRODUCTVER ); - using PartBorderSurface = RigGriddedPart3d::BorderSurface; + using PartBorderSurface = RimFaultReactivation::BorderSurface; std::vector> borders = { { PartBorderSurface::UpperSurface, "TOP" }, { PartBorderSurface::FaultSurface, "FAULT" }, { PartBorderSurface::LowerSurface, "BASE" } }; - // The two parts are "mirrored", so face number 4 should of the two parts should face eachother. - using FaultGridPart = RigFaultReactivationModel::GridPart; + // The two parts are "mirrored", so face number 4 of the two parts should face eachother. + using FaultGridPart = RimFaultReactivation::GridPart; std::map, int> faces = { { { FaultGridPart::PART1, PartBorderSurface::FaultSurface }, 4 }, { { FaultGridPart::PART1, PartBorderSurface::UpperSurface }, 4 }, { { FaultGridPart::PART1, PartBorderSurface::LowerSurface }, 4 }, @@ -58,9 +58,9 @@ std::pair RifFaultReactivationModelExporter::exportToStream( { FaultGridPart::PART2, "RIGHT_PART" }, }; - std::map boundaries = { - { RigGriddedPart3d::Boundary::Bottom, "BOTTOM" }, - { RigGriddedPart3d::Boundary::FarSide, "FARSIDE" }, + std::map boundaries = { + { RimFaultReactivation::Boundary::Bottom, "BOTTOM" }, + { RimFaultReactivation::Boundary::FarSide, "FARSIDE" }, }; double faultFriction = 0.0; @@ -121,12 +121,12 @@ std::pair RifFaultReactivationModelExporter::printHeading( st /// //-------------------------------------------------------------------------------------------------- std::pair RifFaultReactivationModelExporter::printParts( - std::ostream& stream, - const RigFaultReactivationModel& model, - const std::map& partNames, - const std::vector>& borders, - const std::map, int>& faces, - const std::map& boundaries ) + std::ostream& stream, + const RigFaultReactivationModel& model, + const std::map& partNames, + const std::vector>& borders, + const std::map, int>& faces, + const std::map& boundaries ) { RifInpExportTools::printSectionComment( stream, "PARTS" ); @@ -152,7 +152,7 @@ std::pair RifFaultReactivationModelExporter::printParts( RifInpExportTools::printNodeSet( stream, "PORE_PRESSURE", 1, nodes.size(), true ); - const std::map>& borderSurfaceElements = grid->borderSurfaceElements(); + const std::map>& borderSurfaceElements = grid->borderSurfaceElements(); for ( auto [boundary, boundaryName] : boundaries ) { @@ -199,10 +199,10 @@ std::pair RifFaultReactivationModelExporter::printParts( /// //-------------------------------------------------------------------------------------------------- std::pair - RifFaultReactivationModelExporter::printAssembly( std::ostream& stream, - const RigFaultReactivationModel& model, - const std::map& partNames, - const std::pair& transform ) + RifFaultReactivationModelExporter::printAssembly( std::ostream& stream, + const RigFaultReactivationModel& model, + const std::map& partNames, + const std::pair& transform ) { // ASSEMBLY part RifInpExportTools::printSectionComment( stream, "ASSEMBLY" ); @@ -297,10 +297,10 @@ std::pair RifFaultReactivationModelExporter::printInteraction /// //-------------------------------------------------------------------------------------------------- std::pair - RifFaultReactivationModelExporter::printBoundaryConditions( std::ostream& stream, - const RigFaultReactivationModel& model, - const std::map& partNames, - const std::map& boundaries ) + RifFaultReactivationModelExporter::printBoundaryConditions( std::ostream& stream, + const RigFaultReactivationModel& model, + const std::map& partNames, + const std::map& boundaries ) { auto printBoundaryCondition = []( std::ostream& stream, const std::string& boundarySetName, const std::string& symmetryType ) { @@ -308,11 +308,9 @@ std::pair RifInpExportTools::printLine( stream, boundarySetName + ", " + symmetryType ); }; - std::map symmetryTypes = { - { RigGriddedPart3d::Boundary::Bottom, "ZSYMM" }, - { RigGriddedPart3d::Boundary::Back, "YSYMM" }, - { RigGriddedPart3d::Boundary::Front, "YSYMM" }, - { RigGriddedPart3d::Boundary::FarSide, "XSYMM" }, + std::map symmetryTypes = { + { RimFaultReactivation::Boundary::Bottom, "ZSYMM" }, + { RimFaultReactivation::Boundary::FarSide, "XSYMM" }, }; @@ -350,8 +348,8 @@ std::pair /// //-------------------------------------------------------------------------------------------------- std::pair - RifFaultReactivationModelExporter::printPredefinedFields( std::ostream& stream, - const std::map& partNames ) + RifFaultReactivationModelExporter::printPredefinedFields( std::ostream& stream, + const std::map& partNames ) { // PREDEFINED FIELDS struct PredefinedField @@ -383,12 +381,11 @@ std::pair //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::pair - RifFaultReactivationModelExporter::printSteps( std::ostream& stream, - const RigFaultReactivationModel& model, - const std::map& partNames, - const std::vector& timeSteps, - const std::string& exportDirectory ) +std::pair RifFaultReactivationModelExporter::printSteps( std::ostream& stream, + const RigFaultReactivationModel& model, + const std::map& partNames, + const std::vector& timeSteps, + const std::string& exportDirectory ) { // First time step has to be selected in order to export currently if ( timeSteps.size() < 2 ) return { false, "Failed to export fault reactivation INP: needs at least two time steps." }; @@ -456,9 +453,9 @@ std::pair /// //-------------------------------------------------------------------------------------------------- std::pair - RifFaultReactivationModelExporter::printInteractions( std::ostream& stream, - const std::map& partNames, - const std::vector>& borders ) + RifFaultReactivationModelExporter::printInteractions( std::ostream& stream, + const std::map& partNames, + const std::vector>& borders ) { RifInpExportTools::printSectionComment( stream, "INTERACTIONS" ); for ( const auto& [border, borderName] : borders ) @@ -467,7 +464,7 @@ std::pair std::string interactionName = "NON-FAULT"; std::string extra; - if ( border == RigGriddedPart3d::BorderSurface::FaultSurface ) + if ( border == RimFaultReactivation::BorderSurface::FaultSurface ) { interactionName = "FAULT"; extra = ", adjust=0.0"; @@ -476,8 +473,8 @@ std::pair RifInpExportTools::printHeading( stream, "Contact Pair, interaction=" + interactionName + ", small sliding, type=SURFACE TO SURFACE" + extra ); - std::string part1Name = partNames.find( RigFaultReactivationModel::GridPart::PART1 )->second; - std::string part2Name = partNames.find( RigFaultReactivationModel::GridPart::PART2 )->second; + std::string part1Name = partNames.find( RimFaultReactivation::GridPart::PART1 )->second; + std::string part2Name = partNames.find( RimFaultReactivation::GridPart::PART2 )->second; RifInpExportTools::printLine( stream, part1Name + "." + borderName + ", " + part2Name + "." + borderName ); } diff --git a/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.h b/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.h index dd5fd81f5c..719be7a469 100644 --- a/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.h +++ b/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.h @@ -41,34 +41,35 @@ public: private: static std::pair printHeading( std::ostream& stream, const std::string& applicationNameAndVersion ); static std::pair - printParts( std::ostream& stream, - const RigFaultReactivationModel& model, - const std::map& partNames, - const std::vector>& borders, - const std::map, int>& faces, - const std::map& boundaries ); + printParts( std::ostream& stream, + const RigFaultReactivationModel& model, + const std::map& partNames, + const std::vector>& borders, + const std::map, int>& faces, + const std::map& boundaries ); - static std::pair printAssembly( std::ostream& stream, - const RigFaultReactivationModel& model, - const std::map& partNames, - const std::pair& transform ); + static std::pair printAssembly( std::ostream& stream, + const RigFaultReactivationModel& model, + const std::map& partNames, + const std::pair& transform ); static std::pair printMaterials( std::ostream& stream ); static std::pair printInteractionProperties( std::ostream& stream, double faultFriction ); - static std::pair printBoundaryConditions( std::ostream& stream, - const RigFaultReactivationModel& model, - const std::map& partNames, - const std::map& boundaries ); - static std::pair printPredefinedFields( std::ostream& stream, - const std::map& partNames ); - static std::pair printSteps( std::ostream& stream, - const RigFaultReactivationModel& model, - const std::map& partNames, - const std::vector& timeSteps, - const std::string& exportDirectory ); + static std::pair printBoundaryConditions( std::ostream& stream, + const RigFaultReactivationModel& model, + const std::map& partNames, + const std::map& boundaries ); + static std::pair printPredefinedFields( std::ostream& stream, + const std::map& partNames ); + static std::pair printSteps( std::ostream& stream, + const RigFaultReactivationModel& model, + const std::map& partNames, + const std::vector& timeSteps, + const std::string& exportDirectory ); - static std::pair printInteractions( std::ostream& stream, - const std::map& partNames, - const std::vector>& borders ); + static std::pair + printInteractions( std::ostream& stream, + const std::map& partNames, + const std::vector>& borders ); }; diff --git a/ApplicationLibCode/ProjectDataModel/Faults/CMakeLists_files.cmake b/ApplicationLibCode/ProjectDataModel/Faults/CMakeLists_files.cmake index 79898fe1d5..26d1414139 100644 --- a/ApplicationLibCode/ProjectDataModel/Faults/CMakeLists_files.cmake +++ b/ApplicationLibCode/ProjectDataModel/Faults/CMakeLists_files.cmake @@ -5,6 +5,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationModelCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationTools.h ${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationDataAccess.h + ${CMAKE_CURRENT_LIST_DIR}/RimFaultReactivationEnums.h ) set(SOURCE_GROUP_SOURCE_FILES diff --git a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationDataAccess.cpp b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationDataAccess.cpp index d18397652c..05edc676d2 100644 --- a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationDataAccess.cpp +++ b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationDataAccess.cpp @@ -75,18 +75,31 @@ void RimFaultReactivationDataAccess::useCellIndexAdjustment( std::map& cellIndexAdjustmentMap ) +{ + CAF_ASSERT( grid != nullptr ); + + size_t cellIdx = grid->findReservoirCellIndexFromPoint( position ); + + // adjust cell index if present in the map + if ( auto search = cellIndexAdjustmentMap.find( cellIdx ); search != cellIndexAdjustmentMap.end() ) + { + cellIdx = search->second; + } + + return cellIdx; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimFaultReactivationDataAccess::porePressureAtPosition( const cvf::Vec3d& position, double defaultPorePressureGradient ) const { - size_t cellIdx = cvf::UNDEFINED_SIZE_T; if ( ( m_mainGrid != nullptr ) && m_resultAccessor.notNull() ) { - cellIdx = m_mainGrid->findReservoirCellIndexFromPoint( position ); - - // adjust cell index to be on correct side of fault - if ( auto search = m_cellIndexAdjustment.find( cellIdx ); search != m_cellIndexAdjustment.end() ) - { - cellIdx = search->second; - } + auto cellIdx = findAdjustedCellIndex( position, m_mainGrid, m_cellIndexAdjustment ); if ( ( cellIdx != cvf::UNDEFINED_SIZE_T ) ) { @@ -106,7 +119,7 @@ double RimFaultReactivationDataAccess::porePressureAtPosition( const cvf::Vec3d& //-------------------------------------------------------------------------------------------------- double RimFaultReactivationDataAccess::calculatePorePressure( double depth, double gradient ) { - return gradient * 9.81 * depth * 1000; + return gradient * 9.81 * depth * 1000.0; } //-------------------------------------------------------------------------------------------------- @@ -116,3 +129,27 @@ size_t RimFaultReactivationDataAccess::timeStepIndex() const { return m_timeStepIndex; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFaultReactivationDataAccess::elementHasValidData( std::vector elementCorners ) const +{ + int nValid = 0; + for ( auto& p : elementCorners ) + { + auto cellIdx = findAdjustedCellIndex( p, m_mainGrid, m_cellIndexAdjustment ); + + if ( ( cellIdx != cvf::UNDEFINED_SIZE_T ) ) + { + double value = m_resultAccessor->cellScalar( cellIdx ); + if ( !std::isinf( value ) ) + { + nValid++; + } + } + } + + // if more than half of the nodes have valid data, we're ok + return nValid > 4; +} diff --git a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationDataAccess.h b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationDataAccess.h index df57671159..9ae70d04a6 100644 --- a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationDataAccess.h +++ b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationDataAccess.h @@ -22,6 +22,7 @@ #include "cvfVector3.h" #include +#include class RimEclipseCase; class RigEclipseCaseData; @@ -40,12 +41,17 @@ public: void useCellIndexAdjustment( std::map adjustments ); - double porePressureAtPosition( const cvf::Vec3d& position, double defaultPorePressureGradient ); + double porePressureAtPosition( const cvf::Vec3d& position, double defaultPorePressureGradient ) const; size_t timeStepIndex() const; + static size_t + findAdjustedCellIndex( const cvf::Vec3d& position, const RigMainGrid* grid, const std::map& cellIndexAdjustmentMap ); + + bool elementHasValidData( std::vector elementCorners ) const; + protected: - double calculatePorePressure( double depth, double gradient ); + static double calculatePorePressure( double depth, double gradient ); private: RimEclipseCase* m_case; diff --git a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationEnums.h b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationEnums.h new file mode 100644 index 0000000000..f2d49a15bf --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationEnums.h @@ -0,0 +1,61 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2023 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +namespace RimFaultReactivation +{ + +enum class ModelParts +{ + HiPart1, + MidPart1, + LowPart1, + HiPart2, + MidPart2, + LowPart2 +}; + +enum class GridPart +{ + PART1, + PART2 +}; + +enum class BorderSurface +{ + UpperSurface, + FaultSurface, + LowerSurface +}; + +enum class Boundary +{ + FarSide, + Bottom +}; + +enum class ElementSets +{ + OverBurden, + UnderBurden, + Reservoir, + IntraReservoir +}; + +} // namespace RimFaultReactivation diff --git a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.cpp b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.cpp index 349ae7acfa..e808411d5d 100644 --- a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.cpp +++ b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.cpp @@ -24,6 +24,7 @@ #include "RiaQDateTimeTools.h" #include "RifJsonEncodeDecode.h" +#include "RifParameterXmlReader.h" #include "RigBasicPlane.h" #include "RigFaultReactivationModel.h" @@ -37,12 +38,14 @@ #include "RivFaultReactivationModelPartMgr.h" #include "Rim3dView.h" +#include "RimDoubleParameter.h" #include "RimEclipseCase.h" #include "RimEclipseView.h" #include "RimFaultInView.h" #include "RimFaultInViewCollection.h" #include "RimFaultReactivationDataAccess.h" #include "RimFaultReactivationTools.h" +#include "RimParameterGroup.h" #include "RimPolylineTarget.h" #include "RimTimeStepFilter.h" #include "RimTools.h" @@ -104,6 +107,8 @@ RimFaultReactivationModel::RimFaultReactivationModel() CAF_PDM_InitField( &m_numberOfCellsVertMid, "NumberOfCellsVertMid", 20, "Vertical Number of Cells, Middle Part" ); CAF_PDM_InitField( &m_numberOfCellsVertLow, "NumberOfCellsVertLow", 20, "Vertical Number of Cells, Lower Part" ); + CAF_PDM_InitField( &m_useLocalCoordinates, "UseLocalCoordinates", false, "Export Using Local Coordinates" ); + // Time Step Selection CAF_PDM_InitFieldNoDefault( &m_timeStepFilter, "TimeStepFilter", "Available Time Steps" ); CAF_PDM_InitFieldNoDefault( &m_selectedTimeSteps, "TimeSteps", "Select Time Steps" ); @@ -113,11 +118,13 @@ RimFaultReactivationModel::RimFaultReactivationModel() CAF_PDM_InitFieldNoDefault( &m_targets, "Targets", "Targets" ); m_targets.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() ); m_targets.uiCapability()->setUiTreeChildrenHidden( true ); + m_targets.uiCapability()->setUiTreeHidden( true ); m_targets.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP ); m_targets.uiCapability()->setCustomContextMenuEnabled( false ); + CAF_PDM_InitFieldNoDefault( &m_materialParameters, "MaterialParameters", "Materials", ":/Bullet.png" ); + this->setUi3dEditorTypeName( RicPolyline3dEditor::uiEditorTypeName() ); - this->uiCapability()->setUiTreeChildrenHidden( true ); setDeletable( true ); @@ -140,6 +147,23 @@ void RimFaultReactivationModel::initAfterRead() updateVisualization(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFaultReactivationModel::initSettings( QString& outErrmsg ) +{ + RifParameterXmlReader basicreader( RiaPreferencesGeoMech::current()->geomechFRMDefaultXML() ); + if ( !basicreader.parseFile( outErrmsg ) ) return false; + + m_materialParameters.deleteChildren(); + for ( auto group : basicreader.parameterGroups() ) + { + m_materialParameters.push_back( group ); + } + + return true; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -297,7 +321,19 @@ void RimFaultReactivationModel::updateVisualization() m_numberOfCellsVertLow ); m_modelPlane->setThickness( m_modelThickness ); - m_modelPlane->updateRects(); + // set up transform to local coordinate system + { + auto [xVec, yVec] = localCoordSysNormalsXY(); + cvf::Mat4d transform = cvf::Mat4d::fromCoordSystemAxes( &xVec, &yVec, &cvf::Vec3d::Z_AXIS ); + cvf::Vec3d center = m_targets[0]->targetPointXYZ() * -1.0; + center.z() = 0.0; + center.transformPoint( transform ); + transform.setTranslation( center ); + m_modelPlane->setLocalCoordTransformation( transform ); + m_modelPlane->setUseLocalCoordinates( m_useLocalCoordinates ); + } + + m_modelPlane->updateGeometry(); view->scheduleCreateDisplayModelAndRedraw(); } @@ -401,6 +437,13 @@ std::pair RimFaultReactivationModel::localCoordSysNormal cvf::Vec3d yNormal = m_modelPlane->normal(); cvf::Vec3d xNormal = yNormal ^ cvf::Vec3d::Z_AXIS; + xNormal.z() = 0.0; + yNormal.z() = 0.0; + xNormal.normalize(); + yNormal.normalize(); + + yNormal = xNormal ^ cvf::Vec3d::Z_AXIS; + return std::make_pair( xNormal, yNormal ); } @@ -438,6 +481,7 @@ void RimFaultReactivationModel::defineUiOrdering( QString uiConfigName, caf::Pdm gridModelGrp->add( &m_numberOfCellsVertUp ); gridModelGrp->add( &m_numberOfCellsVertMid ); gridModelGrp->add( &m_numberOfCellsVertLow ); + gridModelGrp->add( &m_useLocalCoordinates ); auto timeStepGrp = uiOrdering.addNewGroup( "Time Steps" ); timeStepGrp->add( &m_timeStepFilter ); @@ -560,16 +604,6 @@ std::vector RimFaultReactivationModel::selectedTimeSteps() const return dates; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimFaultReactivationModel::isFirstTimeStepsSelected() const -{ - if ( m_availableTimeSteps.empty() || selectedTimeSteps().empty() ) return false; - - return m_availableTimeSteps.front() == selectedTimeSteps().front(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -660,6 +694,7 @@ bool RimFaultReactivationModel::extractAndExportModelData() if ( !exportModelSettings() ) return false; auto eCase = eclipseCase(); + if ( eCase == nullptr ) return false; // get the selected time step indexes std::vector selectedTimeStepIndexes; @@ -671,6 +706,17 @@ bool RimFaultReactivationModel::extractAndExportModelData() selectedTimeStepIndexes.push_back( idx - m_availableTimeSteps.begin() ); } + auto grid = eCase->mainGrid(); + + // generate cell index mappings for cells that ends up at the wrong side of the fault + model()->generateCellIndexMapping( grid ); + + // generate element sets for the various data parts of the model + { + RimFaultReactivationDataAccess dataAccess( eCase, 0 ); + model()->generateElementSets( &dataAccess, grid ); + } + // extract data for each timestep size_t outputTimeStepIndex = 0; for ( auto timeStepIdx : selectedTimeStepIndexes ) @@ -681,3 +727,30 @@ bool RimFaultReactivationModel::extractAndExportModelData() return true; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::array RimFaultReactivationModel::materialParameters( ElementSets elementSet ) +{ + std::array retVal = { 0.0, 0.0, 0.0 }; + static std::map groupMap = { { ElementSets::OverBurden, "material_overburden" }, + { ElementSets::Reservoir, "material_reservoir" }, + { ElementSets::IntraReservoir, "material_intrareservoir" }, + { ElementSets::UnderBurden, "material_underburden" } }; + + auto keyName = QString::fromStdString( groupMap[elementSet] ); + + for ( auto& grp : m_materialParameters ) + { + if ( grp->name() != keyName ) continue; + + retVal[0] = grp->parameterDoubleValue( "youngs_modulus", 0.0 ); + retVal[1] = grp->parameterDoubleValue( "poissons_number", 0.0 ); + retVal[2] = grp->parameterDoubleValue( "density", 0.0 ); + + break; + } + + return retVal; +} diff --git a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.h b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.h index 95da2370e2..bca610e1d6 100644 --- a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.h +++ b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.h @@ -18,6 +18,7 @@ #pragma once #include "RimCheckableNamedObject.h" +#include "RimFaultReactivationEnums.h" #include "RimPolylinePickerInterface.h" #include "RimPolylinesDataInterface.h" #include "RimTimeStepFilter.h" @@ -42,6 +43,7 @@ class RicPolylineTargetsPickEventHandler; class RimEclipseCase; class RimFaultInView; +class RimParameterGroup; class RimPolylineTarget; class RimTimeStepFilter; class RivFaultReactivationModelPartMgr; @@ -59,11 +61,14 @@ class RimFaultReactivationModel : public RimCheckableNamedObject, public RimPoly CAF_PDM_HEADER_INIT; using TimeStepFilterEnum = caf::AppEnum; + using ElementSets = RimFaultReactivation::ElementSets; public: RimFaultReactivationModel(); ~RimFaultReactivationModel() override; + bool initSettings( QString& outErrmsg ); + QString userDescription(); void setUserDescription( QString description ); @@ -102,7 +107,8 @@ public: void setBaseDir( QString path ); std::vector selectedTimeSteps() const; - bool isFirstTimeStepsSelected() const; + + std::array materialParameters( ElementSets elementSet ); QStringList commandParameters() const; @@ -157,6 +163,7 @@ private: caf::PdmField m_numberOfCellsVertUp; caf::PdmField m_numberOfCellsVertMid; caf::PdmField m_numberOfCellsVertLow; + caf::PdmField m_useLocalCoordinates; cvf::ref m_faultPlane; cvf::ref m_modelPlane; @@ -164,5 +171,7 @@ private: caf::PdmField m_timeStepFilter; caf::PdmField> m_selectedTimeSteps; + caf::PdmChildArrayField m_materialParameters; + std::vector m_availableTimeSteps; }; diff --git a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModelCollection.cpp b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModelCollection.cpp index 4ba6a0870e..acf2f78012 100644 --- a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModelCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModelCollection.cpp @@ -46,6 +46,7 @@ RimFaultReactivationModelCollection::RimFaultReactivationModelCollection() CAF_PDM_InitFieldNoDefault( &m_models, "FaultReactivationModels", "Models" ); m_models.uiCapability()->setUiTreeHidden( true ); + m_models.uiCapability()->setUiHidden( true ); setName( "Fault Reactivation Models" ); } @@ -60,8 +61,11 @@ RimFaultReactivationModelCollection::~RimFaultReactivationModelCollection() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimFaultReactivationModel* - RimFaultReactivationModelCollection::addNewModel( RimFaultInView* fault, cvf::Vec3d target1, cvf::Vec3d target2, QString baseDir ) +RimFaultReactivationModel* RimFaultReactivationModelCollection::addNewModel( RimFaultInView* fault, + cvf::Vec3d target1, + cvf::Vec3d target2, + QString baseDir, + QString& outErrMsg ) { auto newModel = new RimFaultReactivationModel(); newModel->setFault( fault ); @@ -69,11 +73,20 @@ RimFaultReactivationModel* newModel->setUserDescription( fault->name() ); newModel->setTargets( target1, target2 ); + QString errmsg; + if ( !newModel->initSettings( errmsg ) ) + { + delete newModel; + outErrMsg = "Unable to load default parameters from the Fault Reactivation Model default parameter XML file:\n" + errmsg; + return nullptr; + } + m_models.push_back( newModel ); + updateConnectedEditors(); + newModel->updateVisualization(); - // updateView(); return newModel; } diff --git a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModelCollection.h b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModelCollection.h index 1be362fa81..5df7ae7bb8 100644 --- a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModelCollection.h +++ b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModelCollection.h @@ -50,7 +50,7 @@ public: RimFaultReactivationModelCollection(); ~RimFaultReactivationModelCollection() override; - RimFaultReactivationModel* addNewModel( RimFaultInView* fault, cvf::Vec3d target1, cvf::Vec3d target2, QString baseDir ); + RimFaultReactivationModel* addNewModel( RimFaultInView* fault, cvf::Vec3d target1, cvf::Vec3d target2, QString baseDir, QString& errMsg ); bool empty(); int size(); diff --git a/ApplicationLibCode/ProjectDataModel/Parameters/RimParameterGroup.cpp b/ApplicationLibCode/ProjectDataModel/Parameters/RimParameterGroup.cpp index c406d39f3c..376b89d331 100644 --- a/ApplicationLibCode/ProjectDataModel/Parameters/RimParameterGroup.cpp +++ b/ApplicationLibCode/ProjectDataModel/Parameters/RimParameterGroup.cpp @@ -345,3 +345,13 @@ QVariant RimParameterGroup::parameterValue( QString name ) const } return QVariant(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimParameterGroup::parameterDoubleValue( QString name, double defaultValue ) const +{ + RimDoubleParameter* p = dynamic_cast( parameter( name ) ); + if ( p == nullptr ) return defaultValue; + return p->value(); +} diff --git a/ApplicationLibCode/ProjectDataModel/Parameters/RimParameterGroup.h b/ApplicationLibCode/ProjectDataModel/Parameters/RimParameterGroup.h index 07d5719467..acab7e45e8 100644 --- a/ApplicationLibCode/ProjectDataModel/Parameters/RimParameterGroup.h +++ b/ApplicationLibCode/ProjectDataModel/Parameters/RimParameterGroup.h @@ -69,6 +69,7 @@ public: RimGenericParameter* parameter( QString name ) const; QVariant parameterValue( QString name ) const; + double parameterDoubleValue( QString name, double defaultValue ) const; private: void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override; diff --git a/ApplicationLibCode/ReservoirDataModel/RigFaultReactivationModel.cpp b/ApplicationLibCode/ReservoirDataModel/RigFaultReactivationModel.cpp index 6167163316..be613392c2 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigFaultReactivationModel.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigFaultReactivationModel.cpp @@ -74,7 +74,7 @@ RigFaultReactivationModel::~RigFaultReactivationModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RigFaultReactivationModel::allModelParts() const +std::vector RigFaultReactivationModel::allModelParts() const { return { ModelParts::HiPart1, ModelParts::MidPart1, ModelParts::LowPart1, ModelParts::HiPart2, ModelParts::MidPart2, ModelParts::LowPart2 }; } @@ -82,7 +82,7 @@ std::vector RigFaultReactivationModel::al //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RigFaultReactivationModel::allGridParts() const +std::vector RigFaultReactivationModel::allGridParts() const { return { GridPart::PART1, GridPart::PART2 }; } @@ -196,6 +196,23 @@ void RigFaultReactivationModel::setThickness( double thickness ) reset(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFaultReactivationModel::setLocalCoordTransformation( cvf::Mat4d transform ) +{ + m_localCoordTransform = transform; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFaultReactivationModel::setUseLocalCoordinates( bool useLocalCoordinates ) +{ + m_3dparts[GridPart::PART1]->setUseLocalCoordinates( useLocalCoordinates ); + m_3dparts[GridPart::PART2]->setUseLocalCoordinates( useLocalCoordinates ); +} + //-------------------------------------------------------------------------------------------------- /// 7 /// 3----------|----------- 11 @@ -217,7 +234,7 @@ void RigFaultReactivationModel::setThickness( double thickness ) /// /// //-------------------------------------------------------------------------------------------------- -void RigFaultReactivationModel::updateRects() +void RigFaultReactivationModel::updateGeometry() { reset(); @@ -296,7 +313,7 @@ cvf::Vec3d RigFaultReactivationModel::normal() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RigFaultReactivationModel::rect( ModelParts part ) const +std::vector RigFaultReactivationModel::rect( RimFaultReactivation::ModelParts part ) const { return m_parts.at( part ).rect; } @@ -304,7 +321,7 @@ std::vector RigFaultReactivationModel::rect( ModelParts part ) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RigFaultReactivationModel::texture( ModelParts part ) const +cvf::ref RigFaultReactivationModel::texture( RimFaultReactivation::ModelParts part ) const { return m_parts.at( part ).texture; } @@ -312,7 +329,7 @@ cvf::ref RigFaultReactivationModel::texture( ModelParts part //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::vector>& RigFaultReactivationModel::meshLines( GridPart part ) const +const std::vector>& RigFaultReactivationModel::meshLines( RimFaultReactivation::GridPart part ) const { return m_3dparts.at( part )->meshLines(); } @@ -334,12 +351,15 @@ void RigFaultReactivationModel::generateGrids( cvf::Vec3dArray points ) m_cellCountVertMiddle, m_cellCountVertUpper, m_thickness ); + + m_3dparts[GridPart::PART1]->generateLocalNodes( m_localCoordTransform ); + m_3dparts[GridPart::PART2]->generateLocalNodes( m_localCoordTransform ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::shared_ptr RigFaultReactivationModel::grid( GridPart part ) const +std::shared_ptr RigFaultReactivationModel::grid( RimFaultReactivation::GridPart part ) const { return m_3dparts.at( part ); } @@ -355,3 +375,22 @@ void RigFaultReactivationModel::extractModelData( RimFaultReactivationDataAccess m_3dparts[part]->extractModelData( dataAccess, outputTimeStep ); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFaultReactivationModel::generateElementSets( const RimFaultReactivationDataAccess* dataAccess, const RigMainGrid* grid ) +{ + for ( auto part : allGridParts() ) + { + m_3dparts[part]->generateElementSets( dataAccess, grid ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFaultReactivationModel::generateCellIndexMapping( const RigMainGrid* grid ) +{ + m_cellIndexAdjustmentMap.clear(); +} diff --git a/ApplicationLibCode/ReservoirDataModel/RigFaultReactivationModel.h b/ApplicationLibCode/ReservoirDataModel/RigFaultReactivationModel.h index 072f3030b7..ca198f0d60 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigFaultReactivationModel.h +++ b/ApplicationLibCode/ReservoirDataModel/RigFaultReactivationModel.h @@ -18,8 +18,11 @@ #pragma once +#include "RimFaultReactivationEnums.h" + #include "cvfArray.h" #include "cvfColor3.h" +#include "cvfMatrix4.h" #include "cvfObject.h" #include "cvfPlane.h" #include "cvfTextureImage.h" @@ -30,6 +33,7 @@ #include class RigGriddedPart3d; +class RigMainGrid; class RimFaultReactivationDataAccess; class RigFRModelPart @@ -47,24 +51,9 @@ public: /// //================================================================================================== class RigFaultReactivationModel : public cvf::Object - { -public: - enum class ModelParts - { - HiPart1 = 0, - MidPart1, - LowPart1, - HiPart2, - MidPart2, - LowPart2 - }; - - enum class GridPart - { - PART1, - PART2 - }; + using ModelParts = RimFaultReactivation::ModelParts; + using GridPart = RimFaultReactivation::GridPart; public: RigFaultReactivationModel(); @@ -82,8 +71,10 @@ public: void setCellCounts( int horzPart1, int horzPart2, int vertUpper, int vertMiddle, int vertLower ); void setThickness( double thickness ); + void setLocalCoordTransformation( cvf::Mat4d transform ); + void setUseLocalCoordinates( bool useLocalCoordinates ); - void updateRects(); + void updateGeometry(); cvf::Vec3d normal() const; @@ -95,6 +86,9 @@ public: std::shared_ptr grid( GridPart part ) const; + void generateCellIndexMapping( const RigMainGrid* grid ); + void generateElementSets( const RimFaultReactivationDataAccess* dataAccess, const RigMainGrid* grid ); + void clearModelData(); void extractModelData( RimFaultReactivationDataAccess* dataAccess, size_t outputTimeStep ); @@ -128,4 +122,6 @@ private: std::map> m_3dparts; std::map> m_cellIndexAdjustmentMap; + + cvf::Mat4d m_localCoordTransform; }; diff --git a/ApplicationLibCode/ReservoirDataModel/RigGriddedPart3d.cpp b/ApplicationLibCode/ReservoirDataModel/RigGriddedPart3d.cpp index 38bc553954..b993656473 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigGriddedPart3d.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigGriddedPart3d.cpp @@ -18,15 +18,18 @@ #include "RigGriddedPart3d.h" +#include "RigMainGrid.h" + #include "RimFaultReactivationDataAccess.h" +#include "cvfBoundingBox.h" #include "cvfTextureImage.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigGriddedPart3d::RigGriddedPart3d( bool flipFrontBack ) - : m_flipFrontBack( flipFrontBack ) + : m_useLocalCoordinates( false ) { } @@ -46,8 +49,10 @@ void RigGriddedPart3d::reset() m_boundaryNodes.clear(); m_borderSurfaceElements.clear(); m_nodes.clear(); + m_localNodes.clear(); m_elementIndices.clear(); m_meshLines.clear(); + m_elementSets.clear(); clearModelData(); } @@ -101,15 +106,15 @@ void RigGriddedPart3d::generateGeometry( std::vector inputPoints, { reset(); - cvf::Vec3d step0to1 = stepVector( inputPoints[0], inputPoints[1], nVertCellsLower ); - cvf::Vec3d step1to2 = stepVector( inputPoints[1], inputPoints[2], nVertCellsMiddle ); - cvf::Vec3d step2to3 = stepVector( inputPoints[2], inputPoints[3], nVertCellsUpper ); + const cvf::Vec3d step0to1 = stepVector( inputPoints[0], inputPoints[1], nVertCellsLower ); + const cvf::Vec3d step1to2 = stepVector( inputPoints[1], inputPoints[2], nVertCellsMiddle ); + const cvf::Vec3d step2to3 = stepVector( inputPoints[2], inputPoints[3], nVertCellsUpper ); - cvf::Vec3d step4to5 = stepVector( inputPoints[4], inputPoints[5], nVertCellsLower ); - cvf::Vec3d step5to6 = stepVector( inputPoints[5], inputPoints[6], nVertCellsMiddle ); - cvf::Vec3d step6to7 = stepVector( inputPoints[6], inputPoints[7], nVertCellsUpper ); + const cvf::Vec3d step4to5 = stepVector( inputPoints[4], inputPoints[5], nVertCellsLower ); + const cvf::Vec3d step5to6 = stepVector( inputPoints[5], inputPoints[6], nVertCellsMiddle ); + const cvf::Vec3d step6to7 = stepVector( inputPoints[6], inputPoints[7], nVertCellsUpper ); - cvf::Vec3d step0to4 = stepVector( inputPoints[0], inputPoints[4], nHorzCells ); + const cvf::Vec3d step0to4 = stepVector( inputPoints[0], inputPoints[4], nHorzCells ); cvf::Vec3d tVec = step0to4 ^ step0to1; tVec.normalize(); @@ -123,13 +128,8 @@ void RigGriddedPart3d::generateGeometry( std::vector inputPoints, const std::vector firstSteps = { step0to1, step1to2, step2to3 }; const std::vector lastSteps = { step4to5, step5to6, step6to7 }; - const Boundary boundaryBack = m_flipFrontBack ? Boundary::Front : Boundary::Back; - const Boundary boundaryFront = m_flipFrontBack ? Boundary::Back : Boundary::Front; - // ** generate nodes - m_boundaryNodes[boundaryFront] = {}; - m_boundaryNodes[boundaryBack] = {}; m_boundaryNodes[Boundary::Bottom] = {}; m_boundaryNodes[Boundary::FarSide] = {}; @@ -160,14 +160,6 @@ void RigGriddedPart3d::generateGeometry( std::vector inputPoints, { m_boundaryNodes[Boundary::FarSide].push_back( nodeIndex ); } - if ( t == 0 ) - { - m_boundaryNodes[boundaryFront].push_back( nodeIndex ); - } - else if ( t == nThicknessCells ) - { - m_boundaryNodes[boundaryBack].push_back( nodeIndex ); - } } p += stepHorz; @@ -181,12 +173,10 @@ void RigGriddedPart3d::generateGeometry( std::vector inputPoints, m_elementIndices.resize( (size_t)( nVertCells * nHorzCells * nThicknessCells ) ); - m_borderSurfaceElements[BorderSurface::UpperSurface] = {}; - m_borderSurfaceElements[BorderSurface::FaultSurface] = {}; - m_borderSurfaceElements[BorderSurface::LowerSurface] = {}; + m_borderSurfaceElements[RimFaultReactivation::BorderSurface::UpperSurface] = {}; + m_borderSurfaceElements[RimFaultReactivation::BorderSurface::FaultSurface] = {}; + m_borderSurfaceElements[RimFaultReactivation::BorderSurface::LowerSurface] = {}; - m_boundaryElements[boundaryFront] = {}; - m_boundaryElements[boundaryBack] = {}; m_boundaryElements[Boundary::Bottom] = {}; m_boundaryElements[Boundary::FarSide] = {}; @@ -194,15 +184,15 @@ void RigGriddedPart3d::generateGeometry( std::vector inputPoints, int elementIdx = 0; layer = 0; - BorderSurface currentSurfaceRegion = BorderSurface::LowerSurface; + RimFaultReactivation::BorderSurface currentSurfaceRegion = RimFaultReactivation::BorderSurface::LowerSurface; const int nextLayerIdxOff = ( nHorzCells + 1 ) * ( nThicknessCells + 1 ); const int nThicknessOff = nThicknessCells + 1; for ( int v = 0; v < nVertCells; v++, layer++ ) { - if ( v >= nVertCellsLower ) currentSurfaceRegion = BorderSurface::FaultSurface; - if ( v >= nVertCellsLower + nVertCellsMiddle ) currentSurfaceRegion = BorderSurface::UpperSurface; + if ( v >= nVertCellsLower ) currentSurfaceRegion = RimFaultReactivation::BorderSurface::FaultSurface; + if ( v >= nVertCellsLower + nVertCellsMiddle ) currentSurfaceRegion = RimFaultReactivation::BorderSurface::UpperSurface; int i = layerIndexOffset; @@ -228,14 +218,6 @@ void RigGriddedPart3d::generateGeometry( std::vector inputPoints, { m_boundaryElements[Boundary::FarSide].push_back( elementIdx ); } - if ( t == 0 ) - { - m_boundaryElements[boundaryFront].push_back( elementIdx ); - } - else if ( t == ( nThicknessCells - 1 ) ) - { - m_boundaryElements[boundaryBack].push_back( elementIdx ); - } } i += nThicknessOff; } @@ -252,6 +234,13 @@ void RigGriddedPart3d::generateGeometry( std::vector inputPoints, generateMeshlines( { inputPoints[0], inputPoints[1], inputPoints[5], inputPoints[4] }, nHorzCells, nVertCellsLower ); generateMeshlines( { inputPoints[1], inputPoints[2], inputPoints[6], inputPoints[5] }, nHorzCells, nVertCellsMiddle ); generateMeshlines( { inputPoints[2], inputPoints[3], inputPoints[7], inputPoints[6] }, nHorzCells, nVertCellsUpper ); + + // store the reservoir part corners for later + m_reservoirRect.clear(); + for ( auto i : { 1, 2, 6, 5 } ) + { + m_reservoirRect.push_back( inputPoints[i] ); + } } //-------------------------------------------------------------------------------------------------- @@ -267,7 +256,7 @@ void RigGriddedPart3d::generateGeometry( std::vector inputPoints, /// /// Assumes 0->3 and 1->2 is parallel //-------------------------------------------------------------------------------------------------- -void RigGriddedPart3d::generateMeshlines( std::vector cornerPoints, int numHorzCells, int numVertCells ) +void RigGriddedPart3d::generateMeshlines( const std::vector& cornerPoints, int numHorzCells, int numVertCells ) { cvf::Vec3d step0to1 = stepVector( cornerPoints[0], cornerPoints[1], numVertCells ); cvf::Vec3d step0to3 = stepVector( cornerPoints[0], cornerPoints[3], numHorzCells ); @@ -300,13 +289,38 @@ void RigGriddedPart3d::generateMeshlines( std::vector cornerPoints, } //-------------------------------------------------------------------------------------------------- -/// +/// returns node in either global or local coords depending on m_useLocalCoordinates flag //-------------------------------------------------------------------------------------------------- const std::vector& RigGriddedPart3d::nodes() const { + if ( m_useLocalCoordinates ) return m_localNodes; return m_nodes; } +//-------------------------------------------------------------------------------------------------- +/// Always returns nodes in global coordinates +//-------------------------------------------------------------------------------------------------- +const std::vector& RigGriddedPart3d::globalNodes() const +{ + return m_nodes; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGriddedPart3d::setUseLocalCoordinates( bool useLocalCoordinates ) +{ + m_useLocalCoordinates = useLocalCoordinates; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigGriddedPart3d::useLocalCoordinates() const +{ + return m_useLocalCoordinates; +} + //-------------------------------------------------------------------------------------------------- /// Output elements will be of type HEX8 /// @@ -328,7 +342,7 @@ const std::vector>& RigGriddedPart3d::elementIndices() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::map>& RigGriddedPart3d::borderSurfaceElements() const +const std::map>& RigGriddedPart3d::borderSurfaceElements() const { return m_borderSurfaceElements; } @@ -344,7 +358,7 @@ const std::vector>& RigGriddedPart3d::meshLines() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::map>& RigGriddedPart3d::boundaryElements() const +const std::map>& RigGriddedPart3d::boundaryElements() const { return m_boundaryElements; } @@ -352,11 +366,19 @@ const std::map>& RigGridde //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::map>& RigGriddedPart3d::boundaryNodes() const +const std::map>& RigGriddedPart3d::boundaryNodes() const { return m_boundaryNodes; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::map>& RigGriddedPart3d::elementSets() const +{ + return m_elementSets; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -382,3 +404,125 @@ void RigGriddedPart3d::extractModelData( RimFaultReactivationDataAccess* dataAcc m_nodePorePressure[outputTimeStep].push_back( pressure ); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair RigGriddedPart3d::reservoirZTopBottom( const RigMainGrid* grid ) const +{ + cvf::BoundingBox resBb; + for ( const auto& p : m_reservoirRect ) + { + resBb.add( p ); + } + std::vector intersectingCells; + grid->findIntersectingCells( resBb, &intersectingCells ); + + resBb.reset(); + for ( auto cellIdx : intersectingCells ) + { + resBb.add( grid->cell( cellIdx ).boundingBox() ); + } + + auto maxZ = resBb.max().z(); + auto minZ = resBb.min().z(); + + return std::make_pair( maxZ, minZ ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGriddedPart3d::generateElementSets( const RimFaultReactivationDataAccess* dataAccess, const RigMainGrid* grid ) +{ + m_elementSets[ElementSets::OverBurden] = {}; + m_elementSets[ElementSets::Reservoir] = {}; + m_elementSets[ElementSets::IntraReservoir] = {}; + m_elementSets[ElementSets::UnderBurden] = {}; + + auto [topResZ, bottomResZ] = reservoirZTopBottom( grid ); + + for ( unsigned int i = 0; i < m_elementIndices.size(); i++ ) + { + auto corners = elementCorners( i ); + + if ( dataAccess->elementHasValidData( corners ) ) + { + m_elementSets[ElementSets::Reservoir].push_back( i ); + } + else + { + if ( elementIsAboveReservoir( corners, topResZ ) ) + { + m_elementSets[ElementSets::OverBurden].push_back( i ); + } + else if ( elementIsBelowReservoir( corners, bottomResZ ) ) + { + m_elementSets[ElementSets::UnderBurden].push_back( i ); + } + else + { + m_elementSets[ElementSets::IntraReservoir].push_back( i ); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGriddedPart3d::generateLocalNodes( const cvf::Mat4d transform ) +{ + m_localNodes.clear(); + + for ( auto& node : m_nodes ) + { + m_localNodes.push_back( node.getTransformedPoint( transform ) ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigGriddedPart3d::elementCorners( size_t elementIndex ) const +{ + if ( elementIndex >= m_elementIndices.size() ) return {}; + + std::vector corners; + + for ( auto nodeIdx : m_elementIndices[elementIndex] ) + { + if ( nodeIdx >= m_nodes.size() ) continue; + corners.push_back( m_nodes[nodeIdx] ); + } + + return corners; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigGriddedPart3d::elementIsAboveReservoir( const std::vector& cornerPoints, double threshold ) const +{ + int nValid = 0; + for ( auto& p : cornerPoints ) + { + if ( p.z() > threshold ) nValid++; + } + + return nValid > 4; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigGriddedPart3d::elementIsBelowReservoir( const std::vector& cornerPoints, double threshold ) const +{ + int nValid = 0; + for ( auto& p : cornerPoints ) + { + if ( p.z() < threshold ) nValid++; + } + + return nValid > 4; +} diff --git a/ApplicationLibCode/ReservoirDataModel/RigGriddedPart3d.h b/ApplicationLibCode/ReservoirDataModel/RigGriddedPart3d.h index 61b5c36fde..37861734ef 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigGriddedPart3d.h +++ b/ApplicationLibCode/ReservoirDataModel/RigGriddedPart3d.h @@ -18,12 +18,16 @@ #pragma once +#include "RimFaultReactivationEnums.h" + +#include "cvfMatrix4.h" #include "cvfObject.h" #include "cvfVector3.h" #include #include +class RigMainGrid; class RimFaultReactivationDataAccess; //================================================================================================== @@ -32,21 +36,8 @@ class RimFaultReactivationDataAccess; //================================================================================================== class RigGriddedPart3d : public cvf::Object { -public: - enum class BorderSurface - { - UpperSurface = 0, - FaultSurface, - LowerSurface - }; - - enum class Boundary - { - Front = 0, - Back, - FarSide, - Bottom - }; + using ElementSets = RimFaultReactivation::ElementSets; + using Boundary = RimFaultReactivation::Boundary; public: RigGriddedPart3d( bool flipFrontBack ); @@ -62,32 +53,51 @@ public: int nVertCellsUpper, double thickness ); + void generateElementSets( const RimFaultReactivationDataAccess* dataAccess, const RigMainGrid* grid ); + void generateLocalNodes( const cvf::Mat4d transform ); void extractModelData( RimFaultReactivationDataAccess* dataAccess, size_t outputTimeStep ); - const std::vector& nodes() const; - const std::vector>& elementIndices() const; - const std::map>& borderSurfaceElements() const; - const std::vector>& meshLines() const; + const std::vector& nodes() const; + const std::vector& globalNodes() const; + void setUseLocalCoordinates( bool useLocalCoordinates ); + bool useLocalCoordinates() const; + + const std::vector>& elementIndices() const; + const std::map>& borderSurfaceElements() const; + + const std::vector>& meshLines() const; + std::vector elementCorners( size_t elementIndex ) const; const std::map>& boundaryElements() const; const std::map>& boundaryNodes() const; + const std::map>& elementSets() const; + const std::vector& nodePorePressure( size_t outputTimeStep ) const; protected: cvf::Vec3d stepVector( cvf::Vec3d start, cvf::Vec3d stop, int nSteps ); - void generateMeshlines( std::vector cornerPoints, int numHorzCells, int numVertCells ); + void generateMeshlines( const std::vector& cornerPoints, int numHorzCells, int numVertCells ); + + bool elementIsAboveReservoir( const std::vector& cornerPoints, double threshold ) const; + bool elementIsBelowReservoir( const std::vector& cornerPoints, double threshold ) const; + + std::pair reservoirZTopBottom( const RigMainGrid* grid ) const; private: - bool m_flipFrontBack; + bool m_useLocalCoordinates; - std::vector m_nodes; - std::vector> m_elementIndices; - std::map> m_borderSurfaceElements; - std::vector> m_meshLines; - std::map> m_boundaryElements; - std::map> m_boundaryNodes; + std::vector m_nodes; + std::vector m_localNodes; + std::vector> m_elementIndices; + std::map> m_borderSurfaceElements; + std::vector> m_meshLines; + std::map> m_boundaryElements; + std::map> m_boundaryNodes; + std::map> m_elementSets; std::vector> m_nodePorePressure; const std::vector m_emptyData; + + std::vector m_reservoirRect; };