From 6f421e09904353e2da220046ab01e824602d188a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Jensen?= Date: Wed, 22 Aug 2018 11:10:10 +0200 Subject: [PATCH] #3180 Add multiple fraction create command (CommandFile) --- .../Application/Tools/RiaWellNameComparer.h | 3 +- .../CMakeLists_files.cmake | 2 + .../RicfCreateMultipleFractures.h | 69 +++++++ .../ricfcreatemultiplefractures.cpp | 184 ++++++++++++++++++ .../RicCreateMultipleFracturesFeature.cpp | 22 +++ .../RicCreateMultipleFracturesFeature.h | 6 + .../RicCreateMultipleFracturesUi.cpp | 28 ++- .../RicCreateMultipleFracturesUi.h | 8 + 8 files changed, 319 insertions(+), 3 deletions(-) create mode 100644 ApplicationCode/CommandFileInterface/RicfCreateMultipleFractures.h create mode 100644 ApplicationCode/CommandFileInterface/ricfcreatemultiplefractures.cpp diff --git a/ApplicationCode/Application/Tools/RiaWellNameComparer.h b/ApplicationCode/Application/Tools/RiaWellNameComparer.h index 3ef70b9744..a256840f38 100644 --- a/ApplicationCode/Application/Tools/RiaWellNameComparer.h +++ b/ApplicationCode/Application/Tools/RiaWellNameComparer.h @@ -33,9 +33,10 @@ public: static QString tryFindMatchingSimWellName(QString searchName); static QString tryFindMatchingWellPath(QString wellName); -private: static QString tryMatchNameInList(QString searchName, const std::vector& nameList); + +private: static QString tryMatchName(QString searchName, const std::vector& nameList, std::function stringFormatter = nullptr); diff --git a/ApplicationCode/CommandFileInterface/CMakeLists_files.cmake b/ApplicationCode/CommandFileInterface/CMakeLists_files.cmake index e7230c0ae7..3083d15fef 100644 --- a/ApplicationCode/CommandFileInterface/CMakeLists_files.cmake +++ b/ApplicationCode/CommandFileInterface/CMakeLists_files.cmake @@ -20,6 +20,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicfSetStartDir.h ${CMAKE_CURRENT_LIST_DIR}/RicfSetTimeStep.h ${CMAKE_CURRENT_LIST_DIR}/RicfScaleFractureTemplate.h ${CMAKE_CURRENT_LIST_DIR}/RicfSetFractureContainment.h +${CMAKE_CURRENT_LIST_DIR}/RicfCreateMultipleFractures.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -43,6 +44,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicfSetStartDir.cpp ${CMAKE_CURRENT_LIST_DIR}/RicfSetTimeStep.cpp ${CMAKE_CURRENT_LIST_DIR}/RicfScaleFractureTemplate.cpp ${CMAKE_CURRENT_LIST_DIR}/RicfSetFractureContainment.cpp +${CMAKE_CURRENT_LIST_DIR}/RicfCreateMultipleFractures.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/CommandFileInterface/RicfCreateMultipleFractures.h b/ApplicationCode/CommandFileInterface/RicfCreateMultipleFractures.h new file mode 100644 index 0000000000..e8ad6fa340 --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfCreateMultipleFractures.h @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil 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 "RicfCommandObject.h" + +#include "cafPdmField.h" +#include "cafAppEnum.h" + +namespace MultipleFractures +{ + enum Action + { + NONE, + APPEND_FRACTURES, + REPLACE_FRACTURES + }; +} + +class RimEclipseCase; +class RimFractureTemplate; +class RimWellPath; + +//================================================================================================== +// +// +// +//================================================================================================== +class RicfCreateMultipleFractures : public RicfCommandObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicfCreateMultipleFractures(); + + virtual void execute() override; + +private: + bool validateArguments() const; + RimEclipseCase* caseFromId(int caseId)const ; + RimFractureTemplate* fractureTemplateFromId(int templateId) const; + std::vector wellPaths() const; + + caf::PdmField m_caseId; + caf::PdmField> m_wellPathNames; + caf::PdmField m_maxDistFromWellTd; + caf::PdmField m_maxFracturesPerWell; + caf::PdmField m_templateId; + caf::PdmField m_topLayer; + caf::PdmField m_baseLayer; + caf::PdmField m_spacing; + caf::PdmField> m_action; +}; diff --git a/ApplicationCode/CommandFileInterface/ricfcreatemultiplefractures.cpp b/ApplicationCode/CommandFileInterface/ricfcreatemultiplefractures.cpp new file mode 100644 index 0000000000..5435dfa50f --- /dev/null +++ b/ApplicationCode/CommandFileInterface/ricfcreatemultiplefractures.cpp @@ -0,0 +1,184 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 Statoil 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 "RicfCreateMultipleFractures.h" + +#include "RicfCommandFileExecutor.h" + +#include "FractureCommands/RicCreateMultipleFracturesFeature.h" +#include "FractureCommands/RicCreateMultipleFracturesOptionItemUi.h" +#include "FractureCommands/RicCreateMultipleFracturesUi.h" + +#include "RimProject.h" +#include "RimDialogData.h" +#include "RimFractureTemplate.h" +#include "RimOilField.h" +#include "RimEclipseCase.h" +#include "RimEclipseCaseCollection.h" +#include "RimWellPath.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" +#include "RiaWellNameComparer.h" + +#include "cafCmdFeatureManager.h" + + +CAF_PDM_SOURCE_INIT(RicfCreateMultipleFractures, "createMultipleFractures"); + +template<> +void caf::AppEnum< MultipleFractures::Action >::setUp() +{ + addItem(MultipleFractures::APPEND_FRACTURES, "APPEND_FRACTURES", "Append Fractures"); + addItem(MultipleFractures::REPLACE_FRACTURES, "REPLACE_FRACTURES", "Replace Fractures"); + + setDefault(MultipleFractures::NONE); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicfCreateMultipleFractures::RicfCreateMultipleFractures() +{ + RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); + RICF_InitField(&m_wellPathNames, "wellPathNames", std::vector(), "Well Path Names", "", "", ""); + RICF_InitField(&m_maxDistFromWellTd, "maxDistFromWellTd", 100.0, "Max Distance From Well TD", "", "", ""); + RICF_InitField(&m_maxFracturesPerWell, "maxFracturesPerWell", 100, "Max Fractures per Well", "", "", ""); + RICF_InitField(&m_templateId, "templateId", -1, "Template ID", "", "", ""); + RICF_InitField(&m_topLayer, "topLayer", -1, "Top Layer", "", "", ""); + RICF_InitField(&m_baseLayer, "baseLayer", -1, "Base Layer", "", "", ""); + RICF_InitField(&m_spacing, "spacing", 300.0, "Spacing", "", "", ""); + RICF_InitField(&m_action, "action", caf::AppEnum(MultipleFractures::NONE), "Action", "", "", ""); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfCreateMultipleFractures::execute() +{ + RimProject* project = RiaApplication::instance()->project(); + RiuCreateMultipleFractionsUi* settings = project->dialogData()->multipleFractionsData(); + + // Get case and fracture template + auto gridCase = caseFromId(m_caseId); + auto fractureTemplate = fractureTemplateFromId(m_templateId); + auto wellPaths = this->wellPaths(); + + if (gridCase && fractureTemplate && !wellPaths.empty() && validateArguments()) + { + RicCreateMultipleFracturesOptionItemUi* options = new RicCreateMultipleFracturesOptionItemUi(); + options->setValues(m_topLayer, m_baseLayer, fractureTemplate, m_spacing); + + settings->clearWellPaths(); + for (auto wellPath : wellPaths) + { + settings->addWellPath(wellPath); + } + + settings->setValues(gridCase, m_maxDistFromWellTd, m_maxFracturesPerWell); + settings->clearOptions(); + settings->insertOptionItem(nullptr, options); + + caf::CmdFeatureManager* commandManager = caf::CmdFeatureManager::instance(); + auto feature = dynamic_cast(commandManager->getCommandFeature("RicCreateMultipleFracturesFeature")); + + if (feature) + { + if (m_action == MultipleFractures::APPEND_FRACTURES) feature->appendFractures(); + if (m_action == MultipleFractures::REPLACE_FRACTURES) feature->replaceFractures(); + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicfCreateMultipleFractures::validateArguments() const +{ + bool valid = + m_caseId >= 0 && + m_templateId >= 0 && + !(m_action == MultipleFractures::NONE); + + if (valid) return true; + + RiaLogging::error(QString("createMultipleFractures: Command argument validation failed")); + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseCase* RicfCreateMultipleFractures::caseFromId(int caseId) const +{ + for (RimEclipseCase* c : RiaApplication::instance()->project()->activeOilField()->analysisModels->cases()) + { + if (c->caseId() == caseId) return c; + } + + RiaLogging::error(QString("createMultipleFractures: Could not find case with ID %1").arg(caseId)); + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFractureTemplate* RicfCreateMultipleFractures::fractureTemplateFromId(int templateId) const +{ + for (RimFractureTemplate* t : RiaApplication::instance()->project()->allFractureTemplates()) + { + if (t->id() == templateId) return t; + } + + RiaLogging::error(QString("createMultipleFractures: Could not find fracture template with ID %1").arg(templateId)); + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicfCreateMultipleFractures::wellPaths() const +{ + std::vector wellPaths; + auto allWellPaths = RiaApplication::instance()->project()->allWellPaths(); + + if (!m_wellPathNames.v().empty()) + { + std::set wellPathNameSet(m_wellPathNames.v().begin(), m_wellPathNames.v().end()); + + for (auto wellPath : allWellPaths) + { + if (!RiaWellNameComparer::tryMatchNameInList(wellPath->name(), m_wellPathNames.v()).isEmpty()) + wellPaths.push_back(wellPath); + } + } + else + { + wellPaths = allWellPaths; + } + + if (wellPaths.empty() || wellPaths.size() < m_wellPathNames.v().size()) + { + RiaLogging::error(QString("createMultipleFractures: One or more well paths was not found")); + std::this_thread::sleep_for(std::chrono::seconds(2)); + } + return wellPaths; +} + diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.cpp b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.cpp index 072d7b102a..f7f8de7c6b 100644 --- a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.cpp +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.cpp @@ -45,6 +45,22 @@ CAF_CMD_SOURCE_INIT(RicCreateMultipleFracturesFeature, "RicCreateMultipleFracturesFeature"); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::appendFractures() +{ + slotAppendFractures(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::replaceFractures() +{ + slotDeleteAndAppendFractures(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -169,6 +185,7 @@ void RicCreateMultipleFracturesFeature::onActionTriggered(bool isChecked) int maxFractureCount = 100; multipleFractionsUi->setValues(firstSourceCase, minimumDistanceFromTip, maxFractureCount); + // Options auto newItem = new RicCreateMultipleFracturesOptionItemUi; RimFractureTemplate* firstFractureTemplate = nullptr; @@ -184,6 +201,11 @@ void RicCreateMultipleFracturesFeature::onActionTriggered(bool isChecked) } } + // Selected well paths + std::vector selWells = caf::selectedObjectsByTypeStrict(); + multipleFractionsUi->clearWellPaths(); + for (auto wellPath : selWells) multipleFractionsUi->addWellPath(wellPath); + caf::PdmUiPropertyViewDialog propertyDialog( Riu3DMainWindowTools::mainWindowWidget(), multipleFractionsUi, "Create Multiple Fractions", ""); diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.h b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.h index 17fd5bdf00..86ff52bc89 100644 --- a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.h +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.h @@ -36,6 +36,12 @@ class RicCreateMultipleFracturesFeature : public caf::CmdFeature Q_OBJECT CAF_CMD_HEADER_INIT; +public: + RicCreateMultipleFracturesFeature() {} + + void appendFractures(); + void replaceFractures(); + private slots: void slotDeleteAndAppendFractures(); void slotAppendFractures(); diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.cpp b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.cpp index 9a2fd91108..dd4819b1f7 100644 --- a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.cpp +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.cpp @@ -112,6 +112,30 @@ void RiuCreateMultipleFractionsUi::deleteOptionItem(RicCreateMultipleFracturesOp delete optionsItem; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::clearOptions() +{ + m_options.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::addWellPath(RimWellPath* wellPath) +{ + m_wellPaths.push_back(wellPath); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::clearWellPaths() +{ + m_wellPaths.clear(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -242,9 +266,9 @@ std::vector RiuCreateMultipleFractionsUi::locationsForNe if (mainGrid) { - std::vector selWells = caf::selectedObjectsByTypeStrict(); + //std::vector selWells = caf::selectedObjectsByTypeStrict(); - for (auto w : selWells) + for (auto w : m_wellPaths) { auto wellPathGeometry = w->wellPathGeometry(); if (wellPathGeometry) diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.h b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.h index fbf4fa17c3..1a676846bd 100644 --- a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.h +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.h @@ -66,6 +66,12 @@ public: void deleteOptionItem(RicCreateMultipleFracturesOptionItemUi* optionsItem); + void clearOptions(); + + void addWellPath(RimWellPath* wellPath); + + void clearWellPaths(); + std::vector locationsForNewFractures() const; private: @@ -86,4 +92,6 @@ private: caf::PdmChildArrayField m_options; caf::PdmProxyValueField m_fractureCreationSummary; + + std::vector m_wellPaths; };