#4463 Working creation of grid case groups

This commit is contained in:
Gaute Lindkvist 2019-07-18 10:53:59 +02:00
parent 7a2b9926a0
commit 6b7a9b8da5
14 changed files with 228 additions and 21 deletions

View File

@ -24,6 +24,7 @@
#include "SummaryPlotCommands/RicNewSummaryCurveFeature.h"
#include "RiaApplication.h"
#include "RiaGuiApplication.h"
#include "RiaLogging.h"
#include "RiaPreferences.h"
@ -325,7 +326,7 @@ int RiaImportEclipseCaseTools::openEclipseCaseShowTimeStepFilterImpl(const QStri
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaImportEclipseCaseTools::addEclipseCases(const QStringList& fileNames)
bool RiaImportEclipseCaseTools::addEclipseCases(const QStringList& fileNames, RimIdenticalGridCaseGroup** resultingCaseGroup/*=nullptr*/)
{
if (fileNames.size() == 0) return true;
@ -407,11 +408,16 @@ bool RiaImportEclipseCaseTools::addEclipseCases(const QStringList& fileNames)
{
// Create placeholder results and propagate results info from main case to all other cases
gridCaseGroup->loadMainCaseAndActiveCellInfo();
if (resultingCaseGroup)
{
*resultingCaseGroup = gridCaseGroup;
}
}
project->activeOilField()->analysisModels()->updateConnectedEditors();
if (gridCaseGroup->statisticsCaseCollection()->reservoirs.size() > 0)
if (RiaGuiApplication::isRunning() && gridCaseGroup && gridCaseGroup->statisticsCaseCollection()->reservoirs.size() > 0)
{
RiuMainWindow::instance()->selectAsCurrentItem(gridCaseGroup->statisticsCaseCollection()->reservoirs[0]);
}

View File

@ -23,6 +23,8 @@
class QString;
class QStringList;
class RimIdenticalGridCaseGroup;
//==================================================================================================
///
//==================================================================================================
@ -37,7 +39,7 @@ public:
static bool openEclipseInputCaseFromFileNames(const QStringList& fileNames, QString* fileContainingGrid = nullptr);
static bool openMockModel(const QString& name);
static bool addEclipseCases(const QStringList& fileNames);
static bool addEclipseCases(const QStringList& fileNames, RimIdenticalGridCaseGroup** resultingCaseGroup = nullptr);
private:
static int openEclipseCaseFromFile(const QString& fileName);

View File

@ -29,6 +29,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicfCreateLgrForCompletions.h
${CMAKE_CURRENT_LIST_DIR}/RicfApplicationTools.h
${CMAKE_CURRENT_LIST_DIR}/RicfCreateSaturationPressurePlots.h
${CMAKE_CURRENT_LIST_DIR}/RicfExportFlowCharacteristics.h
${CMAKE_CURRENT_LIST_DIR}/RicfCreateGridCaseGroup.h
)
set (SOURCE_GROUP_SOURCE_FILES
@ -61,6 +62,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicfCreateLgrForCompletions.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfApplicationTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfCreateSaturationPressurePlots.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfExportFlowCharacteristics.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfCreateGridCaseGroup.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@ -0,0 +1,79 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- 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 "RicfCreateGridCaseGroup.h"
#include "RiaApplication.h"
#include "RiaImportEclipseCaseTools.h"
#include "RimIdenticalGridCaseGroup.h"
#include <QFileInfo>
#include <QDir>
#include <QStringList>
CAF_PDM_SOURCE_INIT(RicfCreateGridCaseGroupResult, "createGridCaseGroupResult");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicfCreateGridCaseGroupResult::RicfCreateGridCaseGroupResult(int caseGroupId /*= -1*/, const QString& caseGroupName /*= ""*/)
{
CAF_PDM_InitObject("case_group_result", "", "", "");
CAF_PDM_InitField(&this->caseGroupId, "groupId", caseGroupId, "", "", "", "");
CAF_PDM_InitField(&this->caseGroupName, "groupName", caseGroupName, "", "", "", "");
}
CAF_PDM_SOURCE_INIT(RicfCreateGridCaseGroup, "createGridCaseGroup");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicfCreateGridCaseGroup::RicfCreateGridCaseGroup()
{
RICF_InitFieldNoDefault(&m_casePaths, "casePaths", "List of Paths to Case Files", "", "", "");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicfCommandResponse RicfCreateGridCaseGroup::execute()
{
QStringList casePaths;
for (QString casePath : m_casePaths())
{
QFileInfo casePathInfo(casePath);
if (!casePathInfo.exists())
{
QDir startDir(RiaApplication::instance()->startDir());
casePath = startDir.absoluteFilePath(casePath);
}
casePaths.push_back(casePath);
}
RimIdenticalGridCaseGroup* caseGroup = nullptr;
if (RiaImportEclipseCaseTools::addEclipseCases(casePaths, &caseGroup) && caseGroup)
{
RicfCommandResponse response;
response.setResult(new RicfCreateGridCaseGroupResult(caseGroup->groupId(), caseGroup->name()));
return response;
}
return RicfCommandResponse(RicfCommandResponse::COMMAND_ERROR, "Could not load grid case group");
}

View File

@ -0,0 +1,53 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RicfCommandObject.h"
#include "cafPdmField.h"
class RicfCreateGridCaseGroupResult : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RicfCreateGridCaseGroupResult(int caseGroupId = -1, const QString& caseGroupName = "");
public:
caf::PdmField<int> caseGroupId;
caf::PdmField<QString> caseGroupName;
};
//==================================================================================================
//
//
//
//==================================================================================================
class RicfCreateGridCaseGroup : public RicfCommandObject
{
CAF_PDM_HEADER_INIT;
public:
RicfCreateGridCaseGroup();
RicfCommandResponse execute() override;
private:
caf::PdmField<std::vector<QString>> m_casePaths;
};

View File

@ -1,17 +1,18 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// Copyright (C) 2017-2019 Statoil ASA
// 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 <http://www.gnu.org/licenses/gpl.html>
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////

View File

@ -1,6 +1,7 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
// Copyright (C) 2017-2019 Statoil ASA
// 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

View File

@ -82,11 +82,11 @@ RicfCommandResponse RicfSingleCaseReplace::execute()
if (m_caseId() < 0)
{
projectModifier->setReplaceCaseFirstOccurrence(m_newGridFile());
projectModifier->setReplaceCaseFirstOccurrence(filePath);
}
else
{
projectModifier->setReplaceCase(m_caseId(), );
projectModifier->setReplaceCase(m_caseId(), filePath);
}
if (!RiaApplication::instance()->loadProject(lastProjectPath, RiaApplication::PLA_NONE, projectModifier.p()))

View File

@ -233,6 +233,11 @@ message CreateSatPressPlotRequest
repeated int32 caseIds = 1;
}
message CreateGridCaseGroupRequest
{
repeated string casePaths = 1;
}
/* CommandParams handles both command name and parameters in one.
* The message type and content is used as parameters and
* the name of the variable is used to find the command name. */
@ -270,17 +275,25 @@ message CommandParams
CreateLgrForCompRequest createLgrForCompletions = 24;
CreateSatPressPlotRequest createSaturationPressurePlots = 25;
ReplaceCaseRequests replaceMultipleCases = 26;
CreateGridCaseGroupRequest createGridCaseGroup = 27;
}
}
message GridCaseGroupResult
{
int32 groupId = 1;
string groupName = 2;
}
/* Command reply handles the return values for the generic command
* The name of the variable is used to map to the cafPdmObject classKeyword */
message CommandReply
{
oneof result
{
Empty emptyResult = 1;
CaseRequest loadCaseResult = 2;
Empty emptyResult = 1;
CaseRequest loadCaseResult = 2;
GridCaseGroupResult createGridCaseGroupResult = 3;
}
}

