diff --git a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp index 726b090278..e66732370e 100644 --- a/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp +++ b/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp @@ -36,6 +36,7 @@ #include "RicWellPathFractureTextReportFeatureImpl.h" #include "RifTextDataTableFormatter.h" +#include "RifThermalToStimPlanFractureXmlOutput.h" #include "RigActiveCellInfo.h" #include "RigCaseCellResultsData.h" @@ -60,6 +61,7 @@ #include "RimPerforationInterval.h" #include "RimProject.h" #include "RimSimWellInView.h" +#include "RimThermalFractureTemplate.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" #include "RimWellPathCompletions.h" @@ -139,6 +141,29 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions( const std::v fractureTransmissibilityExportInformationStream = std::make_unique( &fractureTransmissibilityExportInformationFile ); } + + // Extra debugging for thermal fractures + if ( exportSettings.includeFractures() ) + { + for ( RimWellPath* wellPath : wellPaths ) + { + std::vector allWellPathLaterals = wellPath->allWellPathLaterals(); + for ( auto wellPathLateral : allWellPathLaterals ) + { + for ( auto& frac : wellPathLateral->fractureCollection()->activeFractures() ) + { + if ( RimThermalFractureTemplate* fractureTemplate = + dynamic_cast( frac->fractureTemplate() ) ) + { + QString name = frac->name(); + QString fractureXmlPath = QDir( exportSettings.folder ).absoluteFilePath( name + ".xml" ); + + RifThermalToStimPlanFractureXmlOutput::writeToFile( fractureTemplate, fractureXmlPath ); + } + } + } + } + } } std::vector completions; diff --git a/ApplicationLibCode/FileInterface/CMakeLists_files.cmake b/ApplicationLibCode/FileInterface/CMakeLists_files.cmake index 148c0e36e1..8e0da3e48f 100644 --- a/ApplicationLibCode/FileInterface/CMakeLists_files.cmake +++ b/ApplicationLibCode/FileInterface/CMakeLists_files.cmake @@ -88,6 +88,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommon.h ${CMAKE_CURRENT_LIST_DIR}/RifInpExportTools.h ${CMAKE_CURRENT_LIST_DIR}/RifFaultReactivationModelExporter.h + ${CMAKE_CURRENT_LIST_DIR}/RifThermalToStimPlanFractureXmlOutput.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -177,6 +178,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RifReaderOpmCommon.cpp ${CMAKE_CURRENT_LIST_DIR}/RifInpExportTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RifFaultReactivationModelExporter.cpp + ${CMAKE_CURRENT_LIST_DIR}/RifThermalToStimPlanFractureXmlOutput.cpp ) list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/FileInterface/RifThermalToStimPlanFractureXmlOutput.cpp b/ApplicationLibCode/FileInterface/RifThermalToStimPlanFractureXmlOutput.cpp new file mode 100644 index 0000000000..486881e813 --- /dev/null +++ b/ApplicationLibCode/FileInterface/RifThermalToStimPlanFractureXmlOutput.cpp @@ -0,0 +1,155 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RifThermalToStimPlanFractureXmlOutput.h" + +#include "RigFractureGrid.h" + +#include "RimThermalFractureTemplate.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifThermalToStimPlanFractureXmlOutput::writeToFile( RimThermalFractureTemplate* fractureTemplate, const QString& filepath ) +{ + CAF_ASSERT( fractureTemplate ); + + QFile data( filepath ); + if ( !data.open( QFile::WriteOnly | QFile::Truncate ) ) return false; + + // Can use a fake depths here: depths must be adjusted when importing + double fakeDepth = 1000.0; + cvf::cref fractureGrid = fractureTemplate->createFractureGrid( fakeDepth ); + if ( fractureGrid.isNull() ) return false; + + QTextStream stream( &data ); + appendHeaderToStream( stream ); + + appendGridDefinitionToStream( stream, *fractureGrid ); + + appendPropertiesToStream( stream, *fractureTemplate, *fractureGrid ); + + appendFooterToStream( stream ); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifThermalToStimPlanFractureXmlOutput::appendHeaderToStream( QTextStream& stream ) +{ + stream << "" << '\n' << "" << '\n'; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifThermalToStimPlanFractureXmlOutput::appendGridDefinitionToStream( QTextStream& stream, const RigFractureGrid& fractureGrid ) +{ + size_t xCount = fractureGrid.iCellCount(); + size_t yCount = fractureGrid.jCellCount(); + + stream << QString( "" ).arg( xCount ).arg( yCount ); + + std::vector xs; + for ( size_t i = 0; i < xCount; i++ ) + { + size_t idx = fractureGrid.getGlobalIndexFromIJ( i, 0 ); + auto fractureCell = fractureGrid.cellFromIndex( idx ); + xs.push_back( fractureCell.centerPosition().x() ); + } + + std::vector ys; + for ( size_t j = 0; j < yCount; j++ ) + { + size_t idx = fractureGrid.getGlobalIndexFromIJ( 0, j ); + auto fractureCell = fractureGrid.cellFromIndex( idx ); + ys.push_back( -fractureCell.centerPosition().y() ); + } + + appendDataVector( stream, "xs", xs ); + appendDataVector( stream, "ys", ys ); + + stream << "\n"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifThermalToStimPlanFractureXmlOutput::appendPropertiesToStream( QTextStream& stream, + const RimThermalFractureTemplate& fractureTemplate, + const RigFractureGrid& fractureGrid ) +{ + stream << "\n"; + + auto resultNamesWithUnit = fractureTemplate.uiResultNamesWithUnit(); + + for ( auto [name, unit] : resultNamesWithUnit ) + { + stream << QString( "\n" ).arg( name ).arg( unit ); + stream << "\n"; + stream << "\n"; + } + stream << "\n"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifThermalToStimPlanFractureXmlOutput::appendDataVector( QTextStream& stream, const QString& name, const std::vector& vals ) +{ + stream << QString( "<%1>[" ).arg( name ); + + for ( auto v : vals ) + { + stream << v << " "; + } + + stream << QString( "]\n" ).arg( name ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifThermalToStimPlanFractureXmlOutput::appendFooterToStream( QTextStream& stream ) +{ + stream << "" << '\n'; +} diff --git a/ApplicationLibCode/FileInterface/RifThermalToStimPlanFractureXmlOutput.h b/ApplicationLibCode/FileInterface/RifThermalToStimPlanFractureXmlOutput.h new file mode 100644 index 0000000000..434db25d88 --- /dev/null +++ b/ApplicationLibCode/FileInterface/RifThermalToStimPlanFractureXmlOutput.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 + +#include + +class RimThermalFractureTemplate; +class RigFractureGrid; + +class QString; +class QTextStream; + +//================================================================================================== +// +//================================================================================================== +class RifThermalToStimPlanFractureXmlOutput +{ +public: + static bool writeToFile( RimThermalFractureTemplate* fractureTemplate, const QString& filepath ); + +private: + static void appendHeaderToStream( QTextStream& stream ); + + static void appendPropertiesToStream( QTextStream& stream, + const RimThermalFractureTemplate& fractureTemplate, + const RigFractureGrid& fractureGrid ); + + static void appendGridDefinitionToStream( QTextStream& stream, const RigFractureGrid& fractureGrid ); + + static void appendDataVector( QTextStream& stream, const QString& name, const std::vector& vals ); + + static void appendFooterToStream( QTextStream& stream ); +}; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimMeshFractureTemplate.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimMeshFractureTemplate.cpp index 6a1ea3d24c..93d0767e34 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimMeshFractureTemplate.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimMeshFractureTemplate.cpp @@ -85,7 +85,7 @@ RimMeshFractureTemplate::~RimMeshFractureTemplate() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int RimMeshFractureTemplate::activeTimeStepIndex() +int RimMeshFractureTemplate::activeTimeStepIndex() const { return m_activeTimeStepIndex; } diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimMeshFractureTemplate.h b/ApplicationLibCode/ProjectDataModel/Completions/RimMeshFractureTemplate.h index 783a9a413e..e93dd7b95b 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimMeshFractureTemplate.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimMeshFractureTemplate.h @@ -43,7 +43,7 @@ class RimMeshFractureTemplate : public RimFractureTemplate RimMeshFractureTemplate(); ~RimMeshFractureTemplate() override; - int activeTimeStepIndex(); + int activeTimeStepIndex() const; virtual void setDefaultsBasedOnFile() = 0;