diff --git a/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.cpp b/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.cpp index e9cff297fa..cc4cf62bed 100644 --- a/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.cpp +++ b/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.cpp @@ -74,11 +74,14 @@ std::pair RifFaultReactivationModelExporter::exportToStream( { RimFaultReactivation::ElementSets::UnderBurden, "UNDERBURDEN" }, }; - double faultFriction = 0.0; - bool useGridVoidRatio = rimModel.useGridVoidRatio(); - bool useGridPorePressure = rimModel.useGridPorePressure(); - bool useGridTemperature = rimModel.useGridTemperature(); - auto dataAccess = rimModel.dataAccess(); + double faultFriction = 0.0; + bool useGridVoidRatio = rimModel.useGridVoidRatio(); + bool useGridPorePressure = rimModel.useGridPorePressure(); + bool useGridTemperature = rimModel.useGridTemperature(); + bool useGridDensity = rimModel.useGridDensity(); + bool useGridElasticProperties = rimModel.useGridElasticProperties(); + + auto dataAccess = rimModel.dataAccess(); auto model = rimModel.model(); CAF_ASSERT( !model.isNull() ); @@ -87,7 +90,10 @@ std::pair RifFaultReactivationModelExporter::exportToStream( [&]() { return printHeading( stream, applicationNameAndVersion ); }, [&]() { return printParts( stream, *model, partNames, borders, faces, boundaries, materialNames ); }, [&]() { return printAssembly( stream, *model, partNames, rimModel.localCoordSysNormalsXY() ); }, - [&]() { return printMaterials( stream, rimModel, materialNames ); }, + [&]() + { + return printMaterials( stream, rimModel, materialNames, *dataAccess, exportDirectory, partNames, useGridDensity, useGridElasticProperties ); + }, [&]() { return printInteractionProperties( stream, faultFriction ); }, [&]() { return printBoundaryConditions( stream, *model, partNames, boundaries ); }, [&]() { return printPredefinedFields( stream, *model, *dataAccess, exportDirectory, partNames, useGridVoidRatio ); }, @@ -279,7 +285,12 @@ std::pair std::pair RifFaultReactivationModelExporter::printMaterials( std::ostream& stream, const RimFaultReactivationModel& rimModel, - const std::map& materialNames ) + const std::map& materialNames, + const RimFaultReactivationDataAccess& dataAccess, + const std::string& exportDirectory, + const std::map& partNames, + bool densityFromGrid, + bool elasticPropertiesFromGrid ) { // MATERIALS PART struct Material @@ -320,15 +331,74 @@ std::pair { RifInpExportTools::printHeading( stream, "Material, name=" + mat.name ); RifInpExportTools::printHeading( stream, "Density" ); - RifInpExportTools::printNumber( stream, mat.density ); + if ( densityFromGrid ) + { + RifInpExportTools::printLine( stream, "DENSITY" ); + } + else + { + RifInpExportTools::printNumber( stream, mat.density ); + } RifInpExportTools::printHeading( stream, "Elastic" ); - RifInpExportTools::printNumbers( stream, { mat.youngsModulus, mat.poissonNumber } ); + if ( elasticPropertiesFromGrid ) + { + RifInpExportTools::printLine( stream, "ELASTICS" ); + } + else + { + RifInpExportTools::printNumbers( stream, { mat.youngsModulus, mat.poissonNumber } ); + } RifInpExportTools::printHeading( stream, "Permeability, specific=1." ); RifInpExportTools::printNumbers( stream, { mat.permeability1, mat.permeability2 } ); } + if ( densityFromGrid ) + { + // Export the density to a separate inp file + std::string tableName = "DENSITY"; + std::string fileName = tableName + ".inp"; + + std::string filePath = createFilePath( exportDirectory, fileName ); + + auto model = rimModel.model(); + bool isOk = writePropertiesToFile( *model, + dataAccess, + { RimFaultReactivation::Property::Density }, + { "DENSITY" }, + 0, + filePath, + partNames, + tableName, + ", 1." ); + if ( !isOk ) return { false, "Failed to create density file." }; + + RifInpExportTools::printHeading( stream, "INCLUDE, input=" + fileName ); + } + + if ( elasticPropertiesFromGrid ) + { + // Export the elastic properties to a separate inp file + std::string tableName = "ELASTICS"; + std::string fileName = tableName + ".inp"; + std::string filePath = createFilePath( exportDirectory, fileName ); + + auto model = rimModel.model(); + bool isOk = writePropertiesToFile( *model, + dataAccess, + { RimFaultReactivation::Property::YoungsModulus, RimFaultReactivation::Property::PoissonsRatio }, + { "MODULUS", "RATIO" }, + 0, + filePath, + partNames, + tableName, + ", 2." ); + if ( !isOk ) return { false, "Failed to create elastic properties file." }; + + RifInpExportTools::printHeading( stream, "INCLUDE, input=" + fileName ); + } + return { true, "" }; } @@ -510,7 +580,7 @@ std::pair RifFaultReactivationModelExporter::printSteps( std: { RifInpExportTools::printSectionComment( stream, "TEMPERATURE" ); - // Export the pore pressure to a separate inp file for each step + // Export the temperature to a separate inp file for each step std::string fileName = createFileName( "TEMPERATURE", stepName ); std::string filePath = createFilePath( exportDirectory, fileName ); @@ -568,6 +638,57 @@ bool RifFaultReactivationModelExporter::writePropertyToFile( const RigFaultReact return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifFaultReactivationModelExporter::writePropertiesToFile( const RigFaultReactivationModel& model, + const RimFaultReactivationDataAccess& dataAccess, + const std::vector& properties, + const std::vector& propertyNames, + size_t outputTimeStep, + const std::string& filePath, + const std::map& partNames, + const std::string& tableName, + const std::string& heading ) +{ + std::ofstream stream( filePath ); + if ( !stream.good() ) return false; + + RifInpExportTools::printHeading( stream, "Distribution Table, name=" + tableName + "_Table" ); + std::string propertyNamesLine; + for ( size_t i = 0; i < propertyNames.size(); i++ ) + { + propertyNamesLine += propertyNames[i]; + if ( i != propertyNames.size() - 1 ) propertyNamesLine += ", "; + } + RifInpExportTools::printLine( stream, propertyNamesLine ); + + RifInpExportTools::printHeading( stream, "Distribution, name=" + tableName + ", location=ELEMENT, Table=" + tableName + "_Table" ); + + RifInpExportTools::printLine( stream, heading ); + + for ( auto [part, partName] : partNames ) + { + auto grid = model.grid( part ); + + const std::vector>& elementIndices = grid->elementIndices(); + for ( size_t i = 0; i < elementIndices.size(); i++ ) + { + std::string line = partName + "." + std::to_string( i + 1 ); + for ( auto property : properties ) + { + const std::vector values = dataAccess.propertyValues( part, property, outputTimeStep ); + if ( values.size() != elementIndices.size() ) return false; + + line += ", " + std::to_string( values[i] ); + } + RifInpExportTools::printLine( stream, line ); + } + } + + return true; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.h b/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.h index 70d5ceecaf..ff65573fe2 100644 --- a/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.h +++ b/ApplicationLibCode/FileInterface/RifFaultReactivationModelExporter.h @@ -56,7 +56,12 @@ private: static std::pair printMaterials( std::ostream& stream, const RimFaultReactivationModel& rimModel, - const std::map& materialNames ); + const std::map& materialNames, + const RimFaultReactivationDataAccess& dataAccess, + const std::string& exportDirectory, + const std::map& partNames, + bool densityFromGrid, + bool elasticPropertiesFromGrid ); static std::pair printInteractionProperties( std::ostream& stream, double faultFriction ); static std::pair printBoundaryConditions( std::ostream& stream, @@ -91,6 +96,16 @@ private: const std::map& partNames, const std::string& additionalData ); + static bool writePropertiesToFile( const RigFaultReactivationModel& model, + const RimFaultReactivationDataAccess& dataAccess, + const std::vector& properties, + const std::vector& propertyNames, + size_t outputTimeStep, + const std::string& filePath, + const std::map& partNames, + const std::string& tableName, + const std::string& heading ); + static std::string createFileName( const std::string& title, const std::string& stepName ); static std::string createFilePath( const std::string& dir, const std::string& fileName ); diff --git a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationDataAccess.cpp b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationDataAccess.cpp index 9a4e1da77d..e3fc59b265 100644 --- a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationDataAccess.cpp +++ b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationDataAccess.cpp @@ -22,6 +22,7 @@ #include "RiaPorosityModel.h" #include "RigCaseCellResultsData.h" +#include "RigCaseToCaseCellMapperTools.h" #include "RigEclipseCaseData.h" #include "RigEclipseResultAddress.h" #include "RigFault.h" @@ -99,6 +100,10 @@ std::vector RimFaultReactivationDataAccess::extractModelData( const RigF RimFaultReactivation::Property property, size_t timeStep ) { + std::set nodeProperties = { RimFaultReactivation::Property::PorePressure, + RimFaultReactivation::Property::VoidRatio, + RimFaultReactivation::Property::Temperature }; + std::shared_ptr accessor = getAccessor( property ); if ( accessor ) { @@ -107,11 +112,27 @@ std::vector RimFaultReactivationDataAccess::extractModelData( const RigF auto grid = model.grid( gridPart ); std::vector values; - for ( auto& node : grid->globalNodes() ) + + if ( nodeProperties.contains( property ) ) { - double value = accessor->valueAtPosition( node ); - values.push_back( value ); + for ( auto& node : grid->globalNodes() ) + { + double value = accessor->valueAtPosition( node ); + values.push_back( value ); + } } + else + { + size_t numElements = grid->elementIndices().size(); + for ( size_t elementIndex = 0; elementIndex < numElements; elementIndex++ ) + { + std::vector corners = grid->elementCorners( elementIndex ); + cvf::Vec3d position = RigCaseToCaseCellMapperTools::calculateCellCenter( corners.data() ); + double value = accessor->valueAtPosition( position ); + values.push_back( value ); + } + } + return values; } diff --git a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.cpp b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.cpp index 9ee277d9dc..44f6342574 100644 --- a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.cpp +++ b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.cpp @@ -118,6 +118,8 @@ RimFaultReactivationModel::RimFaultReactivationModel() CAF_PDM_InitField( &m_useGridPorePressure, "UseGridPorePressure", true, "Use Grid Pore Pressure" ); CAF_PDM_InitField( &m_useGridVoidRatio, "UseGridVoidRatio", true, "Use Grid Void Ratio" ); CAF_PDM_InitField( &m_useGridTemperature, "UseGridTemperature", true, "Use Grid Temperature" ); + CAF_PDM_InitField( &m_useGridDensity, "UseGridDensity", true, "Use Grid Density" ); + CAF_PDM_InitField( &m_useGridElasticProperties, "UseGridElasticProperties", true, "Use Grid Elastic Properties" ); CAF_PDM_InitFieldNoDefault( &m_targets, "Targets", "Targets" ); m_targets.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() ); @@ -500,6 +502,8 @@ void RimFaultReactivationModel::defineUiOrdering( QString uiConfigName, caf::Pdm propertiesGrp->add( &m_useGridPorePressure ); propertiesGrp->add( &m_useGridVoidRatio ); propertiesGrp->add( &m_useGridTemperature ); + propertiesGrp->add( &m_useGridDensity ); + propertiesGrp->add( &m_useGridElasticProperties ); auto appModelGrp = modelGrp->addNewGroup( "Appearance" ); appModelGrp->add( &m_modelPart1Color ); @@ -796,3 +800,19 @@ bool RimFaultReactivationModel::useGridTemperature() const { return m_useGridTemperature(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFaultReactivationModel::useGridDensity() const +{ + return m_useGridDensity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFaultReactivationModel::useGridElasticProperties() const +{ + return m_useGridElasticProperties(); +} diff --git a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.h b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.h index 732d6441a9..43c2a73f51 100644 --- a/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.h +++ b/ApplicationLibCode/ProjectDataModel/Faults/RimFaultReactivationModel.h @@ -128,6 +128,8 @@ public: bool useGridVoidRatio() const; bool useGridPorePressure() const; bool useGridTemperature() const; + bool useGridDensity() const; + bool useGridElasticProperties() const; protected: caf::PdmFieldHandle* userDescriptionField() override; @@ -181,6 +183,8 @@ private: caf::PdmField m_useGridPorePressure; caf::PdmField m_useGridVoidRatio; caf::PdmField m_useGridTemperature; + caf::PdmField m_useGridDensity; + caf::PdmField m_useGridElasticProperties; cvf::ref m_faultPlane; cvf::ref m_modelPlane;