View File

@ -71,7 +71,8 @@ class Commands:
"""
commandReply = self.__execute(loadCase=Cmd.FilePathRequest(path=path))
assert commandReply.HasField("loadCaseResult")
assert(commandReply is not None)
assert(commandReply.HasField("loadCaseResult"))
return Case(self.channel, commandReply.loadCaseResult.id)
def replaceCase(self, newGridFile, caseId=0):
@ -83,7 +84,7 @@ class Commands:
"""
return self.__execute(replaceCase=Cmd.ReplaceCaseRequest(newGridFile=newGridFile,
caseId=caseId))
caseId=caseId))
def replaceSourceCases(self, gridListFile, caseGroupId=0):
"""Replace all source cases within a case group
@ -94,7 +95,22 @@ class Commands:
"""
return self.__execute(replaceSourceCases=Cmd.ReplaceSourceCasesRequest(gridListFile=gridListFile,
caseGroupId=caseGroupId))
caseGroupId=caseGroupId))
def createGridCaseGroup(self, casePaths):
"""Create a Grid Case Group from a list of cases
Arguments:
casePaths (list): list of file path strings
Returns:
A case group id and name
"""
commandReply = self.__execute(createGridCaseGroup=Cmd.CreateGridCaseGroupRequest(casePaths=casePaths))
assert(commandReply is not None)
assert(commandReply.HasField("createGridCaseGroupResult"))
return (commandReply.createGridCaseGroupResult.groupId, commandReply.createGridCaseGroupResult.groupName)
##################
# Export Commands
##################

