#3180 Add multiple fraction create command (CommandFile)

This commit is contained in:
Bjørn Erik Jensen 2018-08-22 11:10:10 +02:00
parent 3a716fe0f7
commit 6f421e0990
8 changed files with 319 additions and 3 deletions

View File

@ -33,9 +33,10 @@ public:
static QString tryFindMatchingSimWellName(QString searchName);
static QString tryFindMatchingWellPath(QString wellName);
private:
static QString tryMatchNameInList(QString searchName,
const std::vector<QString>& nameList);
private:
static QString tryMatchName(QString searchName,
const std::vector<QString>& nameList,
std::function<QString(QString)> stringFormatter = nullptr);

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/gpl.html>
// 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<RimWellPath*> wellPaths() const;
caf::PdmField<int> m_caseId;
caf::PdmField<std::vector<QString>> m_wellPathNames;
caf::PdmField<double> m_maxDistFromWellTd;
caf::PdmField<int> m_maxFracturesPerWell;
caf::PdmField<int> m_templateId;
caf::PdmField<int> m_topLayer;
caf::PdmField<int> m_baseLayer;
caf::PdmField<double> m_spacing;
caf::PdmField<caf::AppEnum<MultipleFractures::Action>> m_action;
};

View File

@ -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 <http://www.gnu.org/licenses/gpl.html>
// 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<QString>(), "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::Action>(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<RicCreateMultipleFracturesFeature*>(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<RimWellPath*> RicfCreateMultipleFractures::wellPaths() const
{
std::vector<RimWellPath*> wellPaths;
auto allWellPaths = RiaApplication::instance()->project()->allWellPaths();
if (!m_wellPathNames.v().empty())
{
std::set<QString> 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;
}

View File

@ -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<RimWellPath*> selWells = caf::selectedObjectsByTypeStrict<RimWellPath*>();
multipleFractionsUi->clearWellPaths();
for (auto wellPath : selWells) multipleFractionsUi->addWellPath(wellPath);
caf::PdmUiPropertyViewDialog propertyDialog(
Riu3DMainWindowTools::mainWindowWidget(), multipleFractionsUi, "Create Multiple Fractions", "");

View File

@ -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();

View File

@ -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<LocationForNewFracture> RiuCreateMultipleFractionsUi::locationsForNe
if (mainGrid)
{
std::vector<RimWellPath*> selWells = caf::selectedObjectsByTypeStrict<RimWellPath*>();
//std::vector<RimWellPath*> selWells = caf::selectedObjectsByTypeStrict<RimWellPath*>();
for (auto w : selWells)
for (auto w : m_wellPaths)
{
auto wellPathGeometry = w->wellPathGeometry();
if (wellPathGeometry)

View File

@ -66,6 +66,12 @@ public:
void deleteOptionItem(RicCreateMultipleFracturesOptionItemUi* optionsItem);
void clearOptions();
void addWellPath(RimWellPath* wellPath);
void clearWellPaths();
std::vector<LocationForNewFracture> locationsForNewFractures() const;
private:
@ -86,4 +92,6 @@ private:
caf::PdmChildArrayField<RicCreateMultipleFracturesOptionItemUi*> m_options;
caf::PdmProxyValueField<QString> m_fractureCreationSummary;
std::vector<RimWellPath*> m_wellPaths;
};