///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2019- 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 "RicExportEclipseSectorModelFeature.h" #include "RiaApplication.h" #include "RiaLogging.h" #include "RiaModelExportDefines.h" #include "RiaResultNames.h" #include "RicExportEclipseSectorModelUi.h" #include "RicExportFeatureImpl.h" #include "RifEclipseInputFileTools.h" #include "RifOpmDeckTools.h" #include "RifOpmFlowDeckFile.h" #include "RifReaderEclipseOutput.h" #include "ProjectDataModel/Jobs/RimKeywordBcprop.h" #include "ProjectDataModel/Jobs/RimKeywordFactory.h" #include "Rim3dView.h" #include "RimDialogData.h" #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseView.h" #include "RimFaultInView.h" #include "RimFaultInViewCollection.h" #include "RimProject.h" #include "Tools/RimEclipseViewTools.h" #include "RigActiveCellInfo.h" #include "RigBoundingBoxIjk.h" #include "RigEclipseCaseData.h" #include "RigEclipseCaseDataTools.h" #include "RigEclipseResultTools.h" #include "RigGridExportAdapter.h" #include "RigMainGrid.h" #include "RigResdataGridConverter.h" #include "RigSimulationInputSettings.h" #include "RigSimulationInputTool.h" #include "Well/RigSimWellData.h" #include "Well/RigWellResultFrame.h" #include "Well/RigWellResultPoint.h" #include "Riu3DMainWindowTools.h" #include "RiuPropertyViewTabWidget.h" #include "RiuViewer.h" #include "cafCmdFeatureManager.h" #include "cafProgressInfo.h" #include "cafSelectionManager.h" #include "opm/input/eclipse/Deck/DeckItem.hpp" #include "opm/input/eclipse/Deck/DeckKeyword.hpp" #include "opm/input/eclipse/Deck/DeckRecord.hpp" #include "opm/input/eclipse/Parser/ParserKeyword.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/C.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/E.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/O.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/S.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/W.hpp" #include "opm/input/eclipse/Utility/Typetools.hpp" #include #include #include #include #include CAF_CMD_SOURCE_INIT( RicExportEclipseSectorModelFeature, "RicExportEclipseInputGridFeature" ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicExportEclipseSectorModelFeature::openDialogAndExecuteCommand( RimEclipseView* view ) { if ( !view ) return; RigEclipseCaseData* caseData = view->eclipseCase()->eclipseCaseData(); cvf::UByteArray cellVisibility; view->calculateCurrentTotalCellVisibility( &cellVisibility, view->currentTimeStep() ); const auto& [min, max] = RimEclipseViewTools::getVisibleCellRange( view, cellVisibility ); RicExportEclipseSectorModelUi* exportSettings = RimProject::current()->dialogData()->exportEclipseSectorModelUi(); exportSettings->setCaseData( caseData, view, min, max ); exportSettings->applyBoundaryDefaults(); exportSettings->removeInvalidKeywords(); RiuPropertyViewTabWidget propertyDialog( Riu3DMainWindowTools::mainWindowWidget(), exportSettings, "Export Eclipse Sector Model", exportSettings->tabNames() ); RicExportFeatureImpl::configureForExport( propertyDialog.dialogButtonBox() ); if ( propertyDialog.exec() == QDialog::Accepted ) { executeCommand( view, *exportSettings, "ExportInputGrid" ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicExportEclipseSectorModelFeature::executeCommand( RimEclipseView* view, const RicExportEclipseSectorModelUi& exportSettings, const QString& logPrefix ) { int resultProgressPercentage = exportSettings.exportParameters() ? std::min( (int)exportSettings.selectedKeywords().size(), 20 ) : 0; int faultsProgressPercentage = exportSettings.exportFaults() ? 10 : 0; int gridProgressPercentage = 100 - resultProgressPercentage - faultsProgressPercentage; caf::ProgressInfo progress( gridProgressPercentage + resultProgressPercentage + faultsProgressPercentage, "Export Eclipse Sector Model" ); CVF_ASSERT( exportSettings.refinement().x() > 0u && exportSettings.refinement().y() > 0u && exportSettings.refinement().z() > 0u ); if ( exportSettings.exportGrid() ) { auto task = progress.task( "Export Grid", gridProgressPercentage ); exportGrid( view, exportSettings ); } if ( exportSettings.exportParameters() != RicExportEclipseSectorModelUi::EXPORT_NO_RESULTS ) { auto task = progress.task( "Export Properties", resultProgressPercentage ); exportParameters( view, exportSettings ); } if ( exportSettings.exportFaults() != RicExportEclipseSectorModelUi::EXPORT_NO_RESULTS ) { auto task = progress.task( "Export Faults", faultsProgressPercentage ); exportFaults( view, exportSettings ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicExportEclipseSectorModelFeature::exportGrid( RimEclipseView* view, const RicExportEclipseSectorModelUi& exportSettings ) { cvf::UByteArray cellVisibility; view->calculateCurrentTotalCellVisibility( &cellVisibility, view->currentTimeStep() ); const cvf::UByteArray* cellVisibilityForActnum = exportSettings.makeInvisibleCellsInactive() ? &cellVisibility : nullptr; bool worked = RifEclipseInputFileTools::exportGrid( exportSettings.exportGridFilename(), view->eclipseCase()->eclipseCaseData(), exportSettings.exportInLocalCoordinates(), cellVisibilityForActnum, exportSettings.min(), exportSettings.max(), exportSettings.refinement() ); if ( !worked ) { RiaLogging::error( QString( "Unable to write grid to '%1'" ).arg( exportSettings.exportGridFilename() ) ); } else { if ( view->eclipseCase()->eclipseCaseData()->gridCount() > 1u ) { RiaLogging::warning( "Grid has LGRs but ResInsight only supports exporting the Main Grid" ); } QFileInfo info( exportSettings.exportGridFilename() ); RiaApplication::instance()->setLastUsedDialogDirectory( "EXPORT_INPUT_GRID", info.absolutePath() ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicExportEclipseSectorModelFeature::exportParameters( RimEclipseView* view, const RicExportEclipseSectorModelUi& exportSettings ) { std::vector keywords = exportSettings.selectedKeywords; if ( exportSettings.exportParameters == RicExportEclipseSectorModelUi::EXPORT_TO_SEPARATE_FILE_PER_RESULT ) { QFileInfo info( exportSettings.exportGridFilename() ); QDir dirPath = info.absoluteDir(); for ( const QString& keyword : keywords ) { QString fileName = dirPath.absoluteFilePath( keyword + ".GRDECL" ); bool worked = RifEclipseInputFileTools::exportKeywords( fileName, view->eclipseCase()->eclipseCaseData(), { keyword }, exportSettings.writeEchoKeywords(), exportSettings.min(), exportSettings.max(), exportSettings.refinement() ); if ( !worked ) { RiaLogging::error( QString( "Unable to write results to '%1'" ).arg( fileName ) ); } } } else { QString fileName = exportSettings.exportParametersFilename(); if ( exportSettings.exportParameters() == RicExportEclipseSectorModelUi::EXPORT_TO_GRID_FILE ) { fileName = exportSettings.exportGridFilename(); } bool worked = RifEclipseInputFileTools::exportKeywords( fileName, view->eclipseCase()->eclipseCaseData(), keywords, exportSettings.writeEchoKeywords(), exportSettings.min(), exportSettings.max(), exportSettings.refinement() ); if ( !worked ) { RiaLogging::error( QString( "Unable to write results to '%1'" ).arg( fileName ) ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicExportEclipseSectorModelFeature::exportFaults( RimEclipseView* view, const RicExportEclipseSectorModelUi& exportSettings ) { if ( exportSettings.exportFaults == RicExportEclipseSectorModelUi::EXPORT_TO_SEPARATE_FILE_PER_RESULT ) { for ( const auto& faultInView : view->faultCollection()->faults() ) { auto rigFault = faultInView->faultGeometry(); QString fileName = QString( "%1.GRDECL" ).arg( rigFault->name() ); RifEclipseInputFileTools::saveFault( fileName, view->eclipseCase()->mainGrid(), rigFault->faultFaces(), rigFault->name(), exportSettings.min(), exportSettings.max(), exportSettings.refinement() ); } } else { QString fileName = exportSettings.exportFaultsFilename(); QIODevice::OpenMode openFlag = QIODevice::Truncate; if ( exportSettings.exportParameters() == RicExportEclipseSectorModelUi::EXPORT_TO_GRID_FILE ) { openFlag = QIODevice::Append; fileName = exportSettings.exportGridFilename(); } QFile exportFile( fileName ); if ( !exportFile.open( QIODevice::Text | QIODevice::WriteOnly | openFlag ) ) { RiaLogging::error( "Could not open the file : " + fileName ); } QTextStream stream( &exportFile ); RifEclipseInputFileTools::saveFaults( stream, view->eclipseCase()->mainGrid(), exportSettings.min(), exportSettings.max(), exportSettings.refinement() ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RicExportEclipseSectorModelFeature::isCommandEnabled() const { return selectedView() != nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicExportEclipseSectorModelFeature::onActionTriggered( bool isChecked ) { RimEclipseView* view = RicExportEclipseSectorModelFeature::selectedView(); openDialogAndExecuteCommand( view ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicExportEclipseSectorModelFeature::setupActionLook( QAction* actionToSetup ) { actionToSetup->setText( "Export Eclipse Sector Model" ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimEclipseView* RicExportEclipseSectorModelFeature::selectedView() { auto contextViewer = dynamic_cast( caf::CmdFeatureManager::instance()->currentContextMenuTargetWidget() ); if ( contextViewer != nullptr ) { // Command is triggered from viewer Rim3dView* activeView = RiaApplication::instance()->activeMainOrComparisonGridView(); return dynamic_cast( activeView ); } // Command triggered from project tree or file menu auto view = caf::SelectionManager::instance()->selectedItemAncestorOfType(); return view; }