View File

@ -0,0 +1,14 @@
import sys
import os
sys.path.insert(1, os.path.join(sys.path[0], '../../'))
import rips
resInsight = rips.Instance.find()
casePaths = []
casePaths.append("../../../../TestModels/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID")
casePaths.append("../../../../TestModels/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID")
groupId, groupName = resInsight.commands.createGridCaseGroup(casePaths=casePaths)
print("Group id = " + str(groupId))
print("Group name = " + groupName)

View File

@ -88,4 +88,4 @@ def test_replaceCase(rips_instance, initializeTest):
assert(len(cases) is 1)
case = project.case(id=0)
assert(case.name == "Real0--BRUGGE_0000.EGRID")
assert(case.id == 0)
assert(case.id == 0)

View File

@ -33,4 +33,12 @@ def test_exportPropertyInView(rips_instance, initializeTest):
rips_instance.commands.exportPropertyInViews(0, "3D View", 0)
expectedFileName = case.name + "-" + str("3D_View") + "-" + "T0" + "-SOIL"
fullPath = tmpdirname + "/" + expectedFileName
assert(os.path.exists(fullPath))
assert(os.path.exists(fullPath))
@pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux")
def test_loadGridCaseGroup(rips_instance, initializeTest):
casePaths = []
casePaths.append(dataroot.PATH + "/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID")
casePaths.append(dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID")
groupId, groupName = rips_instance.commands.createGridCaseGroup(casePaths=casePaths)
print(groupId, groupName)

View File

@ -150,6 +150,13 @@ void RiaGrpcCommandService::assignPdmFieldValue(caf::PdmValueField* pdmValueF
FieldDescriptor::Type fieldDataType = paramDescriptor->type();
const Reflection* reflection = params.GetReflection();
if (paramDescriptor->is_repeated() &&
fieldDataType != FieldDescriptor::TYPE_INT32 &&
fieldDataType != FieldDescriptor::TYPE_STRING)
{
CAF_ASSERT(false && "Only integer and string vectors are implemented as command arguments");
}
switch (fieldDataType)
{
case FieldDescriptor::TYPE_BOOL: {
@ -224,10 +231,15 @@ void RiaGrpcCommandService::assignPdmFieldValue(caf::PdmValueField* pdmValueF
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaGrpcCommandService::assignGrpcFieldValue(google::protobuf::Message* reply,
const google::protobuf::FieldDescriptor* fieldDescriptor,
const caf::PdmValueField* pdmValueField)
void RiaGrpcCommandService::assignGrpcFieldValue(Message* reply,
const FieldDescriptor* fieldDescriptor,
const caf::PdmValueField* pdmValueField)
{
if (fieldDescriptor->is_repeated())
{
CAF_ASSERT(false && "Assigning vector results to Command Results is not yet implemented");
}
FieldDescriptor::Type fieldDataType = fieldDescriptor->type();
QVariant qValue = pdmValueField->toQVariant();