diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index 28c6de9612..4e45051b09 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -39,6 +41,8 @@ #include "RimWellPathCollection.h" #include "RimOilField.h" #include "RimAnalysisModels.h" +#include "RimFaultCollection.h" +#include "RimFaultResultSlot.h" #include "cafCeetronNavigation.h" #include "cafCadNavigation.h" @@ -67,7 +71,7 @@ #include "cafPdmFieldCvfColor.h" #include "cafPdmFieldCvfMat4d.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "RimCellEdgeResultSlot.h" #include "RimCellRangeFilterCollection.h" #include "RimCellPropertyFilterCollection.h" @@ -78,6 +82,7 @@ #include "cvfProgramOptions.h" #include "cvfqtUtils.h" +#include "RimCommandObject.h" namespace caf @@ -834,7 +839,7 @@ bool RiaApplication::parseArguments() progOpt.setOptionPrefix(cvf::ProgramOptions::DOUBLE_DASH); m_helpText = QString("\n%1 v. %2\n").arg(RI_APPLICATION_NAME).arg(getVersionStringApp(false)); - m_helpText += "Copyright Statoil ASA, Ceetron AS 2011, 2012\n\n"; + m_helpText += "Copyright Statoil ASA, Ceetron Solution AS, Ceetron AS\n\n"; const cvf::String usageText = progOpt.usageText(110, 30); m_helpText += cvfqt::Utils::toQString(usageText); @@ -1066,6 +1071,34 @@ QString RiaApplication::octavePath() const return m_preferences->octaveExecutable(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RiaApplication::octaveArguments() const +{ + // http://www.gnu.org/software/octave/doc/interpreter/Command-Line-Options.html#Command-Line-Options + + // -p path + // Add path to the head of the search path for function files. The value of path specified on the command line + // will override any value of OCTAVE_PATH found in the environment, but not any commands in the system or + // user startup files that set the internal load path through one of the path functions. + + + QStringList arguments; + arguments.append("--path"); + arguments << QApplication::applicationDirPath(); + + if (!m_preferences->octaveShowHeaderInfoWhenExecutingScripts) + { + // -q + // Don't print the usual greeting and version message at startup. + + arguments.append("-q"); + } + + return arguments; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1202,7 +1235,7 @@ bool RiaApplication::launchProcessForMultipleCases(const QString& program, const //-------------------------------------------------------------------------------------------------- /// Read fields of a Pdm object using QSettings //-------------------------------------------------------------------------------------------------- -void RiaApplication::readFieldsFromApplicationStore(caf::PdmObject* object) +void RiaApplication::readFieldsFromApplicationStore(caf::PdmObject* object, const QString context) { QSettings settings; std::vector fields; @@ -1213,10 +1246,24 @@ void RiaApplication::readFieldsFromApplicationStore(caf::PdmObject* object) { caf::PdmFieldHandle* fieldHandle = fields[i]; - if (settings.contains(fieldHandle->keyword())) + std::vector children; + fieldHandle->childObjects(&children); + for (size_t childIdx = 0; childIdx < children.size(); childIdx++) { - QVariant val = settings.value(fieldHandle->keyword()); - fieldHandle->setValueFromUi(val); + caf::PdmObject* child = children[childIdx]; + QString subContext = context + child->classKeyword() + "/"; + readFieldsFromApplicationStore(child, subContext); + } + + + if (children.size() == 0) + { + QString key = context + fieldHandle->keyword(); + if (settings.contains(key)) + { + QVariant val = settings.value(key); + fieldHandle->setValueFromUi(val); + } } } } @@ -1224,7 +1271,7 @@ void RiaApplication::readFieldsFromApplicationStore(caf::PdmObject* object) //-------------------------------------------------------------------------------------------------- /// Write fields of a Pdm object using QSettings //-------------------------------------------------------------------------------------------------- -void RiaApplication::writeFieldsToApplicationStore(const caf::PdmObject* object) +void RiaApplication::writeFieldsToApplicationStore(const caf::PdmObject* object, const QString context) { CVF_ASSERT(object); @@ -1238,7 +1285,24 @@ void RiaApplication::writeFieldsToApplicationStore(const caf::PdmObject* object) { caf::PdmFieldHandle* fieldHandle = fields[i]; - settings.setValue(fieldHandle->keyword(), fieldHandle->uiValue()); + std::vector children; + fieldHandle->childObjects(&children); + for (size_t childIdx = 0; childIdx < children.size(); childIdx++) + { + caf::PdmObject* child = children[childIdx]; + QString subContext; + if (context.isEmpty()) + { + subContext = context + child->classKeyword() + "/"; + } + + writeFieldsToApplicationStore(child, subContext); + } + + if (children.size() == 0) + { + settings.setValue(context + fieldHandle->keyword(), fieldHandle->uiValue()); + } } } @@ -2000,8 +2064,8 @@ void RiaApplication::regressionTestConfigureProject() riv->viewer()->setFixedSize(1000, 745); } - riv->faultCollection->showFaultsOutsideFilters.setValueFromUi(false); - riv->faultCollection->showResultsOnFaults.setValueFromUi(true); + riv->faultCollection->setShowFaultsOutsideFilters(false); + riv->faultResultSettings->showCustomFaultResult.setValueFromUi(false); } } } diff --git a/ApplicationCode/Application/RiaApplication.h b/ApplicationCode/Application/RiaApplication.h index f026d613b6..1d04f1ace7 100644 --- a/ApplicationCode/Application/RiaApplication.h +++ b/ApplicationCode/Application/RiaApplication.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -123,15 +125,17 @@ class RiaApplication : public QApplication RINavigationPolicy navigationPolicy() const; QString scriptDirectories() const; QString scriptEditorPath() const; + QString octavePath() const; + QStringList octaveArguments() const; bool launchProcess(const QString& program, const QStringList& arguments); bool launchProcessForMultipleCases(const QString& program, const QStringList& arguments, const std::vector& caseIds); void terminateProcess(); RiaPreferences* preferences(); - void readFieldsFromApplicationStore(caf::PdmObject* object); - void writeFieldsToApplicationStore(const caf::PdmObject* object); + void readFieldsFromApplicationStore(caf::PdmObject* object, const QString context = ""); + void writeFieldsToApplicationStore(const caf::PdmObject* object, const QString context = ""); void applyPreferences(); cvf::Font* standardFont(); diff --git a/ApplicationCode/Application/RiaPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp index 3e45619055..4271085fe0 100644 --- a/ApplicationCode/Application/RiaPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -21,6 +23,8 @@ #include "cafPdmUiFilePathEditor.h" #include "cafPdmFieldCvfColor.h" +#include "cafPdmUiCheckBoxEditor.h" +#include "RifReaderSettings.h" CAF_PDM_SOURCE_INIT(RiaPreferences, "RiaPreferences"); //-------------------------------------------------------------------------------------------------- @@ -36,8 +40,12 @@ RiaPreferences::RiaPreferences(void) CAF_PDM_InitField(&scriptEditorExecutable, "scriptEditorExecutable", QString("kate"), "Script Editor", "", "", ""); scriptEditorExecutable.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); - CAF_PDM_InitField(&octaveExecutable, "octaveExecutable", QString("octave"), "Octave", "", "", ""); + CAF_PDM_InitField(&octaveExecutable, "octaveExecutable", QString("octave"), "Octave executable location", "", "", ""); octaveExecutable.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + octaveExecutable.setUiLabelPosition(caf::PdmUiItemInfo::TOP); + + CAF_PDM_InitField(&octaveShowHeaderInfoWhenExecutingScripts, "octaveShowHeaderInfoWhenExecutingScripts", false, "Show text header when executing scripts", "", "", ""); + octaveShowHeaderInfoWhenExecutingScripts.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); CAF_PDM_InitField(&ssihubAddress, "ssihubAddress", QString("http://"), "ssihub Address", "", "", ""); @@ -56,10 +64,14 @@ RiaPreferences::RiaPreferences(void) CAF_PDM_InitFieldNoDefault(&lastUsedProjectFileName,"lastUsedProjectFileName", "Last Used Project File", "", "", ""); lastUsedProjectFileName.setUiHidden(true); - CAF_PDM_InitField(&autocomputeSOIL, "autocomputeSOIL", true, "SOIL", "", "SOIL = 1.0 - SGAS - SWAT", ""); - CAF_PDM_InitField(&autocomputeDepthRelatedProperties,"autocomputeDepth", true, "DEPTH related properties", "", "DEPTH, DX, DY, DZ, TOP, BOTTOM", ""); + CAF_PDM_InitField(&autocomputeDepthRelatedProperties, "autocomputeDepth", true, "DEPTH related properties", "", "DEPTH, DX, DY, DZ, TOP, BOTTOM", ""); + CAF_PDM_InitField(&autocomputeGridFaults, "autocomputeGridFaults", true, "Grid faults", "", "Detect all fault faces geometrically", ""); + + autocomputeDepthRelatedProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + autocomputeGridFaults.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); - CAF_PDM_InitField(&readFaultData, "readFaultData", true, "Read fault data", "", "", ""); + readerSettings = new RifReaderSettings; + CAF_PDM_InitFieldNoDefault(&readerSettings, "readerSettings", "Reader settings", "", "", ""); } //-------------------------------------------------------------------------------------------------- @@ -75,6 +87,8 @@ RiaPreferences::~RiaPreferences(void) //-------------------------------------------------------------------------------------------------- void RiaPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) { + readerSettings->defineEditorAttribute(field, uiConfigName, attribute); + if (field == &scriptDirectories) { caf::PdmUiFilePathEditorAttribute* myAttr = static_cast(attribute); @@ -84,6 +98,16 @@ void RiaPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QSt myAttr->m_appendUiSelectedFolderToText = true; } } + else if (field == &octaveShowHeaderInfoWhenExecutingScripts || + field == &autocomputeDepthRelatedProperties || + field == &autocomputeGridFaults) + { + caf::PdmUiCheckBoxEditorAttribute* myAttr = static_cast(attribute); + if (myAttr) + { + myAttr->m_useNativeCheckBoxLabel = true; + } + } } //-------------------------------------------------------------------------------------------------- @@ -96,7 +120,10 @@ void RiaPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& caf::PdmUiGroup* scriptGroup = uiOrdering.addNewGroup("Script configuration"); scriptGroup->add(&scriptDirectories); scriptGroup->add(&scriptEditorExecutable); - scriptGroup->add(&octaveExecutable); + + caf::PdmUiGroup* octaveGroup = uiOrdering.addNewGroup("Octave"); + octaveGroup->add(&octaveExecutable); + octaveGroup->add(&octaveShowHeaderInfoWhenExecutingScripts); caf::PdmUiGroup* defaultSettingsGroup = uiOrdering.addNewGroup("Default settings"); defaultSettingsGroup->add(&defaultScaleFactorZ); @@ -107,11 +134,17 @@ void RiaPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& defaultSettingsGroup->add(&defaultWellLabelColor); caf::PdmUiGroup* autoComputeGroup = uiOrdering.addNewGroup("Compute when loading new case"); - autoComputeGroup->add(&autocomputeSOIL); autoComputeGroup->add(&autocomputeDepthRelatedProperties); + autoComputeGroup->add(&autocomputeGridFaults); - caf::PdmUiGroup* faultsGroup = uiOrdering.addNewGroup("Faults"); - faultsGroup->add(&readFaultData); + + caf::PdmUiGroup* readerSettingsGroup = uiOrdering.addNewGroup("Reader settings"); + std::vector readerSettingsFields; + readerSettings->fields(readerSettingsFields); + for (size_t i = 0; i < readerSettingsFields.size(); i++) + { + readerSettingsGroup->add(readerSettingsFields[i]); + } } //-------------------------------------------------------------------------------------------------- @@ -123,9 +156,9 @@ void RiaPreferences::configureForRegressionTests() useShaders = true; showHud = false; - autocomputeSOIL = true; autocomputeDepthRelatedProperties = true; - readFaultData = false; + CVF_ASSERT(readerSettings); + readerSettings->importFaults = false; } diff --git a/ApplicationCode/Application/RiaPreferences.h b/ApplicationCode/Application/RiaPreferences.h index 4623599926..7d3f89b9ff 100644 --- a/ApplicationCode/Application/RiaPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -24,6 +26,10 @@ #include "cafPdmField.h" #include "cafAppEnum.h" +// Include to make Pdm work for cvf::Color +#include "cafPdmFieldCvfColor.h" + +class RifReaderSettings; class RiaPreferences : public caf::PdmObject { @@ -40,7 +46,10 @@ class RiaPreferences : public caf::PdmObject caf::PdmField scriptDirectories; caf::PdmField scriptEditorExecutable; + caf::PdmField octaveExecutable; + caf::PdmField octaveShowHeaderInfoWhenExecutingScripts; + caf::PdmField ssihubAddress; caf::PdmField defaultScaleFactorZ; @@ -55,10 +64,10 @@ class RiaPreferences : public caf::PdmObject caf::PdmField lastUsedProjectFileName; - caf::PdmField autocomputeSOIL; caf::PdmField autocomputeDepthRelatedProperties; + caf::PdmField autocomputeGridFaults; - caf::PdmField readFaultData; + caf::PdmField readerSettings; protected: virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); diff --git a/ApplicationCode/Application/RiaProjectModifier.cpp b/ApplicationCode/Application/RiaProjectModifier.cpp index af5a1d57e2..6de42bef55 100644 --- a/ApplicationCode/Application/RiaProjectModifier.cpp +++ b/ApplicationCode/Application/RiaProjectModifier.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -32,7 +33,7 @@ #include "RimScriptCollection.h" #include "RimCellPropertyFilterCollection.h" #include "RimCellPropertyFilter.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "RimResultSlot.h" #include "RimCellEdgeResultSlot.h" #include "RimCellRangeFilterCollection.h" diff --git a/ApplicationCode/Application/RiaProjectModifier.h b/ApplicationCode/Application/RiaProjectModifier.h index 209a75e0c1..3518630b91 100644 --- a/ApplicationCode/Application/RiaProjectModifier.h +++ b/ApplicationCode/Application/RiaProjectModifier.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/CMakeLists.txt b/ApplicationCode/CMakeLists.txt index d4e7e4113f..b392fbbf8e 100644 --- a/ApplicationCode/CMakeLists.txt +++ b/ApplicationCode/CMakeLists.txt @@ -42,6 +42,7 @@ set( APPLICATION_FILES set( USER_INTERFACE_FILES UserInterface/RiuCursors.cpp + UserInterface/RiuResultTextBuilder.cpp UserInterface/RiuMainWindow.cpp UserInterface/RiuResultInfoPanel.cpp UserInterface/RiuViewer.cpp @@ -166,6 +167,7 @@ list( REMOVE_ITEM RAW_SOURCES UserInterface/RiuSimpleHistogramWidget.cpp UserInterface/RiuMultiCaseImportDialog.cpp + UserInterface/RiuResultTextBuilder.cpp ) include( CustomPCH.cmake ) diff --git a/ApplicationCode/FileInterface/CMakeLists_files.cmake b/ApplicationCode/FileInterface/CMakeLists_files.cmake index 1ddd99f08a..34a6ec93be 100644 --- a/ApplicationCode/FileInterface/CMakeLists_files.cmake +++ b/ApplicationCode/FileInterface/CMakeLists_files.cmake @@ -15,6 +15,7 @@ ${CEE_CURRENT_LIST_DIR}RifReaderEclipseOutput.h ${CEE_CURRENT_LIST_DIR}RifJsonEncodeDecode.h ${CEE_CURRENT_LIST_DIR}RifReaderInterface.h ${CEE_CURRENT_LIST_DIR}RifReaderMockModel.h +${CEE_CURRENT_LIST_DIR}RifReaderSettings.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -26,7 +27,9 @@ ${CEE_CURRENT_LIST_DIR}RifEclipseUnifiedRestartFileAccess.cpp ${CEE_CURRENT_LIST_DIR}RifReaderEclipseInput.cpp ${CEE_CURRENT_LIST_DIR}RifReaderEclipseOutput.cpp ${CEE_CURRENT_LIST_DIR}RifJsonEncodeDecode.cpp +${CEE_CURRENT_LIST_DIR}RifReaderInterface.cpp ${CEE_CURRENT_LIST_DIR}RifReaderMockModel.cpp +${CEE_CURRENT_LIST_DIR}RifReaderSettings.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/FileInterface/FileInterface_UnitTests/CMakeLists.txt b/ApplicationCode/FileInterface/FileInterface_UnitTests/CMakeLists.txt index 475f353da7..092d8d9098 100644 --- a/ApplicationCode/FileInterface/FileInterface_UnitTests/CMakeLists.txt +++ b/ApplicationCode/FileInterface/FileInterface_UnitTests/CMakeLists.txt @@ -59,6 +59,7 @@ set( UNIT_TEST_CPP_SOURCES ) set( LINK_LIBRARIES + cafProjectDataModel CommonCode LibViewing diff --git a/ApplicationCode/FileInterface/FileInterface_UnitTests/Ert-Test.cpp b/ApplicationCode/FileInterface/FileInterface_UnitTests/Ert-Test.cpp index daf5299eae..bdb0ce65ce 100644 --- a/ApplicationCode/FileInterface/FileInterface_UnitTests/Ert-Test.cpp +++ b/ApplicationCode/FileInterface/FileInterface_UnitTests/Ert-Test.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/FileInterface/FileInterface_UnitTests/RifReaderEclipseOutput-Test.cpp b/ApplicationCode/FileInterface/FileInterface_UnitTests/RifReaderEclipseOutput-Test.cpp index d1fbe43b49..5c7b451bbb 100644 --- a/ApplicationCode/FileInterface/FileInterface_UnitTests/RifReaderEclipseOutput-Test.cpp +++ b/ApplicationCode/FileInterface/FileInterface_UnitTests/RifReaderEclipseOutput-Test.cpp @@ -1,8 +1,8 @@ - - ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -27,23 +27,81 @@ #include "ecl_file.h" #include "RifEclipseOutputFileTools.h" #include "RigCaseCellResultsData.h" +#include "RifEclipseUnifiedRestartFileAccess.h" +#include "RifReaderSettings.h" +#if 0 -#if 0 +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigReservoirTest, DISABLED_BasicTest) +{ + + cvf::ref readerInterfaceEcl = new RifReaderEclipseOutput; + cvf::ref reservoir = new RigCaseData; + + QString filename("d:/Models/Statoil/troll_MSW/T07-4A-W2012-16-F3.EGRID"); + + RifReaderSettings readerSettings; + readerInterfaceEcl->setReaderSetting(&readerSettings); + + bool result = readerInterfaceEcl->open(filename, reservoir.p()); + EXPECT_TRUE(result); + + { +// QStringList staticResults = readerInterfaceEcl->staticResults(); +// EXPECT_EQ(42, staticResults.size()); +// qDebug() << "Static results\n" << staticResults; +// +// QStringList dynamicResults = readerInterfaceEcl->dynamicResults(); +// EXPECT_EQ(23, dynamicResults.size()); +// qDebug() << "Dynamic results\n" << dynamicResults; +// +// int numTimeSteps = static_cast(readerInterfaceEcl->numTimeSteps()); +// EXPECT_EQ(9, numTimeSteps); +// +// QStringList timeStepText = readerInterfaceEcl->timeStepText(); +// EXPECT_EQ(numTimeSteps, timeStepText.size()); +// qDebug() << "Time step texts\n" << timeStepText; + } + + + readerInterfaceEcl->close(); + + { +// QStringList staticResults = readerInterfaceEcl->staticResults(); +// EXPECT_EQ(0, staticResults.size()); +// +// QStringList dynamicResults = readerInterfaceEcl->dynamicResults(); +// EXPECT_EQ(0, dynamicResults.size()); +// +// int numTimeSteps = static_cast(readerInterfaceEcl->numTimeSteps()); +// EXPECT_EQ(0, numTimeSteps); +// +// QStringList timeStepText = readerInterfaceEcl->timeStepText(); +// EXPECT_EQ(numTimeSteps, timeStepText.size()); + } +} -TEST(RigReservoirTest, FileOutputToolsTest) + + +TEST(RigReservoirTest, DISABLED_FileOutputToolsTest) { - cvf::ref readerInterfaceEcl = new RifReaderEclipseOutput; - cvf::ref reservoir = new RigReservoir; + cvf::DebugTimer timer("test"); + // QString filename("d:/Models/Statoil/testcase_juli_2011/data/TEST10K_FLT_LGR_NNC.EGRID"); - QString filename("d:/Models/Statoil/testcase_juli_2011/data/TEST10K_FLT_LGR_NNC.UNRST"); +// QString filename("d:/Models/Statoil/testcase_juli_2011/data/TEST10K_FLT_LGR_NNC.UNRST"); +// QString filename("d:/Models/Statoil/troll_MSW/T07-4A-W2012-16-F3.UNRST"); + QString filename("c:/tmp/troll_MSW/T07-4A-W2012-16-F3.UNRST"); + - ecl_file_type* ertFile = ecl_file_open(filename.toAscii().data()); + ecl_file_type* ertFile = ecl_file_open(filename.toAscii().data(), ECL_FILE_CLOSE_STREAM); EXPECT_TRUE(ertFile); @@ -53,7 +111,6 @@ TEST(RigReservoirTest, FileOutputToolsTest) EXPECT_TRUE(keywords.size() == keywordDataItemCounts.size()); - qDebug() << "Keyword - Number of data items"; for (int i = 0; i < keywords.size(); i++) { @@ -63,9 +120,60 @@ TEST(RigReservoirTest, FileOutputToolsTest) ecl_file_close(ertFile); ertFile = NULL; + + timer.reportTime(); + //qDebug() << timer.lapt; } +TEST(RigReservoirTest, UnifiedTestFile) +{ + //QString filename("d:/Models/Statoil/testcase_juli_2011/data/TEST10K_FLT_LGR_NNC.UNRST"); + QString filename("d:/Models/Statoil/troll_MSW/T07-4A-W2012-16-F3.UNRST"); + + { + cvf::ref restartFile = new RifEclipseUnifiedRestartFileAccess(); + + QStringList fileNameList; + fileNameList << filename; + restartFile->setRestartFiles(fileNameList); + restartFile->open(); + + QStringList resultNames; + std::vector resultDataItemCounts; + restartFile->resultNames(&resultNames, &resultDataItemCounts); + + qDebug() << "Result names\n"; + for (int i = 0; i < resultNames.size(); i++) + { + qDebug() << resultNames[i] << "\t" << resultDataItemCounts[i]; + } + + std::vector tsteps = restartFile->timeSteps(); + + qDebug() << "Time step texts\n"; + for (int i = 0; i < tsteps.size(); i++) + { + qDebug() << tsteps[i].toString(); + } + + /* + std::vector resultValues; + size_t timeStep = 0; + restartFile->results(resultNames[0], timeStep, &resultValues); + + size_t i; + for (i = 0; i < 500; i++) + { + qDebug() << resultValues[i]; + } + */ + } + +} + + + void buildResultInfoString(RigReservoir* reservoir, RifReaderInterface::PorosityModelResultType porosityModel, RimDefines::ResultCatType resultType) { RigCaseCellResultsData* matrixResults = reservoir->results(porosityModel); diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp index 5feeb2908c..cb9264ea6a 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -21,6 +23,7 @@ #include "RifReaderEclipseOutput.h" #include "RigCaseCellResultsData.h" #include "RigCaseData.h" +#include "RigResultAccessorFactory.h" #include "cafProgressInfo.h" @@ -73,6 +76,8 @@ bool readDoubleValues(RigCaseData* reservoir, size_t resultIndex, ecl_kw_type* e newPropertyData.push_back(std::vector()); newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL); ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data()); + + return true; } //-------------------------------------------------------------------------------------------------- @@ -86,17 +91,17 @@ bool readDoubleValuesForActiveCells(RigCaseData* reservoir, size_t resultIndex, newPropertyData.push_back(std::vector()); RigActiveCellInfo* activeCellInfo = reservoir->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); - if (activeCellInfo->globalCellCount() > 0 && activeCellInfo->globalCellCount() != activeCellInfo->globalActiveCellCount()) + if (activeCellInfo->reservoirCellCount() > 0 && activeCellInfo->reservoirCellCount() != activeCellInfo->reservoirActiveCellCount()) { std::vector valuesAllCells; valuesAllCells.resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL); ecl_kw_get_data_as_double(eclKeyWordData, valuesAllCells.data()); - newPropertyData[0].resize(activeCellInfo->globalActiveCellCount(), HUGE_VAL); + newPropertyData[0].resize(activeCellInfo->reservoirActiveCellCount(), HUGE_VAL); std::vector& valuesActiveCells = newPropertyData[0]; size_t acIdx = 0; - for (size_t gcIdx = 0; gcIdx < activeCellInfo->globalCellCount(); gcIdx++) + for (size_t gcIdx = 0; gcIdx < activeCellInfo->reservoirCellCount(); gcIdx++) { size_t activeCellResultIndex = activeCellInfo->cellResultIndex(gcIdx); if (activeCellResultIndex != cvf::UNDEFINED_SIZE_T) @@ -110,6 +115,8 @@ bool readDoubleValuesForActiveCells(RigCaseData* reservoir, size_t resultIndex, newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL); ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data()); } + + return true; } @@ -496,8 +503,8 @@ bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileNa return false; } - cvf::ref dataAccessObject = eclipseCase->dataAccessObject(eclipseCase->mainGrid(), porosityModel, timeStep, resultIndex); - if (dataAccessObject.isNull()) + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, eclipseCase->mainGrid()->gridIndex(), porosityModel, timeStep, resultName); + if (resultAccessor.isNull()) { return false; } @@ -510,7 +517,7 @@ bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileNa { for (i = 0; i < eclipseCase->mainGrid()->cellCountI(); i++) { - double resultValue = dataAccessObject->cellScalar(eclipseCase->mainGrid()->cellIndexFromIJK(i, j, k)); + double resultValue = resultAccessor->cellScalar(eclipseCase->mainGrid()->cellIndexFromIJK(i, j, k)); if (resultValue == HUGE_VAL) { resultValue = undefinedValue; @@ -819,9 +826,11 @@ bool RifEclipseInputFileTools::readFaultsAndParseIncludeStatementsRecursively(QF } else if (line.startsWith(faultsKeyword, Qt::CaseInsensitive)) { - readFaults(file, file.pos(), faults, isEditKeywordDetected); - - filenamesWithFaults.push_back(file.fileName()); + if (!line.contains("/")) + { + readFaults(file, file.pos(), faults, isEditKeywordDetected); + filenamesWithFaults.push_back(file.fileName()); + } } if (isEditKeywordDetected && *isEditKeywordDetected) @@ -839,6 +848,18 @@ bool RifEclipseInputFileTools::readFaultsAndParseIncludeStatementsRecursively(QF return true; } +cvf::StructGridInterface::FaceEnum RifEclipseInputFileTools::faceEnumFromText(const QString& faceString) +{ + if (faceString == "X" ) return cvf::StructGridInterface::POS_I; + if (faceString == "X-") return cvf::StructGridInterface::NEG_I; + if (faceString == "Y" ) return cvf::StructGridInterface::POS_J; + if (faceString == "Y-") return cvf::StructGridInterface::NEG_J; + if (faceString == "Z" ) return cvf::StructGridInterface::POS_K; + if (faceString == "Z-") return cvf::StructGridInterface::NEG_K; + + return cvf::StructGridInterface::NO_FACE; +} + //-------------------------------------------------------------------------------------------------- /// The file pointer is pointing at the line following the FAULTS keyword. /// Parse content of this keyword until end of file or @@ -905,9 +926,11 @@ void RifEclipseInputFileTools::readFaults(QFile &data, qint64 filePos, cvf::Coll QString faceString = entries[7]; faceString.remove("'"); - cvf::StructGridInterface::FaceEnum cellFaceEnum = cvf::StructGridInterface::FaceEnum::fromText(faceString); + cvf::StructGridInterface::FaceEnum cellFaceEnum = RifEclipseInputFileTools::faceEnumFromText(faceString); - cvf::CellRange cellrange(i1 - 1, j1 - 1, k1 - 1, i2 - 1, j2 - 1, k2 - 1); // Adjust from 1-based to 0-based cell indices + // Adjust from 1-based to 0-based cell indices + // Guard against invalid cell ranges by limiting lowest possible range value to zero + cvf::CellRange cellrange(CVF_MAX(i1 - 1, 0), CVF_MAX(j1 - 1, 0), CVF_MAX(k1 - 1, 0), CVF_MAX(i2 - 1, 0), CVF_MAX(j2 - 1, 0), CVF_MAX(k2 - 1, 0)); if (!(fault && fault->name() == name)) { diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.h b/ApplicationCode/FileInterface/RifEclipseInputFileTools.h index 2ee6f34de1..461c5aeee9 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.h +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -82,4 +84,5 @@ class RifEclipseInputFileTools : public cvf::Object static qint64 findKeyword(const QString& keyword, QFile& file, qint64 startPos); + static cvf::StructGridInterface::FaceEnum faceEnumFromText(const QString& faceString); }; diff --git a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp index ee46809f05..0bf35563c4 100644 --- a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -329,3 +331,26 @@ void RifEclipseOutputFileTools::readGridDimensions(const QString& gridFileName, stringlist_free( lgr_names ); } + +//-------------------------------------------------------------------------------------------------- +/// Returns the following integer values from the first INTEHEAD keyword found +/// 1 : METRIC +/// 2 : FIELD +/// 3 : LAB +/// -1 : No INTEHEAD keyword found +//-------------------------------------------------------------------------------------------------- +int RifEclipseOutputFileTools::readUnitsType(ecl_file_type* ecl_file) +{ + int unitsType = -1; + + if (ecl_file) + { + ecl_kw_type* kwINTEHEAD = ecl_file_iget_named_kw(ecl_file, INTEHEAD_KW, 0); + if (kwINTEHEAD) + { + unitsType = ecl_kw_iget_int(kwINTEHEAD, INTEHEAD_UNIT_INDEX); + } + } + + return unitsType; +} diff --git a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h index a46c83e4b9..8b6abcde5a 100644 --- a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h +++ b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -56,4 +58,6 @@ class RifEclipseOutputFileTools static QStringList filterFileNamesOfType(const QStringList& fileSet, ecl_file_enum fileType); static void readGridDimensions(const QString& gridFileName, std::vector< std::vector >& gridDimensions); + + static int readUnitsType(ecl_file_type* ecl_file); }; diff --git a/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h b/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h index 757e324e02..81bfc31819 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h +++ b/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -54,4 +56,5 @@ class RifEclipseRestartDataAccess : public cvf::Object virtual bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values) = 0; virtual void readWellData(well_info_type * well_info) = 0; + virtual int readUnitsType() = 0; }; diff --git a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp index 0c105ad4f5..ff838c57ff 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp +++ b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -240,3 +242,19 @@ void RifEclipseRestartFilesetAccess::openTimeStep(size_t timeStep) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RifEclipseRestartFilesetAccess::readUnitsType() +{ + ecl_file_type* ecl_file = NULL; + + if (m_ecl_files.size() > 0) + { + openTimeStep(0); + ecl_file = m_ecl_files[0]; + } + + return RifEclipseOutputFileTools::readUnitsType(ecl_file); +} + diff --git a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h index 645f641fc4..3bcbee647d 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h +++ b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -47,6 +49,7 @@ class RifEclipseRestartFilesetAccess : public RifEclipseRestartDataAccess bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values); virtual void readWellData(well_info_type* well_info); + virtual int readUnitsType(); private: void openTimeStep(size_t timeStep); diff --git a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.cpp b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.cpp index 20c26e7caa..43159f8f56 100644 --- a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.cpp +++ b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -163,3 +165,13 @@ void RifEclipseUnifiedRestartFileAccess::setRestartFiles(const QStringList& file } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RifEclipseUnifiedRestartFileAccess::readUnitsType() +{ + openFile(); + + return RifEclipseOutputFileTools::readUnitsType(m_ecl_file); +} + diff --git a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h index 066f685153..fd2e85bee8 100644 --- a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h +++ b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -48,6 +50,7 @@ class RifEclipseUnifiedRestartFileAccess : public RifEclipseRestartDataAccess bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values); virtual void readWellData(well_info_type * well_info); + virtual int readUnitsType(); private: bool openFile(); diff --git a/ApplicationCode/FileInterface/RifReaderEclipseInput.cpp b/ApplicationCode/FileInterface/RifReaderEclipseInput.cpp index 8e74e59068..2f6ff3f235 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseInput.cpp +++ b/ApplicationCode/FileInterface/RifReaderEclipseInput.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp b/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp index e9cb4e2918..40b0ea6e12 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp +++ b/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,28 +18,29 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "cvfBase.h" +#include "RifReaderEclipseOutput.h" -#include "RigMainGrid.h" -#include "RigCaseData.h" #include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigMainGrid.h" -#include "RifReaderEclipseOutput.h" +#include "RifEclipseInputFileTools.h" #include "RifEclipseOutputFileTools.h" -#include "RifEclipseUnifiedRestartFileAccess.h" #include "RifEclipseRestartFilesetAccess.h" +#include "RifEclipseUnifiedRestartFileAccess.h" #include "RifReaderInterface.h" -#include +#include "cafProgressInfo.h" #include "ecl_grid.h" #include "well_state.h" #include "ecl_kw_magic.h" #include "ecl_nnc_export.h" -#include "cafProgressInfo.h" +#include #include -#include "RifEclipseInputFileTools.h" +#include // Needed for HUGE_VAL on Linux + //-------------------------------------------------------------------------------------------------- /// ECLIPSE cell numbering layout: @@ -112,29 +115,29 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigActiveCellInfo* activeCellIn // Loop over cells and fill them with data #pragma omp parallel for - for (int localCellIdx = 0; localCellIdx < cellCount; ++localCellIdx) + for (int gridLocalCellIndex = 0; gridLocalCellIndex < cellCount; ++gridLocalCellIndex) { - RigCell& cell = mainGrid->cells()[cellStartIndex + localCellIdx]; + RigCell& cell = mainGrid->cells()[cellStartIndex + gridLocalCellIndex]; - cell.setCellIndex(localCellIdx); + cell.setGridLocalCellIndex(gridLocalCellIndex); // Active cell index - int matrixActiveIndex = ecl_grid_get_active_index1(localEclGrid, localCellIdx); + int matrixActiveIndex = ecl_grid_get_active_index1(localEclGrid, gridLocalCellIndex); if (matrixActiveIndex != -1) { - activeCellInfo->setCellResultIndex(cellStartIndex + localCellIdx, matrixActiveStartIndex + matrixActiveIndex); + activeCellInfo->setCellResultIndex(cellStartIndex + gridLocalCellIndex, matrixActiveStartIndex + matrixActiveIndex); } - int fractureActiveIndex = ecl_grid_get_active_fracture_index1(localEclGrid, localCellIdx); + int fractureActiveIndex = ecl_grid_get_active_fracture_index1(localEclGrid, gridLocalCellIndex); if (fractureActiveIndex != -1) { - fractureActiveCellInfo->setCellResultIndex(cellStartIndex + localCellIdx, fractureActiveStartIndex + fractureActiveIndex); + fractureActiveCellInfo->setCellResultIndex(cellStartIndex + gridLocalCellIndex, fractureActiveStartIndex + fractureActiveIndex); } // Parent cell index - int parentCellIndex = ecl_grid_get_parent_cell1(localEclGrid, localCellIdx); + int parentCellIndex = ecl_grid_get_parent_cell1(localEclGrid, gridLocalCellIndex); if (parentCellIndex == -1) { cell.setParentCellIndex(cvf::UNDEFINED_SIZE_T); @@ -148,14 +151,14 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigActiveCellInfo* activeCellIn int cIdx; for (cIdx = 0; cIdx < 8; ++cIdx) { - double * point = mainGrid->nodes()[nodeStartIndex + localCellIdx * 8 + cellMappingECLRi[cIdx]].ptr(); - ecl_grid_get_corner_xyz1(localEclGrid, localCellIdx, cIdx, &(point[0]), &(point[1]), &(point[2])); + double * point = mainGrid->nodes()[nodeStartIndex + gridLocalCellIndex * 8 + cellMappingECLRi[cIdx]].ptr(); + ecl_grid_get_corner_xyz1(localEclGrid, gridLocalCellIndex, cIdx, &(point[0]), &(point[1]), &(point[2])); point[2] = -point[2]; // Flipping Z making depth become negative z values - cell.cornerIndices()[cIdx] = nodeStartIndex + localCellIdx*8 + cIdx; + cell.cornerIndices()[cIdx] = nodeStartIndex + gridLocalCellIndex*8 + cIdx; } // Sub grid in cell - const ecl_grid_type* subGrid = ecl_grid_get_cell_lgr1(localEclGrid, localCellIdx); + const ecl_grid_type* subGrid = ecl_grid_get_cell_lgr1(localEclGrid, gridLocalCellIndex); if (subGrid != NULL) { int subGridId = ecl_grid_get_lgr_nr(subGrid); @@ -287,8 +290,8 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, totalCellCount += ecl_grid_get_global_size(localEclGrid); } - activeCellInfo->setGlobalCellCount(totalCellCount); - fractureActiveCellInfo->setGlobalCellCount(totalCellCount); + activeCellInfo->setReservoirCellCount(totalCellCount); + fractureActiveCellInfo->setReservoirCellCount(totalCellCount); // Reserve room for the cells and nodes and fill them with data @@ -434,17 +437,26 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigCaseData* eclipseC progInfo.setProgressDescription("Reading NNC data"); progInfo.setNextProgressIncrement(5); - transferNNCData(mainEclGrid, m_ecl_init_file, eclipseCase->mainGrid()); + if (isNNCsEnabled()) + { + transferNNCData(mainEclGrid, m_ecl_init_file, eclipseCase->mainGrid()); + } progInfo.incrementProgress(); progInfo.setProgressDescription("Processing NNC data"); progInfo.setNextProgressIncrement(20); - eclipseCase->mainGrid()->nncData()->processConnections( *(eclipseCase->mainGrid())); + if (isNNCsEnabled()) + { + eclipseCase->mainGrid()->nncData()->processConnections( *(eclipseCase->mainGrid())); + } progInfo.incrementProgress(); progInfo.setNextProgressIncrement(8); progInfo.setProgressDescription("Reading Well information"); - readWellCells(mainEclGrid); + if (isSimulationWellDataEnabled()) + { + readWellCells(mainEclGrid); + } progInfo.setProgressDescription("Releasing reader memory"); ecl_grid_free( mainEclGrid ); @@ -470,13 +482,14 @@ void RifReaderEclipseOutput::transferNNCData( const ecl_grid_type * mainEclGrid //cvf::Trace::show("Reading NNC. Count: " + cvf::String(numNNC)); mainGrid->nncData()->connections().resize(numNNC); + std::vector& transmissibilityValues = mainGrid->nncData()->makeConnectionScalarResult(cvf::UNDEFINED_SIZE_T); for (int nIdx = 0; nIdx < numNNC; ++nIdx) { RigGridBase* grid1 = mainGrid->gridByIndex(eclNNCData[nIdx].grid_nr1); - mainGrid->nncData()->connections()[nIdx].m_c1GlobIdx = grid1->globalGridCellIndex(eclNNCData[nIdx].global_index1); + mainGrid->nncData()->connections()[nIdx].m_c1GlobIdx = grid1->reservoirCellIndex(eclNNCData[nIdx].global_index1); RigGridBase* grid2 = mainGrid->gridByIndex(eclNNCData[nIdx].grid_nr2); - mainGrid->nncData()->connections()[nIdx].m_c2GlobIdx = grid2->globalGridCellIndex(eclNNCData[nIdx].global_index2); - mainGrid->nncData()->connections()[nIdx].m_transmissibility = eclNNCData[nIdx].trans; + mainGrid->nncData()->connections()[nIdx].m_c2GlobIdx = grid2->reservoirCellIndex(eclNNCData[nIdx].global_index2); + transmissibilityValues[nIdx] = eclNNCData[nIdx].trans; } @@ -544,16 +557,16 @@ bool RifReaderEclipseOutput::readActiveCellInfo() std::vector > actnumValuesPerGrid; actnumValuesPerGrid.resize(actnumKeywordCount); - size_t globalCellCount = 0; + size_t reservoirCellCount = 0; for (size_t gridIdx = 0; gridIdx < static_cast(actnumKeywordCount); gridIdx++) { RifEclipseOutputFileTools::keywordData(ecl_file, ACTNUM_KW, gridIdx, &actnumValuesPerGrid[gridIdx]); - globalCellCount += actnumValuesPerGrid[gridIdx].size(); + reservoirCellCount += actnumValuesPerGrid[gridIdx].size(); } // Check if number of cells is matching - if (m_eclipseCase->mainGrid()->cells().size() != globalCellCount) + if (m_eclipseCase->mainGrid()->cells().size() != reservoirCellCount) { return false; } @@ -561,8 +574,8 @@ bool RifReaderEclipseOutput::readActiveCellInfo() RigActiveCellInfo* activeCellInfo = m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); RigActiveCellInfo* fractureActiveCellInfo = m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS); - activeCellInfo->setGlobalCellCount(globalCellCount); - fractureActiveCellInfo->setGlobalCellCount(globalCellCount); + activeCellInfo->setReservoirCellCount(reservoirCellCount); + fractureActiveCellInfo->setReservoirCellCount(reservoirCellCount); activeCellInfo->setGridCount(actnumKeywordCount); fractureActiveCellInfo->setGridCount(actnumKeywordCount); @@ -666,6 +679,22 @@ void RifReaderEclipseOutput::buildMetaData() fractureModelResults->setTimeStepDates(resIndex, m_timeSteps); } } + + // Default units type is METRIC + RigCaseData::UnitsType unitsType = RigCaseData::UNITS_METRIC; + { + int unitsTypeValue = m_dynamicResultsAccess->readUnitsType(); + if (unitsTypeValue == 2) + { + unitsType = RigCaseData::UNITS_FIELD; + } + else if (unitsTypeValue == 3) + { + unitsType = RigCaseData::UNITS_LAB; + } + } + + m_eclipseCase->setUnitsType(unitsType); } progInfo.incrementProgress(); @@ -764,7 +793,7 @@ bool RifReaderEclipseOutput::staticResult(const QString& result, PorosityModelRe if (result.compare("ACTNUM", Qt::CaseInsensitive) == 0) { RigActiveCellInfo* activeCellInfo = m_eclipseCase->activeCellInfo(matrixOrFracture); - values->resize(activeCellInfo->globalActiveCellCount(), 1.0); + values->resize(activeCellInfo->reservoirActiveCellCount(), 1.0); return true; } @@ -1542,7 +1571,7 @@ QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel(const QStringL if (matrixOrFracture == RifReaderInterface::FRACTURE_RESULTS) { - if (fractureActiveCellInfo->globalActiveCellCount() == 0) + if (fractureActiveCellInfo->reservoirActiveCellCount() == 0) { return QStringList(); } @@ -1555,16 +1584,16 @@ QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel(const QStringL QString keyword = keywords[i]; size_t keywordDataCount = keywordDataItemCounts[i]; - if (activeCellInfo->globalActiveCellCount() > 0) + if (activeCellInfo->reservoirActiveCellCount() > 0) { - size_t timeStepsAllCells = keywordDataItemCounts[i] / activeCellInfo->globalCellCount(); - size_t timeStepsAllCellsRest = keywordDataItemCounts[i] % activeCellInfo->globalCellCount(); + size_t timeStepsAllCells = keywordDataItemCounts[i] / activeCellInfo->reservoirCellCount(); + size_t timeStepsAllCellsRest = keywordDataItemCounts[i] % activeCellInfo->reservoirCellCount(); - size_t timeStepsMatrix = keywordDataItemCounts[i] / activeCellInfo->globalActiveCellCount(); - size_t timeStepsMatrixRest = keywordDataItemCounts[i] % activeCellInfo->globalActiveCellCount(); + size_t timeStepsMatrix = keywordDataItemCounts[i] / activeCellInfo->reservoirActiveCellCount(); + size_t timeStepsMatrixRest = keywordDataItemCounts[i] % activeCellInfo->reservoirActiveCellCount(); - size_t timeStepsMatrixAndFracture = keywordDataItemCounts[i] / (activeCellInfo->globalActiveCellCount() + fractureActiveCellInfo->globalActiveCellCount()); - size_t timeStepsMatrixAndFractureRest = keywordDataItemCounts[i] % (activeCellInfo->globalActiveCellCount() + fractureActiveCellInfo->globalActiveCellCount()); + size_t timeStepsMatrixAndFracture = keywordDataItemCounts[i] / (activeCellInfo->reservoirActiveCellCount() + fractureActiveCellInfo->reservoirActiveCellCount()); + size_t timeStepsMatrixAndFractureRest = keywordDataItemCounts[i] % (activeCellInfo->reservoirActiveCellCount() + fractureActiveCellInfo->reservoirActiveCellCount()); if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS) { @@ -1611,7 +1640,7 @@ void RifReaderEclipseOutput::extractResultValuesBasedOnPorosityModel(PorosityMod RigActiveCellInfo* fracActCellInfo = m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS); - if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS && fracActCellInfo->globalActiveCellCount() == 0) + if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS && fracActCellInfo->reservoirActiveCellCount() == 0) { destinationResultValues->insert(destinationResultValues->end(), sourceResultValues.begin(), sourceResultValues.end()); } diff --git a/ApplicationCode/FileInterface/RifReaderEclipseOutput.h b/ApplicationCode/FileInterface/RifReaderEclipseOutput.h index 4f2668f162..5ee457471f 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseOutput.h +++ b/ApplicationCode/FileInterface/RifReaderEclipseOutput.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/FileInterface/RifReaderInterface.cpp b/ApplicationCode/FileInterface/RifReaderInterface.cpp new file mode 100644 index 0000000000..0c2c852827 --- /dev/null +++ b/ApplicationCode/FileInterface/RifReaderInterface.cpp @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RifReaderInterface.h" + +#include "RifReaderSettings.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderInterface::setReaderSetting(RifReaderSettings* settings) +{ + m_settings = settings; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifReaderInterface::isFaultImportEnabled() +{ + if (m_settings.notNull()) + { + return m_settings->importFaults; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifReaderInterface::isSimulationWellDataEnabled() +{ + if (m_settings.notNull()) + { + return m_settings->importSimulationWellData; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifReaderInterface::isNNCsEnabled() +{ + if (m_settings.notNull()) + { + return m_settings->importNNCs; + } + + return false; +} diff --git a/ApplicationCode/FileInterface/RifReaderInterface.h b/ApplicationCode/FileInterface/RifReaderInterface.h index b57a8d4976..8ec215f5de 100644 --- a/ApplicationCode/FileInterface/RifReaderInterface.h +++ b/ApplicationCode/FileInterface/RifReaderInterface.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,12 +24,16 @@ #include "cvfObject.h" #include "cvfLibCore.h" +#include "cafPdmPointer.h" + #include #include #include class RigCaseData; +class RifReaderSettings; + //================================================================================================== // @@ -44,11 +50,14 @@ class RifReaderInterface : public cvf::Object }; public: - RifReaderInterface() { m_readFaultData = false; } - virtual ~RifReaderInterface() {} + RifReaderInterface() { } + virtual ~RifReaderInterface() { } + + void setReaderSetting(RifReaderSettings* settings); - void readFaultData(bool readFaultData) { m_readFaultData = readFaultData; } - bool isFaultImportEnabled() { return m_readFaultData; } + bool isFaultImportEnabled(); + bool isSimulationWellDataEnabled(); + bool isNNCsEnabled(); virtual bool open(const QString& fileName, RigCaseData* eclipseCase) = 0; virtual void close() = 0; @@ -63,6 +72,6 @@ class RifReaderInterface : public cvf::Object private: - std::vector m_filenamesWithFaults; - bool m_readFaultData; + std::vector m_filenamesWithFaults; + caf::PdmPointer m_settings; }; diff --git a/ApplicationCode/FileInterface/RifReaderMockModel.cpp b/ApplicationCode/FileInterface/RifReaderMockModel.cpp index 64507ebc8d..0db76f7f25 100644 --- a/ApplicationCode/FileInterface/RifReaderMockModel.cpp +++ b/ApplicationCode/FileInterface/RifReaderMockModel.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/FileInterface/RifReaderMockModel.h b/ApplicationCode/FileInterface/RifReaderMockModel.h index 3acd5a7c7b..dbe4a083ee 100644 --- a/ApplicationCode/FileInterface/RifReaderMockModel.h +++ b/ApplicationCode/FileInterface/RifReaderMockModel.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/FileInterface/RifReaderSettings.cpp b/ApplicationCode/FileInterface/RifReaderSettings.cpp new file mode 100644 index 0000000000..b6d74adaa4 --- /dev/null +++ b/ApplicationCode/FileInterface/RifReaderSettings.cpp @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RifReaderSettings.h" +#include "cafPdmUiCheckBoxEditor.h" + + +CAF_PDM_SOURCE_INIT(RifReaderSettings, "RifReaderSettings"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifReaderSettings::RifReaderSettings() +{ + CAF_PDM_InitObject("RifReaderSettings", "", "", ""); + + CAF_PDM_InitField(&importFaults, "importFaults", true, "Import faults", "", "", ""); + importFaults.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + + CAF_PDM_InitField(&importSimulationWellData, "importSimulationWellData", true, "Import simulation wells", "", "", ""); + importSimulationWellData.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + + CAF_PDM_InitField(&importNNCs, "importSimulationNNCs", true, "Import NNCs", "", "", ""); + importNNCs.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderSettings::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ + if (field == &importFaults || + field == &importSimulationWellData || + field == &importNNCs) + { + caf::PdmUiCheckBoxEditorAttribute* myAttr = static_cast(attribute); + if (myAttr) + { + myAttr->m_useNativeCheckBoxLabel = true; + } + } +} + diff --git a/ApplicationCode/FileInterface/RifReaderSettings.h b/ApplicationCode/FileInterface/RifReaderSettings.h new file mode 100644 index 0000000000..793495ed3f --- /dev/null +++ b/ApplicationCode/FileInterface/RifReaderSettings.h @@ -0,0 +1,47 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "cafPdmField.h" +#include "cafPdmObject.h" + + +//================================================================================================== +/// +/// +//================================================================================================== +class RifReaderSettings : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + + friend class RiaPreferences; + +public: + RifReaderSettings(); + + caf::PdmField importFaults; + caf::PdmField importSimulationWellData; + caf::PdmField importNNCs; + +protected: + virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); + +}; + diff --git a/ApplicationCode/ModelVisualization/CMakeLists_files.cmake b/ApplicationCode/ModelVisualization/CMakeLists_files.cmake index 02509f21c9..fec6bd6869 100644 --- a/ApplicationCode/ModelVisualization/CMakeLists_files.cmake +++ b/ApplicationCode/ModelVisualization/CMakeLists_files.cmake @@ -22,6 +22,14 @@ ${CEE_CURRENT_LIST_DIR}RivWellPathPartMgr.h ${CEE_CURRENT_LIST_DIR}RivWellPathCollectionPartMgr.h ${CEE_CURRENT_LIST_DIR}RivWellPipesPartMgr.h ${CEE_CURRENT_LIST_DIR}RivWellHeadPartMgr.h +${CEE_CURRENT_LIST_DIR}RivResultToTextureMapper.h +${CEE_CURRENT_LIST_DIR}RivTernaryResultToTextureMapper.h +${CEE_CURRENT_LIST_DIR}RivTextureCoordsCreator.h +${CEE_CURRENT_LIST_DIR}RivTernaryScalarMapper.h +${CEE_CURRENT_LIST_DIR}RivTernaryTextureCoordsCreator.h +${CEE_CURRENT_LIST_DIR}RivTernaryScalarMapperEffectGenerator.h +${CEE_CURRENT_LIST_DIR}RivScalarMapperUtils.h +${CEE_CURRENT_LIST_DIR}RivCellEdgeGeometryUtils.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -42,6 +50,12 @@ ${CEE_CURRENT_LIST_DIR}RivWellPathPartMgr.cpp ${CEE_CURRENT_LIST_DIR}RivWellPathCollectionPartMgr.cpp ${CEE_CURRENT_LIST_DIR}RivWellPipesPartMgr.cpp ${CEE_CURRENT_LIST_DIR}RivWellHeadPartMgr.cpp +${CEE_CURRENT_LIST_DIR}RivTextureCoordsCreator.cpp +${CEE_CURRENT_LIST_DIR}RivTernaryScalarMapper.cpp +${CEE_CURRENT_LIST_DIR}RivTernaryTextureCoordsCreator.cpp +${CEE_CURRENT_LIST_DIR}RivTernaryScalarMapperEffectGenerator.cpp +${CEE_CURRENT_LIST_DIR}RivScalarMapperUtils.cpp +${CEE_CURRENT_LIST_DIR}RivCellEdgeGeometryUtils.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/CMakeLists.txt b/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/CMakeLists.txt index 0b0bb00ce8..97e839bfc1 100644 --- a/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/CMakeLists.txt +++ b/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/CMakeLists.txt @@ -19,6 +19,7 @@ include_directories( set( MODEL_VISUALIZATION_CPP_SOURCES ../RivPipeGeometryGenerator.cpp + ../RivTernaryScalarMapper.cpp ) @@ -29,6 +30,7 @@ set( CPP_SOURCES set( UNIT_TEST_CPP_SOURCES main.cpp RivPipeGeometryGenerator-Test.cpp + RivTernaryScalarMapper-Test.cpp ) @@ -37,10 +39,13 @@ set( LINK_LIBRARIES LibRender LibGeometry LibCore + LibGuiQt CommonCode ${OPENGL_LIBRARIES} + ${QT_LIBRARIES} + ) diff --git a/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/RivTernaryScalarMapper-Test.cpp b/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/RivTernaryScalarMapper-Test.cpp new file mode 100644 index 0000000000..579412857c --- /dev/null +++ b/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/RivTernaryScalarMapper-Test.cpp @@ -0,0 +1,103 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "gtest/gtest.h" + +#include "RivTernaryScalarMapper.h" + +#include "cvfTextureImage.h" +#include "cvfqtUtils.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(TernaryScalarMapperTest, BasicFunctions) +{ + cvf::ref scalarMapper = new RivTernaryScalarMapper(cvf::Color3f::GRAY); + + cvf::ref texImage = new cvf::TextureImage; + scalarMapper->updateTexture(texImage.p(), 1.0); + + QImage img = cvfqt::Utils::toQImage(*(texImage.p())); + + img.save("c:/tmp/test.png"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(TernaryScalarMapperTest, TextureMapping) +{ + cvf::ref scalarMapper = new RivTernaryScalarMapper(cvf::Color3f::GRAY); + + // Without opacity + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.0, 0.0, false); + EXPECT_DOUBLE_EQ(0.0, texCoord.x()); + EXPECT_DOUBLE_EQ(0.0, texCoord.y()); + } + + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(1.0, 0.0, false); + EXPECT_DOUBLE_EQ(1.0, texCoord.x()); + EXPECT_DOUBLE_EQ(0.0, texCoord.y()); + } + + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.0, 1.0, false); + EXPECT_DOUBLE_EQ(0.0, texCoord.x()); + EXPECT_DOUBLE_EQ(0.5, texCoord.y()); + } + + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(3.0, 3.0, false); + EXPECT_DOUBLE_EQ(1.0, texCoord.x()); + EXPECT_DOUBLE_EQ(0.0, texCoord.y()); + } + + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(-1.0, -1.0, false); + EXPECT_DOUBLE_EQ(0.0, texCoord.x()); + EXPECT_DOUBLE_EQ(0.0, texCoord.y()); + } + + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.5, 3.0, false); + EXPECT_DOUBLE_EQ(0.5, texCoord.x()); + EXPECT_DOUBLE_EQ(0.25, texCoord.y()); + } + + + + + // Opacity + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.0, 0.0, true); + EXPECT_DOUBLE_EQ(0.0, texCoord.x()); + EXPECT_DOUBLE_EQ(0.5, texCoord.y()); + } + + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.0, 1.0, true); + EXPECT_DOUBLE_EQ(0.0, texCoord.x()); + EXPECT_DOUBLE_EQ(1.0, texCoord.y()); + } +} diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp index b2e37f55bc..3171aad530 100644 --- a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,262 +18,54 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "RivCellEdgeEffectGenerator.h" -#include "cvfBase.h" -#include "cvfAssert.h" -#include "cvfDrawableGeo.h" -#include "cvfVertexAttribute.h" -#include "cvfStructGridGeometryGenerator.h" -#include "cvfScalarMapperUniformLevels.h" +#include "RivTernaryScalarMapper.h" +#include "cvfRenderStateBlending.h" +#include "cvfRenderStateCullFace.h" +#include "cvfRenderStateTextureBindings.h" +#include "cvfSampler.h" +#include "cvfShaderProgram.h" #include "cvfShaderProgramGenerator.h" #include "cvfShaderSourceProvider.h" -#include "cvfqtUtils.h" -#include "cvfShaderProgram.h" -#include "cvfRenderStateCullFace.h" - -#include "cvfTextureImage.h" #include "cvfTexture.h" -#include "cvfSampler.h" -#include "cvfScalarMapper.h" -#include "cafEffectGenerator.h" - -#include +#include "cvfqtUtils.h" #include #include -#include "RimCase.h" - -#include "RimReservoirView.h" -#include "RimResultSlot.h" - -#include "RigGridBase.h" -#include "RigMainGrid.h" -#include "RigCaseCellResultsData.h" -#include "RigCaseData.h" -#include "RigActiveCellInfo.h" - -#include "RimReservoirCellResultsCacher.h" - -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo( - size_t timeStepIndex, - RimResultSlot* cellResultSlot, - RimCellEdgeResultSlot* cellEdgeResultSlot, - cvf::StructGridGeometryGenerator* generator, - cvf::DrawableGeo* geo, - size_t gridIndex, - float opacityLevel) +CellEdgeEffectGenerator::CellEdgeEffectGenerator(const cvf::ScalarMapper* edgeScalarMapper) { - const std::vector& quadToCell = generator->quadToGridCellIndices(); - const std::vector& quadToFace = generator->quadToFace(); - - size_t vertexCount = geo->vertexArray()->size(); - size_t quadCount = vertexCount / 4; - - cvf::ref localCoords = new cvf::Vec2fArray; - localCoords->resize(vertexCount); - - cvf::ref faceIndexArray = new cvf::IntArray; - faceIndexArray->resize(vertexCount); - - cvf::ref cellColorTextureCoordArray = new cvf::FloatArray; - cellColorTextureCoordArray->resize(vertexCount); - - // Build six cell face color arrays - cvf::Collection cellEdgeColorTextureCoordsArrays; - size_t idx; - for (idx = 0; idx < 6; idx++) - { - cvf::ref colorArray = new cvf::FloatArray; - colorArray->resize(vertexCount); - cellEdgeColorTextureCoordsArrays.push_back(colorArray.p()); - } - - cvf::ScalarMapper* cellResultScalarMapper = cellResultSlot->legendConfig()->scalarMapper(); - cvf::ScalarMapper* edgeResultScalarMapper = cellEdgeResultSlot->legendConfig()->scalarMapper(); - - const RigGridBase* grid = dynamic_cast(generator->activeGrid()); - CVF_ASSERT(grid != NULL); - - RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); - CVF_ASSERT(eclipseCase != NULL); - - cvf::ref cellCenterDataAccessObject = NULL; - if (cellResultSlot->hasResult()) - { - if (!cellResultSlot->hasDynamicResult()) - { - // Static result values are located at time step 0 - timeStepIndex = 0; - } - - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); - cellCenterDataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, cellResultSlot->gridScalarIndex()); - } - - CVF_ASSERT(cellEdgeResultSlot->hasResult()); - - size_t resultIndices[6]; - cellEdgeResultSlot->gridScalarIndices(resultIndices); - - cvf::Collection cellEdgeDataAccessObjects; - - size_t cubeFaceIdx; - for (cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) - { - cvf::ref daObj; - - if (resultIndices[cubeFaceIdx] != cvf::UNDEFINED_SIZE_T) - { - // Assuming static values to be mapped onto cell edge, always using time step zero - // TODO: Now hardcoded matrix results, should it be possible to use fracture results? - daObj = eclipseCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, 0, resultIndices[cubeFaceIdx]); - } - - cellEdgeDataAccessObjects.push_back(daObj.p()); - } - - double ignoredScalarValue = cellEdgeResultSlot->ignoredScalarValue(); - - const std::vector* isWellPipeVisible = NULL; - cvf::ref gridCellToWellindexMap; - - if (opacityLevel < 1.0f) - { - isWellPipeVisible = &(cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex)); - gridCellToWellindexMap = eclipseCase->gridCellToWellIndex( gridIndex ); - } - -#pragma omp parallel for - for (int quadIdx = 0; quadIdx < static_cast(quadCount); quadIdx++) - { - localCoords->set(quadIdx * 4 + 0, cvf::Vec2f(0, 0)); - localCoords->set(quadIdx * 4 + 1, cvf::Vec2f(1, 0)); - localCoords->set(quadIdx * 4 + 2, cvf::Vec2f(1, 1)); - localCoords->set(quadIdx * 4 + 3, cvf::Vec2f(0, 1)); - - faceIndexArray->set(quadIdx * 4 + 0, quadToFace[quadIdx] ); - faceIndexArray->set(quadIdx * 4 + 1, quadToFace[quadIdx] ); - faceIndexArray->set(quadIdx * 4 + 2, quadToFace[quadIdx] ); - faceIndexArray->set(quadIdx * 4 + 3, quadToFace[quadIdx] ); - - float cellColorTextureCoord = 0.5f; // If no results exists, the texture will have a special color - size_t cellIndex = quadToCell[quadIdx]; - - { - double scalarValue = HUGE_VAL; - - if (cellCenterDataAccessObject.notNull()) - { - scalarValue = cellCenterDataAccessObject->cellScalar(cellIndex); - } - - if (scalarValue != HUGE_VAL) - { - - cellColorTextureCoord = cellResultScalarMapper->mapToTextureCoord(scalarValue)[0]; - // If we are dealing with wellcells, the default is transparent. - // we need to make cells opaque if there are no wellpipe through them. - if (opacityLevel < 1.0f) - { - cvf::uint wellIndex = gridCellToWellindexMap->get(cellIndex); - if (wellIndex != cvf::UNDEFINED_UINT) - { - if ( !(*isWellPipeVisible)[wellIndex]) - { - cellColorTextureCoord += 2.0f; // The shader must interpret values in the range 2-3 as "opaque" - } - } - } - } - else - { - cellColorTextureCoord = -1.0f; // Undefined texture coord. Shader handles this. - } - } - - cellColorTextureCoordArray->set(quadIdx * 4 + 0, cellColorTextureCoord); - cellColorTextureCoordArray->set(quadIdx * 4 + 1, cellColorTextureCoord); - cellColorTextureCoordArray->set(quadIdx * 4 + 2, cellColorTextureCoord); - cellColorTextureCoordArray->set(quadIdx * 4 + 3, cellColorTextureCoord); - - size_t cubeFaceIdx; - float edgeColor; - for (cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) - { - edgeColor = -1.0f; // Undefined texture coord. Shader handles this. - - double scalarValue = HUGE_VAL; - if (cellEdgeDataAccessObjects[cubeFaceIdx].notNull()) - { - scalarValue = cellEdgeDataAccessObjects[cubeFaceIdx]->cellScalar(cellIndex); - } - - if (scalarValue != HUGE_VAL && scalarValue != ignoredScalarValue) - { - edgeColor = edgeResultScalarMapper->mapToTextureCoord(scalarValue)[0]; - } - - cvf::FloatArray* colArr = cellEdgeColorTextureCoordsArrays.at(cubeFaceIdx); - - colArr->set(quadIdx * 4 + 0, edgeColor); - colArr->set(quadIdx * 4 + 1, edgeColor); - colArr->set(quadIdx * 4 + 2, edgeColor); - colArr->set(quadIdx * 4 + 3, edgeColor); - } - } - - geo->setVertexAttribute(new cvf::Vec2fVertexAttribute("a_localCoord", localCoords.p())); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorCell", cellColorTextureCoordArray.p())); + CVF_ASSERT(edgeScalarMapper != NULL); - cvf::ref faceIntAttribute = new cvf::IntVertexAttributeDirect("a_face", faceIndexArray.p()); - //faceIntAttribute->setIntegerTypeConversion(cvf::VertexAttribute::DIRECT_FLOAT); - geo->setVertexAttribute(faceIntAttribute.p()); + m_edgeScalarMapper = edgeScalarMapper; - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosI", cellEdgeColorTextureCoordsArrays.at(0))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegI", cellEdgeColorTextureCoordsArrays.at(1))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosJ", cellEdgeColorTextureCoordsArrays.at(2))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegJ", cellEdgeColorTextureCoordsArrays.at(3))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosK", cellEdgeColorTextureCoordsArrays.at(4))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegK", cellEdgeColorTextureCoordsArrays.at(5))); + m_cullBackfaces = caf::FC_NONE; + m_opacityLevel = 1.0f; + m_defaultCellColor = cvf::Color3f(cvf::Color3::WHITE); } - - - - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -CellEdgeEffectGenerator::CellEdgeEffectGenerator(const cvf::ScalarMapper* edgeScalarMapper, const cvf::ScalarMapper* cellScalarMapper) +void CellEdgeEffectGenerator::setScalarMapper(const cvf::ScalarMapper* cellScalarMapper) { - CVF_ASSERT(edgeScalarMapper != NULL); - - m_cellScalarMapper = cellScalarMapper; - m_edgeScalarMapper = edgeScalarMapper; - - m_cullBackfaces = false; - m_opacityLevel = 1.0f; - m_defaultCellColor = cvf::Color3f(cvf::Color3::WHITE); + m_cellScalarMapper = cellScalarMapper; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CellEdgeEffectGenerator::setTernaryScalarMapper(const RivTernaryScalarMapper* ternaryScalarMapper) +{ + m_ternaryCellScalarMapper = ternaryScalarMapper; +} //-------------------------------------------------------------------------------------------------- /// @@ -283,7 +77,8 @@ bool CellEdgeEffectGenerator::isEqual(const EffectGenerator* other) const if (otherCellFaceEffectGenerator && m_cellScalarMapper.p() == otherCellFaceEffectGenerator->m_cellScalarMapper.p() && m_edgeScalarMapper.p() == otherCellFaceEffectGenerator->m_edgeScalarMapper.p() - && m_cullBackfaces == otherCellFaceEffectGenerator->m_cullBackfaces + && m_ternaryCellScalarMapper.p() == otherCellFaceEffectGenerator->m_ternaryCellScalarMapper.p() + && m_cullBackfaces == otherCellFaceEffectGenerator->m_cullBackfaces && m_opacityLevel == otherCellFaceEffectGenerator->m_opacityLevel && m_undefinedColor == otherCellFaceEffectGenerator->m_undefinedColor && m_defaultCellColor == otherCellFaceEffectGenerator->m_defaultCellColor @@ -316,12 +111,14 @@ bool CellEdgeEffectGenerator::isEqual(const EffectGenerator* other) const //-------------------------------------------------------------------------------------------------- caf::EffectGenerator* CellEdgeEffectGenerator::copy() const { - CellEdgeEffectGenerator * newEffect = new CellEdgeEffectGenerator(m_edgeScalarMapper.p(), m_cellScalarMapper.p()); + CellEdgeEffectGenerator * newEffect = new CellEdgeEffectGenerator(m_edgeScalarMapper.p()); + newEffect->setScalarMapper(m_cellScalarMapper.p()); + newEffect->setTernaryScalarMapper(m_ternaryCellScalarMapper.p()); newEffect->m_edgeTextureImage = m_edgeTextureImage; newEffect->m_cellTextureImage = m_cellTextureImage; newEffect->setOpacityLevel(m_opacityLevel); - newEffect->setCullBackfaces(m_cullBackfaces); + newEffect->setFaceCulling(m_cullBackfaces); newEffect->setUndefinedColor(m_undefinedColor); newEffect->setDefaultCellColor(m_defaultCellColor); @@ -333,36 +130,54 @@ caf::EffectGenerator* CellEdgeEffectGenerator::copy() const //-------------------------------------------------------------------------------------------------- void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) const { - cvf::ref eff = effect; - - // Set up shader program - - cvf::ShaderProgramGenerator shaderGen("CellEdgeFaceShaderProgramGenerator", cvf::ShaderSourceProvider::instance()); - { - QFile data(":/Shader/fs_CellFace.glsl"); - if (data.open(QFile::ReadOnly)) - { - QTextStream in(&data); - - QString data = in.readAll(); - cvf::String cvfString = cvfqt::Utils::toString(data); - - shaderGen.addFragmentCode(cvfString); - } - } - - { - QFile data(":/Shader/vs_CellFace.glsl"); - if (data.open(QFile::ReadOnly)) - { - QTextStream in(&data); - - QString data = in.readAll(); - cvf::String cvfString = cvfqt::Utils::toString(data); - - shaderGen.addVertexCode(cvfString); - } - } + cvf::ref eff = effect; + + // Set up shader program + + cvf::ShaderProgramGenerator shaderGen("CellEdgeFaceShaderProgramGenerator", cvf::ShaderSourceProvider::instance()); + { + QFile data(":/Shader/fs_CellFace.glsl"); + if (data.open(QFile::ReadOnly)) + { + QTextStream in(&data); + + QString data = in.readAll(); + cvf::String cvfString = cvfqt::Utils::toString(data); + + shaderGen.addFragmentCode(cvfString); + } + } + + if (m_ternaryCellScalarMapper.notNull()) + { + { + QFile data(":/Shader/vs_2dTextureCellFace.glsl"); + if (data.open(QFile::ReadOnly)) + { + QTextStream in(&data); + + QString data = in.readAll(); + cvf::String cvfString = cvfqt::Utils::toString(data); + + shaderGen.addVertexCode(cvfString); + } + } + } + else + { + { + QFile data(":/Shader/vs_CellFace.glsl"); + if (data.open(QFile::ReadOnly)) + { + QTextStream in(&data); + + QString data = in.readAll(); + cvf::String cvfString = cvfqt::Utils::toString(data); + + shaderGen.addVertexCode(cvfString); + } + } + } shaderGen.addFragmentCode(caf::CommonShaderSources::light_AmbientDiffuse()); shaderGen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard); @@ -377,7 +192,12 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) cvf::ref modifiedCellTextImage; m_edgeScalarMapper->updateTexture(m_edgeTextureImage.p()); - if (m_cellScalarMapper.notNull()) + if (m_ternaryCellScalarMapper.notNull()) + { + m_ternaryCellScalarMapper->updateTexture(m_cellTextureImage.p(), m_opacityLevel); + modifiedCellTextImage = m_cellTextureImage; + } + else if (m_cellScalarMapper.notNull()) { m_cellScalarMapper->updateTexture(m_cellTextureImage.p()); modifiedCellTextImage = caf::ScalarMapperEffectGenerator::addAlphaAndUndefStripes(m_cellTextureImage.p(), m_undefinedColor, m_opacityLevel); @@ -419,15 +239,28 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) eff->setRenderState(blender.p()); } - // Backface culling - - if (m_cullBackfaces) + // Face culling + if (m_cullBackfaces != caf::FC_NONE) { cvf::ref faceCulling = new cvf::RenderStateCullFace; - eff->setRenderState(faceCulling.p()); + if (m_cullBackfaces == caf::FC_BACK) + { + faceCulling->setMode(cvf::RenderStateCullFace::BACK); + } + else if (m_cullBackfaces == caf::FC_FRONT) + { + faceCulling->setMode(cvf::RenderStateCullFace::FRONT); + } + else if (m_cullBackfaces == caf::FC_FRONT_AND_BACK) + { + faceCulling->setMode(cvf::RenderStateCullFace::FRONT_AND_BACK); + } + + effect->setRenderState(faceCulling.p()); } } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -438,3 +271,4 @@ void CellEdgeEffectGenerator::updateForFixedFunctionRendering(cvf::Effect* effec surfaceGen.updateEffect(effect); } + diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h index f05d7e1a49..967cc0de12 100644 --- a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h +++ b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,30 +22,76 @@ #include "cafEffectGenerator.h" -namespace cvf -{ - class StructGridGeometryGenerator; - class DrawableGeo; -} +class RivTernaryScalarMapper; -class RimCellEdgeResultSlot; -class RimResultSlot; -class RigGridBase; -class RivCellEdgeGeometryGenerator -{ -public: - static void addCellEdgeResultsToDrawableGeo(size_t timeStepIndex, - RimResultSlot* cellResultSlot, - RimCellEdgeResultSlot* cellEdgeResultSlot, - cvf::StructGridGeometryGenerator* generator, - cvf::DrawableGeo* geo, - size_t gridIndex, - float opacityLevel); -}; +/* + Thoughts on organizing the texture coords generation a bit. + + Conceptually several mappings takes place: + + 1. ResultValues to ResultPointValues <-- Eg. Cell Center values to CellFace Values + 2. ResultPointValues to GeometryPointValues <-- Eg. CellCenter Values to Triangle Vertex + 3. GeometryPointValues to TextureCoordinates/Colors <-- Handled by ScalarMapper + + When evaluating, we normally use the geometry as starting point, as that often is + a subset of the total results/geometry domain. + + To make this efficient, a minimum of internal storage should be used, so we want + to make the mappings as a set of functions called for each (or a few) texture + coordinate positions + + The mapping is then actually accessed in the opposite way of the above, while calculated in the 1-3 order + + Accessing correct values: + GeometryPointIdx->ResultPointIdx->ResultValueIdx + Calculating color: + ResultValue->ResultPointValue->GeometryPointValue->Texture/ColorValue + In ResInsight (for now) + the ResultPointValue will be the same for all the corresponding GeometryPoints, + which means each quadvertex has the same texcoord for all corners. + + Proposal: + ---------- + Let the FaceValue to Face vertex texture coordinate mapping be the same for all. + Extract that from the code floating around. + Create a PrimitiveFaceIdx to CellIdx with Face mapper class that handles the lookup, + created by the geometry generation + + Create separate calculators/mappers/Strategies to create FaceValues from results. + + Test Code + ----------- + // Example code + // 1. CellCenterToCellFace + // 2. CellFace to Quad Corners + // 3. Quad Corner Values to tex coords + + texCoords.resize(m_quadsToGridCells.size()*4); + for (i = 0; i < m_quadsToGridCells.size(); ++i) + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(resultAccessor->cellScalar(m_quadsToGridCells[i])); + ResValue ResPoint To ResValue + texCoords[i*4 + 0] = texCoord; + texCoords[i*4 + 1] = texCoord; + texCoords[i*4 + 2] = texCoord; + texCoords[i*4 + 3] = texCoord; + } + + Texturing needs in ResInsight: + * ScalarMapper + * Handle HugeVal/nan + * PipeCellTransparency + - includes geometry point to cell mapping + * Modify the Scalarmapper Texture + * The domain values to convert pr geometry point + + + +*/ //================================================================================================== // @@ -53,11 +101,14 @@ class RivCellEdgeGeometryGenerator class CellEdgeEffectGenerator : public caf::EffectGenerator { public: - CellEdgeEffectGenerator(const cvf::ScalarMapper* edgeScalarMapper, const cvf::ScalarMapper* cellScalarMapper); + CellEdgeEffectGenerator(const cvf::ScalarMapper* edgeScalarMapper); + + void setScalarMapper(const cvf::ScalarMapper* cellScalarMapper); + void setTernaryScalarMapper(const RivTernaryScalarMapper* ternaryScalarMapper); void setOpacityLevel(float opacity) { m_opacityLevel = cvf::Math::clamp(opacity, 0.0f , 1.0f ); } void setUndefinedColor(cvf::Color3f color) { m_undefinedColor = color; } - void setCullBackfaces(bool cullBackFaces) { m_cullBackfaces = cullBackFaces; } + void setFaceCulling(caf::FaceCulling faceCulling) { m_cullBackfaces = faceCulling; } void setDefaultCellColor(cvf::Color3f color) { m_defaultCellColor = color; } protected: @@ -73,10 +124,11 @@ class CellEdgeEffectGenerator : public caf::EffectGenerator cvf::cref m_cellScalarMapper; mutable cvf::ref m_cellTextureImage; - float m_opacityLevel; - bool m_cullBackfaces; + cvf::cref m_ternaryCellScalarMapper; + + float m_opacityLevel; + caf::FaceCulling m_cullBackfaces; cvf::Color3f m_undefinedColor; cvf::Color3f m_defaultCellColor; - }; diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.cpp b/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.cpp new file mode 100644 index 0000000000..c23b50c919 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.cpp @@ -0,0 +1,344 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RivCellEdgeGeometryUtils.h" + +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigCellEdgeResultAccessor.h" +#include "RigGridBase.h" +#include "RigResultAccessor.h" +#include "RigResultAccessorFactory.h" +#include "RimCase.h" +#include "RimCellEdgeResultSlot.h" +#include "RimReservoirView.h" +#include "RimResultSlot.h" +#include "RimTernaryLegendConfig.h" +#include "RimWellCollection.h" +#include "RivTernaryTextureCoordsCreator.h" + +#include "cvfDrawableGeo.h" +#include "cvfVertexAttribute.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivCellEdgeGeometryUtils::addCellEdgeResultsToDrawableGeo( + size_t timeStepIndex, + RimResultSlot* cellResultSlot, + RimCellEdgeResultSlot* cellEdgeResultSlot, + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, + cvf::DrawableGeo* geo, + size_t gridIndex, + float opacityLevel) +{ + RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); + CVF_ASSERT(eclipseCase != NULL); + + // Create result access objects + + cvf::ref cellCenterDataAccessObject = createCellCenterResultAccessor(cellResultSlot, timeStepIndex, eclipseCase, eclipseCase->grid(gridIndex)); + cvf::ref cellEdgeResultAccessor = createCellEdgeCenterResultAccessor(cellResultSlot, cellEdgeResultSlot, timeStepIndex, eclipseCase, eclipseCase->grid(gridIndex)); + + size_t vertexCount = geo->vertexArray()->size(); + size_t quadCount = vertexCount / 4; + + cvf::ref localCoords = new cvf::Vec2fArray; + localCoords->resize(vertexCount); + + cvf::ref faceIndexArray = new cvf::IntArray; + faceIndexArray->resize(vertexCount); + + cvf::ref cellColorTextureCoordArray = new cvf::FloatArray; + cellColorTextureCoordArray->resize(vertexCount); + + // Build six cell face color arrays + cvf::Collection cellEdgeColorTextureCoordsArrays; + size_t idx; + for (idx = 0; idx < 6; idx++) + { + cvf::ref colorArray = new cvf::FloatArray; + colorArray->resize(vertexCount); + cellEdgeColorTextureCoordsArrays.push_back(colorArray.p()); + } + + cvf::ScalarMapper* cellResultScalarMapper = cellResultSlot->legendConfig()->scalarMapper(); + cvf::ScalarMapper* edgeResultScalarMapper = cellEdgeResultSlot->legendConfig()->scalarMapper(); + + double ignoredScalarValue = cellEdgeResultSlot->ignoredScalarValue(); + + const std::vector* isWellPipeVisible = NULL; + cvf::ref gridCellToWellindexMap; + + if (opacityLevel < 1.0f) + { + isWellPipeVisible = &(cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex)); + gridCellToWellindexMap = eclipseCase->gridCellToWellIndex(gridIndex); + } + +#pragma omp parallel for + for (int quadIdx = 0; quadIdx < static_cast(quadCount); quadIdx++) + { + localCoords->set(quadIdx * 4 + 0, cvf::Vec2f(0, 0)); + localCoords->set(quadIdx * 4 + 1, cvf::Vec2f(1, 0)); + localCoords->set(quadIdx * 4 + 2, cvf::Vec2f(1, 1)); + localCoords->set(quadIdx * 4 + 3, cvf::Vec2f(0, 1)); + + faceIndexArray->set(quadIdx * 4 + 0, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 1, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 2, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 3, quadToCellFaceMapper->cellFace(quadIdx)); + + size_t cellIndex = quadToCellFaceMapper->cellIndex(quadIdx); + { + cvf::StructGridInterface::FaceType cellFace = quadToCellFaceMapper->cellFace(quadIdx); + double scalarValue = cellCenterDataAccessObject->cellFaceScalar(cellIndex, cellFace); + + { + float cellColorTextureCoord = 0.5f; // If no results exists, the texture will have a special color + if (scalarValue != HUGE_VAL) + { + cellColorTextureCoord = cellResultScalarMapper->mapToTextureCoord(scalarValue)[0]; + // If we are dealing with wellcells, the default is transparent. + // we need to make cells opaque if there are no wellpipe through them. + if (opacityLevel < 1.0f) + { + cvf::uint wellIndex = gridCellToWellindexMap->get(cellIndex); + if (wellIndex != cvf::UNDEFINED_UINT) + { + if (!(*isWellPipeVisible)[wellIndex]) + { + cellColorTextureCoord += 2.0f; // The shader must interpret values in the range 2-3 as "opaque" + } + } + } + } + else + { + cellColorTextureCoord = -1.0f; // Undefined texture coord. Shader handles this. + } + + cellColorTextureCoordArray->set(quadIdx * 4 + 0, cellColorTextureCoord); + cellColorTextureCoordArray->set(quadIdx * 4 + 1, cellColorTextureCoord); + cellColorTextureCoordArray->set(quadIdx * 4 + 2, cellColorTextureCoord); + cellColorTextureCoordArray->set(quadIdx * 4 + 3, cellColorTextureCoord); + } + } + + + float edgeColor; + for (size_t cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) + { + edgeColor = -1.0f; // Undefined texture coord. Shader handles this. + + double scalarValue = cellEdgeResultAccessor->cellFaceScalar(cellIndex, static_cast(cubeFaceIdx)); + + if (!hideScalarValue(scalarValue, ignoredScalarValue, 1e-2)) + { + edgeColor = edgeResultScalarMapper->mapToTextureCoord(scalarValue)[0]; + } + + cvf::FloatArray* colArr = cellEdgeColorTextureCoordsArrays.at(cubeFaceIdx); + + colArr->set(quadIdx * 4 + 0, edgeColor); + colArr->set(quadIdx * 4 + 1, edgeColor); + colArr->set(quadIdx * 4 + 2, edgeColor); + colArr->set(quadIdx * 4 + 3, edgeColor); + } + } + + geo->setVertexAttribute(new cvf::Vec2fVertexAttribute("a_localCoord", localCoords.p())); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorCell", cellColorTextureCoordArray.p())); + + cvf::ref faceIntAttribute = new cvf::IntVertexAttributeDirect("a_face", faceIndexArray.p()); + geo->setVertexAttribute(faceIntAttribute.p()); + + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosI", cellEdgeColorTextureCoordsArrays.at(0))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegI", cellEdgeColorTextureCoordsArrays.at(1))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosJ", cellEdgeColorTextureCoordsArrays.at(2))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegJ", cellEdgeColorTextureCoordsArrays.at(3))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosK", cellEdgeColorTextureCoordsArrays.at(4))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegK", cellEdgeColorTextureCoordsArrays.at(5))); +} + +bool RivCellEdgeGeometryUtils::hideScalarValue(double scalarValue, double scalarValueToHide, double tolerance) +{ + return (scalarValue == HUGE_VAL || cvf::Math::abs(scalarValue - scalarValueToHide) <= scalarValueToHide*tolerance); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivCellEdgeGeometryUtils::addTernaryCellEdgeResultsToDrawableGeo(size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot, + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, + cvf::DrawableGeo* geo, size_t gridIndex, float opacityLevel) +{ + RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); + CVF_ASSERT(eclipseCase != NULL); + + cvf::ref cellEdgeResultAccessor = createCellEdgeCenterResultAccessor(cellResultSlot, cellEdgeResultSlot, timeStepIndex, eclipseCase, eclipseCase->grid(gridIndex)); + + size_t vertexCount = geo->vertexArray()->size(); + size_t quadCount = vertexCount / 4; + + cvf::ref localCoords = new cvf::Vec2fArray; + localCoords->resize(vertexCount); + + cvf::ref faceIndexArray = new cvf::IntArray; + faceIndexArray->resize(vertexCount); + + cvf::ref vCellColorTextureCoordArray = new cvf::Vec2fArray; + vCellColorTextureCoordArray->resize(vertexCount); + + // Build six cell face color arrays + cvf::Collection cellEdgeColorTextureCoordsArrays; + size_t idx; + for (idx = 0; idx < 6; idx++) + { + cvf::ref colorArray = new cvf::FloatArray; + colorArray->resize(vertexCount); + cellEdgeColorTextureCoordsArrays.push_back(colorArray.p()); + } + + RivTernaryScalarMapper* ternaryCellResultScalarMapper = cellResultSlot->ternaryLegendConfig()->scalarMapper(); + cvf::ScalarMapper* edgeResultScalarMapper = cellEdgeResultSlot->legendConfig()->scalarMapper(); + + double ignoredScalarValue = cellEdgeResultSlot->ignoredScalarValue(); + + RivTernaryTextureCoordsCreator texturer(cellResultSlot, cellResultSlot->ternaryLegendConfig(), + timeStepIndex, + gridIndex, + quadToCellFaceMapper); + + texturer.createTextureCoords(vCellColorTextureCoordArray.p()); + +#pragma omp parallel for + for (int quadIdx = 0; quadIdx < static_cast(quadCount); quadIdx++) + { + localCoords->set(quadIdx * 4 + 0, cvf::Vec2f(0, 0)); + localCoords->set(quadIdx * 4 + 1, cvf::Vec2f(1, 0)); + localCoords->set(quadIdx * 4 + 2, cvf::Vec2f(1, 1)); + localCoords->set(quadIdx * 4 + 3, cvf::Vec2f(0, 1)); + + faceIndexArray->set(quadIdx * 4 + 0, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 1, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 2, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 3, quadToCellFaceMapper->cellFace(quadIdx)); + + size_t cellIndex = quadToCellFaceMapper->cellIndex(quadIdx); + + float edgeColor; + for (size_t cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) + { + edgeColor = -1.0f; // Undefined texture coord. Shader handles this. + + double scalarValue = cellEdgeResultAccessor->cellFaceScalar(cellIndex, static_cast(cubeFaceIdx)); + + if (!hideScalarValue(scalarValue, ignoredScalarValue, 1e-2)) + { + edgeColor = edgeResultScalarMapper->mapToTextureCoord(scalarValue)[0]; + } + + cvf::FloatArray* colArr = cellEdgeColorTextureCoordsArrays.at(cubeFaceIdx); + + colArr->set(quadIdx * 4 + 0, edgeColor); + colArr->set(quadIdx * 4 + 1, edgeColor); + colArr->set(quadIdx * 4 + 2, edgeColor); + colArr->set(quadIdx * 4 + 3, edgeColor); + } + } + + geo->setVertexAttribute(new cvf::Vec2fVertexAttribute("a_localCoord", localCoords.p())); + geo->setVertexAttribute(new cvf::Vec2fVertexAttribute("a_cellTextureCoord", vCellColorTextureCoordArray.p())); + + cvf::ref faceIntAttribute = new cvf::IntVertexAttributeDirect("a_face", faceIndexArray.p()); + geo->setVertexAttribute(faceIntAttribute.p()); + + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosI", cellEdgeColorTextureCoordsArrays.at(0))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegI", cellEdgeColorTextureCoordsArrays.at(1))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosJ", cellEdgeColorTextureCoordsArrays.at(2))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegJ", cellEdgeColorTextureCoordsArrays.at(3))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosK", cellEdgeColorTextureCoordsArrays.at(4))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegK", cellEdgeColorTextureCoordsArrays.at(5))); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivCellEdgeGeometryUtils::createCellEdgeCenterResultAccessor( + RimResultSlot* cellResultSlot, + RimCellEdgeResultSlot* cellEdgeResultSlot, + size_t timeStepIndex, + RigCaseData* eclipseCase, + const RigGridBase* grid) +{ + cvf::ref cellEdgeResultAccessor = new RigCellEdgeResultAccessor(); + { + size_t resultIndices[6]; + cellEdgeResultSlot->gridScalarIndices(resultIndices); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); + + size_t cubeFaceIdx; + for (cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) + { + // Assuming static values to be mapped onto cell edge, always using time step zero + cvf::ref daObj = RigResultAccessorFactory::createResultAccessor(eclipseCase, grid->gridIndex(), porosityModel, 0, resultIndices[cubeFaceIdx]); + cellEdgeResultAccessor->setDataAccessObjectForFace(static_cast(cubeFaceIdx), daObj.p()); + } + } + + return cellEdgeResultAccessor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivCellEdgeGeometryUtils::createCellCenterResultAccessor(RimResultSlot* cellResultSlot, size_t timeStepIndex, RigCaseData* eclipseCase, const RigGridBase* grid) +{ + cvf::ref resultAccessor = NULL; + + if (cellResultSlot->hasResult()) + { + if (!cellResultSlot->hasDynamicResult()) + { + // Static result values are located at time step 0 + timeStepIndex = 0; + } + + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); + resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, grid->gridIndex(), porosityModel, timeStepIndex, cellResultSlot->resultVariable()); + } + + if (resultAccessor.isNull()) + { + resultAccessor = new RigHugeValResultAccessor; + } + + return resultAccessor; +} + + + + + + + diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.h b/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.h new file mode 100644 index 0000000000..ce11b19a18 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.h @@ -0,0 +1,73 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "cvfBase.h" +#include "cvfObject.h" + +namespace cvf +{ + class DrawableGeo; + class StructGridQuadToCellFaceMapper; +} + +class RimCellEdgeResultSlot; +class RimResultSlot; +class RigGridBase; +class RigResultAccessor; +class RigCaseData; + + +class RivCellEdgeGeometryUtils +{ +public: + static void addCellEdgeResultsToDrawableGeo(size_t timeStepIndex, + RimResultSlot* cellResultSlot, + RimCellEdgeResultSlot* cellEdgeResultSlot, + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, + cvf::DrawableGeo* geo, + size_t gridIndex, + float opacityLevel); + + static void addTernaryCellEdgeResultsToDrawableGeo(size_t timeStepIndex, + RimResultSlot* cellResultSlot, + RimCellEdgeResultSlot* cellEdgeResultSlot, + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, + cvf::DrawableGeo* geo, + size_t gridIndex, + float opacityLevel); + + +private: + static cvf::ref createCellCenterResultAccessor( + RimResultSlot* cellResultSlot, + size_t timeStepIndex, + RigCaseData* eclipseCase, + const RigGridBase* grid); + + static cvf::ref createCellEdgeCenterResultAccessor( + RimResultSlot* cellResultSlot, + RimCellEdgeResultSlot* cellEdgeResultSlot, + size_t timeStepIndex, + RigCaseData* eclipseCase, + const RigGridBase* grid); + + static bool hideScalarValue(double scalarValue, double scalarValueToHide, double tolerance); +}; diff --git a/ApplicationCode/ModelVisualization/RivColorTableArray.cpp b/ApplicationCode/ModelVisualization/RivColorTableArray.cpp index 451ad62a49..a3a6f60d28 100644 --- a/ApplicationCode/ModelVisualization/RivColorTableArray.cpp +++ b/ApplicationCode/ModelVisualization/RivColorTableArray.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/ModelVisualization/RivColorTableArray.h b/ApplicationCode/ModelVisualization/RivColorTableArray.h index 8702cd0ca5..df59373f25 100644 --- a/ApplicationCode/ModelVisualization/RivColorTableArray.h +++ b/ApplicationCode/ModelVisualization/RivColorTableArray.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.cpp index 0a8b3efe2f..4a7c73a8c0 100644 --- a/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -23,7 +24,8 @@ #include "cvfDrawableGeo.h" #include "cvfPrimitiveSetIndexedUInt.h" #include "cvfOutlineEdgeExtractor.h" -#include "cvfStructGridScalarDataAccess.h" +#include "cvfStructGridGeometryGenerator.h" + #include "cvfScalarMapper.h" #include "RigFault.h" @@ -38,6 +40,8 @@ RivFaultGeometryGenerator::RivFaultGeometryGenerator(const cvf::StructGridInterf m_fault(fault), m_computeNativeFaultFaces(computeNativeFaultFaces) { + m_quadMapper = new cvf::StructGridQuadToCellFaceMapper; + m_triangleMapper = new cvf::StuctGridTriangleToCellFaceMapper(m_quadMapper.p()); } //-------------------------------------------------------------------------------------------------- @@ -149,8 +153,8 @@ cvf::ref RivFaultGeometryGenerator::lineIndicesFromQuadVertexArr void RivFaultGeometryGenerator::computeArrays() { std::vector vertices; - m_quadsToGridCells.clear(); - m_quadsToFace.clear(); + m_quadMapper->quadToCellIndexMap().clear(); + m_quadMapper->quadToCellFaceMap().clear(); cvf::Vec3d offset = m_grid->displayModelOffset(); @@ -159,12 +163,14 @@ void RivFaultGeometryGenerator::computeArrays() #pragma omp parallel for for (int fIdx = 0; fIdx < static_cast(faultFaces.size()); fIdx++) { - size_t cellIndex = faultFaces[fIdx].m_nativeGlobalCellIndex; + size_t cellIndex = faultFaces[fIdx].m_nativeReservoirCellIndex; cvf::StructGridInterface::FaceType face = faultFaces[fIdx].m_nativeFace; + if (cellIndex >= m_cellVisibility->size()) continue; + if (!m_computeNativeFaultFaces) { - cellIndex = faultFaces[fIdx].m_oppositeGlobalCellIndex; + cellIndex = faultFaces[fIdx].m_oppositeReservoirCellIndex; face = cvf::StructGridInterface::oppositeFace(faultFaces[fIdx].m_nativeFace); } @@ -186,8 +192,8 @@ void RivFaultGeometryGenerator::computeArrays() } // Keep track of the source cell index per quad - m_quadsToGridCells.push_back(cellIndex); - m_quadsToFace.push_back(face); + m_quadMapper->quadToCellIndexMap().push_back(cellIndex); + m_quadMapper->quadToCellFaceMap().push_back(face); } } @@ -195,72 +201,6 @@ void RivFaultGeometryGenerator::computeArrays() m_vertices->assign(vertices); } -//-------------------------------------------------------------------------------------------------- -/// Calculates the texture coordinates in a "nearly" one dimensional texture. -/// Undefined values are coded with a y-texture coordinate value of 1.0 instead of the normal 0.5 -//-------------------------------------------------------------------------------------------------- -void RivFaultGeometryGenerator::textureCoordinates(cvf::Vec2fArray* textureCoords, const cvf::StructGridScalarDataAccess* dataAccessObject, const cvf::ScalarMapper* mapper) const -{ - if (!dataAccessObject) return; - - size_t numVertices = m_quadsToGridCells.size()*4; - - textureCoords->resize(numVertices); - cvf::Vec2f* rawPtr = textureCoords->ptr(); - - double cellScalarValue; - cvf::Vec2f texCoord; - -#pragma omp parallel for private(texCoord, cellScalarValue) - for (int i = 0; i < static_cast(m_quadsToGridCells.size()); i++) - { - cellScalarValue = dataAccessObject->cellScalar(m_quadsToGridCells[i]); - texCoord = mapper->mapToTextureCoord(cellScalarValue); - if (cellScalarValue == HUGE_VAL || cellScalarValue != cellScalarValue) // a != a is true for NAN's - { - texCoord[1] = 1.0f; - } - - size_t j; - for (j = 0; j < 4; j++) - { - rawPtr[i*4 + j] = texCoord; - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref > RivFaultGeometryGenerator::triangleToSourceGridCellMap() const -{ - cvf::ref > triangles = new cvf::Array(2*m_quadsToGridCells.size()); -#pragma omp parallel for - for (int i = 0; i < static_cast(m_quadsToGridCells.size()); i++) - { - triangles->set(i*2, m_quadsToGridCells[i]); - triangles->set(i*2+1, m_quadsToGridCells[i]); - } - - return triangles; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref > RivFaultGeometryGenerator::triangleToFaceType() const -{ - cvf::ref > triangles = new cvf::Array(2*m_quadsToFace.size()); -#pragma omp parallel for - for (int i = 0; i < static_cast(m_quadsToFace.size()); i++) - { - triangles->set(i*2, m_quadsToFace[i]); - triangles->set(i*2+1, m_quadsToFace[i]); - } - - return triangles; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -268,20 +208,3 @@ void RivFaultGeometryGenerator::setCellVisibility(const cvf::UByteArray* cellVis { m_cellVisibility = cellVisibility; } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const std::vector& RivFaultGeometryGenerator::quadToGridCellIndices() const -{ - return m_quadsToGridCells; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const std::vector& RivFaultGeometryGenerator::quadToFace() const -{ - return m_quadsToFace; -} - diff --git a/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.h b/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.h index 43329a408d..a41e75a67f 100644 --- a/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -47,16 +48,10 @@ class RivFaultGeometryGenerator : public cvf::Object void setCellVisibility(const cvf::UByteArray* cellVisibilities ); - void textureCoordinates(cvf::Vec2fArray* textureCoords, - const cvf::StructGridScalarDataAccess* dataAccessObject, - const cvf::ScalarMapper* mapper) const; - // Mapping between cells and geometry - cvf::ref > triangleToSourceGridCellMap() const; - cvf::ref > triangleToFaceType() const; - const std::vector& quadToGridCellIndices() const; - const std::vector& quadToFace() const; + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper() { return m_quadMapper.p(); } + const cvf::StuctGridTriangleToCellFaceMapper* triangleToCellFaceMapper() { return m_triangleMapper.p(); } // Generated geometry cvf::ref generateSurface(); @@ -70,18 +65,19 @@ class RivFaultGeometryGenerator : public cvf::Object private: // Input - cvf::cref m_grid; - cvf::cref m_fault; - cvf::cref m_cellVisibility; + cvf::cref m_grid; + cvf::cref m_fault; + cvf::cref m_cellVisibility; - bool m_computeNativeFaultFaces; + bool m_computeNativeFaultFaces; // Created arrays - cvf::ref m_vertices; + cvf::ref m_vertices; // Mappings - std::vector m_triangleIndexToGridCellIndex; - std::vector m_quadsToGridCells; + std::vector m_quadsToGridCells; std::vector m_quadsToFace; - std::vector m_triangleToFace; + + cvf::ref m_quadMapper; + cvf::ref m_triangleMapper; }; diff --git a/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp b/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp index e2df00d265..773a1314e6 100644 --- a/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,38 +19,32 @@ #include "RivFaultPartMgr.h" -#include "cvfPart.h" -#include "cafEffectGenerator.h" -#include "cvfStructGrid.h" -#include "cvfDrawableGeo.h" -#include "cvfModelBasicList.h" -#include "RivCellEdgeEffectGenerator.h" -#include "RimReservoirView.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RigCaseCellResultsData.h" -#include "RigCaseData.h" #include "RiaApplication.h" #include "RiaPreferences.h" -#include "RimCase.h" -#include "RimWellCollection.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirCellResultsCacher.h" -#include "cvfDrawableText.h" -#include "cvfqtUtils.h" -#include "cvfPrimitiveSetIndexedUInt.h" -#include "cvfPrimitiveSetDirect.h" -#include "RivGridPartMgr.h" -#include "cvfRenderStateDepth.h" -#include "RivSourceInfo.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigResultAccessor.h" +#include "RimCase.h" +#include "RimFaultCollection.h" +#include "RimReservoirView.h" +#include "RimResultSlot.h" +#include "RimTernaryLegendConfig.h" +#include "RivResultToTextureMapper.h" +#include "RivScalarMapperUtils.h" +#include "RivSourceInfo.h" +#include "RivTernaryScalarMapper.h" +#include "RivTernaryTextureCoordsCreator.h" +#include "RivTextureCoordsCreator.h" +#include "cvfDrawableGeo.h" +#include "cvfDrawableText.h" +#include "cvfModelBasicList.h" +#include "cvfPart.h" +#include "cvfPrimitiveSetDirect.h" +#include "cvfqtUtils.h" //-------------------------------------------------------------------------------------------------- @@ -105,9 +100,7 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* updateNNCColors(cellResultSlot); - - size_t scalarSetIndex = cellResultSlot->gridScalarIndex(); - const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper(); + size_t scalarSetIndex = cellResultSlot->scalarResultIndex(); // If the result is static, only read that. size_t resTimeStepIdx = timeStepIndex; @@ -116,161 +109,73 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); - cvf::ref dataAccessObject = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, scalarSetIndex); // Faults if (m_nativeFaultFaces.notNull()) { - cvf::ref surfaceFacesColorArray; if (cellResultSlot->isTernarySaturationSelected()) { - surfaceFacesColorArray = new cvf::Color3ubArray; + RivTernaryTextureCoordsCreator texturer(cellResultSlot, cellResultSlot->ternaryLegendConfig(), + timeStepIndex, + m_grid->gridIndex(), + m_nativeFaultGenerator->quadToCellFaceMapper()); - const std::vector& quadsToGridCells = m_nativeFaultGenerator->quadToGridCellIndices(); + texturer.createTextureCoords(m_nativeFaultFacesTextureCoords.p()); - RivTransmissibilityColorMapper::updateTernarySaturationColorArray(timeStepIndex, cellResultSlot, m_grid.p(), surfaceFacesColorArray.p(), quadsToGridCells); - } - else if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) - { - const std::vector& quadsToFaceTypes = m_nativeFaultGenerator->quadToFace(); - const std::vector& quadsToGridCells = m_nativeFaultGenerator->quadToGridCellIndices(); - cvf::Vec2fArray* textureCoords = m_nativeFaultFacesTextureCoords.p(); - - RivTransmissibilityColorMapper::updateCombinedTransmissibilityTextureCoordinates(cellResultSlot, m_grid.p(), textureCoords, quadsToFaceTypes, quadsToGridCells); - } + const RivTernaryScalarMapper* mapper = cellResultSlot->ternaryLegendConfig()->scalarMapper(); + RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_nativeFaultFaces.p(), m_nativeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode()); + } else { - if (dataAccessObject.isNull()) - { - return; - } - m_nativeFaultGenerator->textureCoordinates(m_nativeFaultFacesTextureCoords.p(), dataAccessObject.p(), mapper); + RivTextureCoordsCreator texturer(cellResultSlot, + timeStepIndex, + m_grid->gridIndex(), + m_nativeFaultGenerator->quadToCellFaceMapper()); - } + if (!texturer.isValid()) + { + return; + } - if (m_opacityLevel < 1.0f ) - { - const std::vector& isWellPipeVisible = cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex); - cvf::ref gridCellToWellindexMap = eclipseCase->gridCellToWellIndex(m_grid->gridIndex()); - const std::vector& quadsToGridCells = m_nativeFaultGenerator->quadToGridCellIndices(); + texturer.createTextureCoords(m_nativeFaultFacesTextureCoords.p()); - for(size_t i = 0; i < m_nativeFaultFacesTextureCoords->size(); ++i) - { - if ((*m_nativeFaultFacesTextureCoords)[i].y() == 1.0f) continue; // Do not touch undefined values - - size_t quadIdx = i/4; - size_t cellIndex = quadsToGridCells[quadIdx]; - cvf::uint wellIndex = gridCellToWellindexMap->get(cellIndex); - if (wellIndex != cvf::UNDEFINED_UINT) - { - if ( !isWellPipeVisible[wellIndex]) - { - (*m_nativeFaultFacesTextureCoords)[i].y() = 0; // Set the Y texture coordinate to the opaque line in the texture - } - } - } - } - - cvf::DrawableGeo* dg = dynamic_cast(m_nativeFaultFaces->drawable()); - if (surfaceFacesColorArray.notNull()) - { - if (dg) - { - dg->setColorArray(surfaceFacesColorArray.p()); - } - - cvf::ref perVertexColorEffect = RivGridPartMgr::createPerVertexColoringEffect(m_opacityLevel); - m_nativeFaultFaces->setEffect(perVertexColorEffect.p()); - - m_nativeFaultFaces->setPriority(100); - } - else - { - if (dg) dg->setTextureCoordArray(m_nativeFaultFacesTextureCoords.p()); - - cvf::ref scalarEffect = cellResultEffect(mapper, caf::PO_1); - m_nativeFaultFaces->setEffect(scalarEffect.p()); + const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper(); + RivScalarMapperUtils::applyTextureResultsToPart(m_nativeFaultFaces.p(), m_nativeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode()); } } - if (m_oppositeFaultFaces.notNull()) { - cvf::ref surfaceFacesColorArray; - - if (cellResultSlot->isTernarySaturationSelected()) - { - surfaceFacesColorArray = new cvf::Color3ubArray; - - const std::vector& quadsToGridCells = m_oppositeFaultGenerator->quadToGridCellIndices(); - - RivTransmissibilityColorMapper::updateTernarySaturationColorArray(timeStepIndex, cellResultSlot, m_grid.p(), surfaceFacesColorArray.p(), quadsToGridCells); - } - else if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) - { - const std::vector& quadsToFaceTypes = m_oppositeFaultGenerator->quadToFace(); - const std::vector& quadsToGridCells = m_oppositeFaultGenerator->quadToGridCellIndices(); - cvf::Vec2fArray* textureCoords = m_oppositeFaultFacesTextureCoords.p(); - - RivTransmissibilityColorMapper::updateCombinedTransmissibilityTextureCoordinates(cellResultSlot, m_grid.p(), textureCoords, quadsToFaceTypes, quadsToGridCells); - } - else - { - if (dataAccessObject.isNull()) - { - return; - } - - m_oppositeFaultGenerator->textureCoordinates(m_oppositeFaultFacesTextureCoords.p(), dataAccessObject.p(), mapper); - } - - if (m_opacityLevel < 1.0f ) - { - const std::vector& isWellPipeVisible = cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex); - cvf::ref gridCellToWellindexMap = eclipseCase->gridCellToWellIndex(m_grid->gridIndex()); - const std::vector& quadsToGridCells = m_oppositeFaultGenerator->quadToGridCellIndices(); - - for(size_t i = 0; i < m_oppositeFaultFacesTextureCoords->size(); ++i) - { - if ((*m_oppositeFaultFacesTextureCoords)[i].y() == 1.0f) continue; // Do not touch undefined values - - size_t quadIdx = i/4; - size_t cellIndex = quadsToGridCells[quadIdx]; - cvf::uint wellIndex = gridCellToWellindexMap->get(cellIndex); - if (wellIndex != cvf::UNDEFINED_UINT) - { - if ( !isWellPipeVisible[wellIndex]) - { - (*m_oppositeFaultFacesTextureCoords)[i].y() = 0; // Set the Y texture coordinate to the opaque line in the texture - } - } - } - } - - cvf::DrawableGeo* dg = dynamic_cast(m_oppositeFaultFaces->drawable()); - if (surfaceFacesColorArray.notNull()) - { - if (dg) - { - dg->setColorArray(surfaceFacesColorArray.p()); - } - - cvf::ref perVertexColorEffect = RivGridPartMgr::createPerVertexColoringEffect(m_opacityLevel); - m_oppositeFaultFaces->setEffect(perVertexColorEffect.p()); - - m_oppositeFaultFaces->setPriority(100); - } - else - { - if (dg) dg->setTextureCoordArray(m_oppositeFaultFacesTextureCoords.p()); - - // Use a different offset than native fault faces to avoid z-fighting - cvf::ref scalarEffect = cellResultEffect(mapper, caf::PO_2); - - m_oppositeFaultFaces->setEffect(scalarEffect.p()); - } - } - + if (cellResultSlot->isTernarySaturationSelected()) + { + RivTernaryTextureCoordsCreator texturer(cellResultSlot, cellResultSlot->ternaryLegendConfig(), + timeStepIndex, + m_grid->gridIndex(), + m_oppositeFaultGenerator->quadToCellFaceMapper()); + + texturer.createTextureCoords(m_oppositeFaultFacesTextureCoords.p()); + + const RivTernaryScalarMapper* mapper = cellResultSlot->ternaryLegendConfig()->scalarMapper(); + RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_oppositeFaultFaces.p(), m_oppositeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode()); + } + else + { + RivTextureCoordsCreator texturer(cellResultSlot, + timeStepIndex, + m_grid->gridIndex(), + m_oppositeFaultGenerator->quadToCellFaceMapper()); + + if (!texturer.isValid()) + { + return; + } + + texturer.createTextureCoords(m_oppositeFaultFacesTextureCoords.p()); + + const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper(); + RivScalarMapperUtils::applyTextureResultsToPart(m_oppositeFaultFaces.p(), m_oppositeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode()); + } + } } //-------------------------------------------------------------------------------------------------- @@ -278,7 +183,32 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot) { + updateNNCColors(cellResultSlot); + if (m_nativeFaultFaces.notNull()) + { + cvf::DrawableGeo* dg = dynamic_cast(m_nativeFaultFaces->drawable()); + if (dg) + { + cvf::ref eff = RivScalarMapperUtils::createCellEdgeEffect(dg, m_nativeFaultGenerator->quadToCellFaceMapper(), + m_grid->gridIndex(), + timeStepIndex, cellResultSlot, cellEdgeResultSlot, m_opacityLevel, m_defaultColor, this->faceCullingMode()); + + m_nativeFaultFaces->setEffect(eff.p()); + } + } + + if (m_oppositeFaultFaces.notNull()) + { + cvf::DrawableGeo* dg = dynamic_cast(m_oppositeFaultFaces->drawable()); + if (dg) + { + cvf::ref eff = RivScalarMapperUtils::createCellEdgeEffect(dg, m_oppositeFaultGenerator->quadToCellFaceMapper(), m_grid->gridIndex(), + timeStepIndex, cellResultSlot, cellEdgeResultSlot, m_opacityLevel, m_defaultColor, this->faceCullingMode()); + + m_oppositeFaultFaces->setEffect(eff.p()); + } + } } const int priFaultGeo = 1; @@ -311,8 +241,7 @@ void RivFaultPartMgr::generatePartGeometry() // Set mapping from triangle face index to cell index cvf::ref si = new RivSourceInfo; - si->m_cellIndices = m_nativeFaultGenerator->triangleToSourceGridCellMap().p(); - si->m_faceTypes = m_nativeFaultGenerator->triangleToFaceType().p(); + si->m_cellFaceFromTriangleMapper = m_nativeFaultGenerator->triangleToCellFaceMapper(); part->setSourceInfo(si.p()); part->updateBoundingBox(); @@ -365,8 +294,7 @@ void RivFaultPartMgr::generatePartGeometry() // Set mapping from triangle face index to cell index cvf::ref si = new RivSourceInfo; - si->m_cellIndices = m_oppositeFaultGenerator->triangleToSourceGridCellMap().p(); - si->m_faceTypes = m_oppositeFaultGenerator->triangleToFaceType().p(); + si->m_cellFaceFromTriangleMapper = m_oppositeFaultGenerator->triangleToCellFaceMapper(); part->setSourceInfo(si.p()); part->updateBoundingBox(); @@ -673,22 +601,6 @@ void RivFaultPartMgr::appendNNCFacesToModel(cvf::ModelBasicList* model) if (m_NNCFaces.notNull()) model->addPart(m_NNCFaces.p()); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref RivFaultPartMgr::cellResultEffect(const cvf::ScalarMapper* mapper, caf::PolygonOffset polygonOffset) const -{ - CVF_ASSERT(mapper); - - caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); - scalarEffgen.setFaceCulling(faceCullingMode()); - scalarEffgen.setOpacityLevel(m_opacityLevel); - - cvf::ref scalarEffect = scalarEffgen.generateEffect(); - - return scalarEffect; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -699,7 +611,7 @@ caf::FaceCulling RivFaultPartMgr::faceCullingMode() const { if (m_rimFaultCollection->faultResult() == RimFaultCollection::FAULT_BACK_FACE_CULLING) { - if (m_grid->mainGrid()->faceNormalsIsOutwards()) + if (m_grid->mainGrid()->isFaceNormalsOutwards()) { return caf::FC_BACK; } @@ -710,7 +622,7 @@ caf::FaceCulling RivFaultPartMgr::faceCullingMode() const } else if (m_rimFaultCollection->faultResult() == RimFaultCollection::FAULT_FRONT_FACE_CULLING) { - if (m_grid->mainGrid()->faceNormalsIsOutwards()) + if (m_grid->mainGrid()->isFaceNormalsOutwards()) { return caf::FC_FRONT; } @@ -738,11 +650,25 @@ void RivFaultPartMgr::updateNNCColors(RimResultSlot* cellResultSlot) { if (m_NNCFaces.isNull()) return; - if (cellResultSlot && cellResultSlot->resultVariable() == RimDefines::combinedTransmissibilityResultName()) + bool showNncsWithScalarMappedColor = false; + + if (cellResultSlot) + { + size_t scalarSetIndex = cellResultSlot->scalarResultIndex(); + + if (m_grid->mainGrid()->nncData()->hasScalarValues(scalarSetIndex)) + { + showNncsWithScalarMappedColor = true; + } + } + + if (showNncsWithScalarMappedColor) { + size_t scalarSetIndex = cellResultSlot->scalarResultIndex(); + const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper(); - m_NNCGenerator->textureCoordinates(m_NNCTextureCoords.p(), mapper); + m_NNCGenerator->textureCoordinates(m_NNCTextureCoords.p(), mapper, scalarSetIndex); cvf::ref nncEffect; diff --git a/ApplicationCode/ModelVisualization/RivFaultPartMgr.h b/ApplicationCode/ModelVisualization/RivFaultPartMgr.h index d4a01e8736..5f21cc6cb7 100644 --- a/ApplicationCode/ModelVisualization/RivFaultPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivFaultPartMgr.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -69,7 +70,6 @@ class RivFaultPartMgr : public cvf::Object void updateNNCColors(RimResultSlot* cellResultSlot); - cvf::ref cellResultEffect(const cvf::ScalarMapper* mapper, caf::PolygonOffset polygonOffset) const; caf::FaceCulling faceCullingMode() const; void createLabelWithAnchorLine(const cvf::Part* part); diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index ddf67713c6..1c2a3d0c47 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,11 +20,34 @@ #include "RivGridPartMgr.h" +#include "RiaApplication.h" +#include "RiaPreferences.h" + +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigResultAccessorFactory.h" + +#include "RimCase.h" +#include "RimCellEdgeResultSlot.h" +#include "RimReservoirCellResultsStorage.h" +#include "RimReservoirView.h" +#include "RimResultSlot.h" +#include "RimTernaryLegendConfig.h" +#include "RimWellCollection.h" + +#include "RivCellEdgeEffectGenerator.h" +#include "RivResultToTextureMapper.h" +#include "RivScalarMapperUtils.h" +#include "RivSourceInfo.h" +#include "RivTernaryScalarMapperEffectGenerator.h" +#include "RivTernaryTextureCoordsCreator.h" +#include "RivTextureCoordsCreator.h" #include "cafEffectGenerator.h" #include "cafPdmFieldCvfColor.h" #include "cafPdmFieldCvfMat4d.h" #include "cafProgressInfo.h" + #include "cvfDrawableGeo.h" #include "cvfMath.h" #include "cvfModelBasicList.h" @@ -37,39 +62,21 @@ #include "cvfStructGrid.h" #include "cvfUniform.h" -#include "RiaApplication.h" -#include "RiaPreferences.h" -#include "RigCaseCellResultsData.h" -#include "RigCaseData.h" -#include "RimCase.h" -#include "RimCellEdgeResultSlot.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimReservoirView.h" -#include "RimResultSlot.h" -#include "RimTernaryLegendConfig.h" -#include "RimWellCollection.h" -#include "RivCellEdgeEffectGenerator.h" -#include "RivSourceInfo.h" - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RivGridPartMgr::RivGridPartMgr(const RigGridBase* grid, size_t gridIdx, const RimFaultCollection* rimFaultCollection) +RivGridPartMgr::RivGridPartMgr(const RigGridBase* grid, size_t gridIdx) : m_surfaceGenerator(grid), - m_faultGenerator(grid), m_gridIdx(gridIdx), m_grid(grid), m_surfaceFaceFilter(grid), - m_faultFaceFilter(grid), m_opacityLevel(1.0f), - m_defaultColor(cvf::Color3::WHITE), - m_rimFaultCollection(rimFaultCollection) + m_defaultColor(cvf::Color3::WHITE) { CVF_ASSERT(grid); m_cellVisibility = new cvf::UByteArray; m_surfaceFacesTextureCoords = new cvf::Vec2fArray; - m_faultFacesTextureCoords = new cvf::Vec2fArray; } //-------------------------------------------------------------------------------------------------- @@ -93,14 +100,10 @@ void RivGridPartMgr::setCellVisibility(cvf::UByteArray* cellVisibilities) m_surfaceGenerator.setCellVisibility(cellVisibilities); m_surfaceGenerator.addFaceVisibilityFilter(&m_surfaceFaceFilter); - m_faultGenerator.setCellVisibility(cellVisibilities); - m_faultGenerator.addFaceVisibilityFilter(&m_faultFaceFilter); - - generatePartGeometry(m_surfaceGenerator, false); - generatePartGeometry(m_faultGenerator, true); + generatePartGeometry(m_surfaceGenerator); } -void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder, bool faultGeometry) +void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder) { bool useBufferObjects = true; // Surface geometry @@ -123,8 +126,8 @@ void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoB // Set mapping from triangle face index to cell index cvf::ref si = new RivSourceInfo; - si->m_cellIndices = geoBuilder.triangleToSourceGridCellMap().p(); - si->m_faceTypes = geoBuilder.triangleToFaceTypes().p(); + si->m_cellFaceFromTriangleMapper = geoBuilder.triangleToCellFaceMapper(); + part->setSourceInfo(si.p()); part->updateBoundingBox(); @@ -133,17 +136,8 @@ void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoB caf::SurfaceEffectGenerator geometryEffgen(cvf::Color4f(cvf::Color3f::WHITE), caf::PO_1); cvf::ref geometryOnlyEffect = geometryEffgen.generateEffect(); part->setEffect(geometryOnlyEffect.p()); - - if (faultGeometry) - { - part->setEnableMask(faultBit); - m_faultFaces = part; - } - else - { - part->setEnableMask(surfaceBit); - m_surfaceFaces = part; - } + part->setEnableMask(surfaceBit); + m_surfaceFaces = part; } } @@ -167,30 +161,19 @@ void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoB RiaPreferences* prefs = RiaApplication::instance()->preferences(); cvf::ref eff; - if (faultGeometry) - { - caf::MeshEffectGenerator effGen(prefs->defaultFaultGridLineColors()); - eff = effGen.generateEffect(); + caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); + eff = effGen.generateEffect(); - part->setEnableMask(meshFaultBit); - part->setEffect(eff.p()); - m_faultGridLines = part; - } - else - { - caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); - eff = effGen.generateEffect(); - - // Set priority to make sure fault lines are rendered first - part->setPriority(10); + // Set priority to make sure fault lines are rendered first + part->setPriority(10); - part->setEnableMask(meshSurfaceBit); - part->setEffect(eff.p()); - m_surfaceGridLines = part; - } + part->setEnableMask(meshSurfaceBit); + part->setEffect(eff.p()); + m_surfaceGridLines = part; } } } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -200,12 +183,6 @@ void RivGridPartMgr::appendPartsToModel(cvf::ModelBasicList* model) if(m_surfaceFaces.notNull() ) model->addPart(m_surfaceFaces.p() ); if(m_surfaceGridLines.notNull()) model->addPart(m_surfaceGridLines.p()); - - if (m_rimFaultCollection && m_rimFaultCollection->showGeometryDetectedFaults()) - { - if(m_faultFaces.notNull() ) model->addPart(m_faultFaces.p() ); - if(m_faultGridLines.notNull() ) model->addPart(m_faultGridLines.p() ); - } } //-------------------------------------------------------------------------------------------------- @@ -213,20 +190,18 @@ void RivGridPartMgr::appendPartsToModel(cvf::ModelBasicList* model) //-------------------------------------------------------------------------------------------------- void RivGridPartMgr::updateCellColor(cvf::Color4f color) { - if (m_surfaceFaces.isNull() && m_faultFaces.isNull()) return; + if (m_surfaceFaces.isNull()) return; // Set default effect caf::SurfaceEffectGenerator geometryEffgen(color, caf::PO_1); cvf::ref geometryOnlyEffect = geometryEffgen.generateEffect(); if (m_surfaceFaces.notNull()) m_surfaceFaces->setEffect(geometryOnlyEffect.p()); - if (m_faultFaces.notNull()) m_faultFaces->setEffect(geometryOnlyEffect.p()); if (color.a() < 1.0f) { // Set priority to make sure this transparent geometry are rendered last if (m_surfaceFaces.notNull()) m_surfaceFaces->setPriority(100); - if (m_faultFaces.notNull()) m_faultFaces->setPriority(100); } m_opacityLevel = color.a(); @@ -236,12 +211,6 @@ void RivGridPartMgr::updateCellColor(cvf::Color4f color) RiaPreferences* prefs = RiaApplication::instance()->preferences(); cvf::ref eff; - if (m_faultFaces.notNull()) - { - caf::MeshEffectGenerator faultEffGen(prefs->defaultFaultGridLineColors()); - eff = faultEffGen.generateEffect(); - m_faultGridLines->setEffect(eff.p()); - } if (m_surfaceFaces.notNull()) { caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); @@ -257,153 +226,42 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* { CVF_ASSERT(cellResultSlot); - const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper(); RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); cvf::ref surfaceFacesColorArray; // Outer surface - if (m_surfaceFaces.notNull()) - { - if (cellResultSlot->isTernarySaturationSelected()) - { - surfaceFacesColorArray = new cvf::Color3ubArray; - - const std::vector& quadsToGridCells = m_surfaceGenerator.quadToGridCellIndices(); - - RivTransmissibilityColorMapper::updateTernarySaturationColorArray(timeStepIndex, cellResultSlot, m_grid.p(), surfaceFacesColorArray.p(), quadsToGridCells); - } - else if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) - { - const std::vector& quadsToFaceTypes = m_surfaceGenerator.quadToFace(); - const std::vector& quadsToGridCells = m_surfaceGenerator.quadToGridCellIndices(); - cvf::Vec2fArray* textureCoords = m_surfaceFacesTextureCoords.p(); - - RivTransmissibilityColorMapper::updateCombinedTransmissibilityTextureCoordinates(cellResultSlot, m_grid.p(), textureCoords, quadsToFaceTypes, quadsToGridCells); - } - else - { - size_t scalarSetIndex = cellResultSlot->gridScalarIndex(); - - // If the result is static, only read that. - size_t resTimeStepIdx = timeStepIndex; - if (cellResultSlot->hasStaticResult()) resTimeStepIdx = 0; - - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); - cvf::ref dataAccessObject = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, scalarSetIndex); - if (dataAccessObject.isNull()) return; - - m_surfaceGenerator.textureCoordinates(m_surfaceFacesTextureCoords.p(), dataAccessObject.p(), mapper); - } - - // if this gridpart manager is set to have some transparency, we - // interpret it as we are displaying beeing wellcells. The cells are then transparent by default, but - // we turn that off for particular cells, if the well pipe is not shown for that cell - - if (m_opacityLevel < 1.0f ) - { - const std::vector& isWellPipeVisible = cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex); - cvf::ref gridCellToWellindexMap = eclipseCase->gridCellToWellIndex(m_grid->gridIndex()); - const std::vector& quadsToGridCells = m_surfaceGenerator.quadToGridCellIndices(); - - for(size_t i = 0; i < m_surfaceFacesTextureCoords->size(); ++i) - { - if ((*m_surfaceFacesTextureCoords)[i].y() == 1.0f) continue; // Do not touch undefined values - - size_t quadIdx = i/4; - size_t cellIndex = quadsToGridCells[quadIdx]; - cvf::uint wellIndex = gridCellToWellindexMap->get(cellIndex); - if (wellIndex != cvf::UNDEFINED_UINT) - { - if ( !isWellPipeVisible[wellIndex]) - { - (*m_surfaceFacesTextureCoords)[i].y() = 0; // Set the Y texture coordinate to the opaque line in the texture - } - } - } - } - - cvf::DrawableGeo* dg = dynamic_cast(m_surfaceFaces->drawable()); - if (surfaceFacesColorArray.notNull()) - { - if (dg) - { - dg->setColorArray(surfaceFacesColorArray.p()); - } - - cvf::ref perVertexColorEffect = RivGridPartMgr::createPerVertexColoringEffect(m_opacityLevel); - m_surfaceFaces->setEffect(perVertexColorEffect.p()); - - m_surfaceFaces->setPriority(100); - } - else - { - if (dg) - { - dg->setTextureCoordArray(m_surfaceFacesTextureCoords.p()); - } - - caf::PolygonOffset polygonOffset = caf::PO_1; - caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); - - scalarEffgen.setOpacityLevel(m_opacityLevel); - - cvf::ref scalarEffect = scalarEffgen.generateEffect(); - - m_surfaceFaces->setEffect(scalarEffect.p()); - } - } - - // Faults - if (m_faultFaces.notNull()) - { - size_t scalarSetIndex = cellResultSlot->gridScalarIndex(); - - // If the result is static, only read that. - size_t resTimeStepIdx = timeStepIndex; - if (cellResultSlot->hasStaticResult()) resTimeStepIdx = 0; - - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); - cvf::ref dataAccessObject = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, scalarSetIndex); - if (dataAccessObject.isNull()) return; - - m_faultGenerator.textureCoordinates(m_faultFacesTextureCoords.p(), dataAccessObject.p(), mapper); - - if (m_opacityLevel < 1.0f ) - { - const std::vector& isWellPipeVisible = cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex); - cvf::ref gridCellToWellindexMap = eclipseCase->gridCellToWellIndex(m_grid->gridIndex()); - const std::vector& quadsToGridCells = m_faultGenerator.quadToGridCellIndices(); - - for(size_t i = 0; i < m_faultFacesTextureCoords->size(); ++i) - { - if ((*m_faultFacesTextureCoords)[i].y() == 1.0f) continue; // Do not touch undefined values - - size_t quadIdx = i/4; - size_t cellIndex = quadsToGridCells[quadIdx]; - cvf::uint wellIndex = gridCellToWellindexMap->get(cellIndex); - if (wellIndex != cvf::UNDEFINED_UINT) - { - if ( !isWellPipeVisible[wellIndex]) - { - (*m_faultFacesTextureCoords)[i].y() = 0; // Set the Y texture coordinate to the opaque line in the texture - } - } - } - } - - cvf::DrawableGeo* dg = dynamic_cast(m_faultFaces->drawable()); - if (dg) dg->setTextureCoordArray(m_faultFacesTextureCoords.p()); - - caf::PolygonOffset polygonOffset = caf::PO_1; - caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); - - scalarEffgen.setOpacityLevel(m_opacityLevel); - - cvf::ref scalarEffect = scalarEffgen.generateEffect(); - - m_faultFaces->setEffect(scalarEffect.p()); - } + if (m_surfaceFaces.notNull()) + { + if (cellResultSlot->isTernarySaturationSelected()) + { + RivTernaryTextureCoordsCreator texturer(cellResultSlot, cellResultSlot->ternaryLegendConfig(), + timeStepIndex, + m_grid->gridIndex(), + m_surfaceGenerator.quadToCellFaceMapper()); + + texturer.createTextureCoords(m_surfaceFacesTextureCoords.p()); + + const RivTernaryScalarMapper* mapper = cellResultSlot->ternaryLegendConfig()->scalarMapper(); + RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_surfaceFaces.p(), m_surfaceFacesTextureCoords.p(), mapper, m_opacityLevel, caf::FC_NONE); + } + else + { + RivTextureCoordsCreator texturer(cellResultSlot, + timeStepIndex, + m_grid->gridIndex(), + m_surfaceGenerator.quadToCellFaceMapper()); + if (!texturer.isValid()) + { + return; + } + + texturer.createTextureCoords(m_surfaceFacesTextureCoords.p()); + + const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper(); + RivScalarMapperUtils::applyTextureResultsToPart(m_surfaceFaces.p(), m_surfaceFacesTextureCoords.p(), mapper, m_opacityLevel, caf::FC_NONE); + } + } } //-------------------------------------------------------------------------------------------------- @@ -411,46 +269,17 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* //-------------------------------------------------------------------------------------------------- void RivGridPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot) { - if (m_surfaceFaces.notNull()) - { - cvf::DrawableGeo* dg = dynamic_cast(m_surfaceFaces->drawable()); - if (dg) - { - RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultSlot, cellEdgeResultSlot, - &m_surfaceGenerator, dg, m_grid->gridIndex(), m_opacityLevel ); - - cvf::ScalarMapper* cellScalarMapper = NULL; - if (cellResultSlot->hasResult()) cellScalarMapper = cellResultSlot->legendConfig()->scalarMapper(); - - CellEdgeEffectGenerator cellFaceEffectGen(cellEdgeResultSlot->legendConfig()->scalarMapper(), cellScalarMapper); - cellFaceEffectGen.setOpacityLevel(m_opacityLevel); - cellFaceEffectGen.setDefaultCellColor(m_defaultColor); - - cvf::ref eff = cellFaceEffectGen.generateEffect(); - - m_surfaceFaces->setEffect(eff.p()); - } - } - if (m_faultFaces.notNull()) - { - cvf::DrawableGeo* dg = dynamic_cast(m_faultFaces->drawable()); - if (dg) - { - RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultSlot, cellEdgeResultSlot, - &m_faultGenerator, dg, m_grid->gridIndex(), m_opacityLevel); - - cvf::ScalarMapper* cellScalarMapper = NULL; - if (cellResultSlot->hasResult()) cellScalarMapper = cellResultSlot->legendConfig()->scalarMapper(); - - CellEdgeEffectGenerator cellFaceEffectGen(cellEdgeResultSlot->legendConfig()->scalarMapper(), cellScalarMapper); - cellFaceEffectGen.setOpacityLevel(m_opacityLevel); - cellFaceEffectGen.setDefaultCellColor(m_defaultColor); - - cvf::ref eff = cellFaceEffectGen.generateEffect(); - - m_faultFaces->setEffect(eff.p()); - } - } + if (m_surfaceFaces.notNull()) + { + cvf::DrawableGeo* dg = dynamic_cast(m_surfaceFaces->drawable()); + if (dg) + { + cvf::ref eff = RivScalarMapperUtils::createCellEdgeEffect(dg, m_surfaceGenerator.quadToCellFaceMapper(), m_grid->gridIndex(), + timeStepIndex, cellResultSlot, cellEdgeResultSlot, m_opacityLevel, m_defaultColor, caf::FC_NONE); + + m_surfaceFaces->setEffect(eff.p()); + } + } } //-------------------------------------------------------------------------------------------------- @@ -466,270 +295,4 @@ RivGridPartMgr::~RivGridPartMgr() #endif } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref RivGridPartMgr::createPerVertexColoringEffect(float opacity) -{ - cvf::ref colorArrayEffect = new cvf::Effect; - - if (RiaApplication::instance()->useShaders()) - { - cvf::ShaderProgramGenerator gen("PerVertexColor", cvf::ShaderSourceProvider::instance()); - gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); - gen.addFragmentCode(cvf::ShaderSourceRepository::src_VaryingColorGlobalAlpha); - gen.addFragmentCode(caf::CommonShaderSources::light_AmbientDiffuse()); - gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard); - - cvf::ref m_shaderProg = gen.generate(); - m_shaderProg->setDefaultUniform(new cvf::UniformFloat("u_alpha", opacity)); - - colorArrayEffect->setShaderProgram(m_shaderProg.p()); - } - else - { - cvf::ref mat = new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE); - mat->setAlpha(opacity); - mat->enableColorMaterial(true); - colorArrayEffect->setRenderState(mat.p()); - - cvf::ref lighting = new cvf::RenderStateLighting_FF; - lighting->enableTwoSided(true); - colorArrayEffect->setRenderState(lighting.p()); - } - - // Simple transparency - if (opacity < 1.0f) - { - cvf::ref blender = new cvf::RenderStateBlending; - blender->configureTransparencyBlending(); - colorArrayEffect->setRenderState(blender.p()); - } - - caf::PolygonOffset polygonOffset = caf::PO_1; - cvf::ref polyOffset = caf::EffectGenerator::createAndConfigurePolygonOffsetRenderState(polygonOffset); - colorArrayEffect->setRenderState(polyOffset.p()); - - return colorArrayEffect; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivTransmissibilityColorMapper::updateCombinedTransmissibilityTextureCoordinates(RimResultSlot* cellResultSlot, - const RigGridBase* grid, - cvf::Vec2fArray* textureCoords, - const std::vector& quadsToFaceTypes, - const std::vector& quadsToGridCells) -{ - const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper(); - if (!mapper) return; - - const RimReservoirCellResultsStorage* gridCellResults = cellResultSlot->currentGridCellResults(); - if (!gridCellResults) return; - - RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); - if (!eclipseCase) return; - - size_t tranPosXScalarSetIndex, tranPosYScalarSetIndex, tranPosZScalarSetIndex; - if (!gridCellResults->cellResults()->findTransmissibilityResults(tranPosXScalarSetIndex, tranPosYScalarSetIndex, tranPosZScalarSetIndex)) return; - - // If the result is static, only read that. - size_t resTimeStepIdx = 0; - - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); - - cvf::ref dataAccessObjectTranX = eclipseCase->dataAccessObject(grid, porosityModel, resTimeStepIdx, tranPosXScalarSetIndex); - cvf::ref dataAccessObjectTranY = eclipseCase->dataAccessObject(grid, porosityModel, resTimeStepIdx, tranPosYScalarSetIndex); - cvf::ref dataAccessObjectTranZ = eclipseCase->dataAccessObject(grid, porosityModel, resTimeStepIdx, tranPosZScalarSetIndex); - - size_t numVertices = quadsToGridCells.size()*4; - - textureCoords->resize(numVertices); - cvf::Vec2f* rawPtr = textureCoords->ptr(); - - double cellScalarValue; - cvf::Vec2f texCoord; - -#pragma omp parallel for private(texCoord, cellScalarValue) - for (int idx = 0; idx < static_cast(quadsToGridCells.size()); idx++) - { - cellScalarValue = HUGE_VAL; - - if (quadsToFaceTypes[idx] == cvf::StructGridInterface::POS_I) - { - cellScalarValue = dataAccessObjectTranX->cellScalar(quadsToGridCells[idx]); - } - else if (quadsToFaceTypes[idx] == cvf::StructGridInterface::NEG_I) - { - size_t i, j, k, neighborGridCellIdx; - grid->ijkFromCellIndex(quadsToGridCells[idx], &i, &j, &k); - - if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::NEG_I, &neighborGridCellIdx)) - { - cellScalarValue = dataAccessObjectTranX->cellScalar(neighborGridCellIdx); - } - } - else if (quadsToFaceTypes[idx] == cvf::StructGridInterface::POS_J) - { - cellScalarValue = dataAccessObjectTranY->cellScalar(quadsToGridCells[idx]); - } - else if (quadsToFaceTypes[idx] == cvf::StructGridInterface::NEG_J) - { - size_t i, j, k, neighborGridCellIdx; - grid->ijkFromCellIndex(quadsToGridCells[idx], &i, &j, &k); - - if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::NEG_J, &neighborGridCellIdx)) - { - cellScalarValue = dataAccessObjectTranY->cellScalar(neighborGridCellIdx); - } - } - else if (quadsToFaceTypes[idx] == cvf::StructGridInterface::POS_K) - { - cellScalarValue = dataAccessObjectTranZ->cellScalar(quadsToGridCells[idx]); - } - else if (quadsToFaceTypes[idx] == cvf::StructGridInterface::NEG_K) - { - size_t i, j, k, neighborGridCellIdx; - grid->ijkFromCellIndex(quadsToGridCells[idx], &i, &j, &k); - - if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::NEG_K, &neighborGridCellIdx)) - { - cellScalarValue = dataAccessObjectTranZ->cellScalar(neighborGridCellIdx); - } - } - - texCoord = mapper->mapToTextureCoord(cellScalarValue); - if (cellScalarValue == HUGE_VAL || cellScalarValue != cellScalarValue) // a != a is true for NAN's - { - texCoord[1] = 1.0f; - } - - size_t j; - for (j = 0; j < 4; j++) - { - rawPtr[idx*4 + j] = texCoord; - } - } - -} - - -//-------------------------------------------------------------------------------------------------- -/// Helper class used to provide zero for all cells -/// This way we can avoid to test if a StructGridScalarDataAccess object is valid before reading out the value. -//-------------------------------------------------------------------------------------------------- -class ScalarDataAccessZeroForAllCells : public cvf::StructGridScalarDataAccess -{ -public: - virtual double cellScalar(size_t cellIndex) const - { - return 0.0; - } - virtual void setCellScalar(size_t cellIndex, double value) - { - } -}; - - -//-------------------------------------------------------------------------------------------------- -/// Creates and assigns a ternary saturation color for all four vertices of a quad representing a cell face -/// -/// Loads ternary saturation results SOIL, SWAT and SGAS -/// If any of these are not present, the values for a missing component is set to 0.0 -//-------------------------------------------------------------------------------------------------- -void RivTransmissibilityColorMapper::updateTernarySaturationColorArray(size_t timeStepIndex, RimResultSlot* cellResultSlot, const RigGridBase* grid, cvf::Color3ubArray* colorArray, const std::vector& quadsToGridCells) -{ - RimReservoirCellResultsStorage* gridCellResults = cellResultSlot->currentGridCellResults(); - if (!gridCellResults) return; - - RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); - if (!eclipseCase) return; - - size_t soilScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); - size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); - size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); - - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); - - double soilMin = 0.0; - double soilMax = 1.0; - double sgasMin = 0.0; - double sgasMax = 1.0; - double swatMin = 0.0; - double swatMax = 1.0; - - cellResultSlot->ternaryLegendConfig()->ternaryRanges(soilMin, soilMax, sgasMin, sgasMax, swatMin, swatMax); - - cvf::ref dataAccessObjectSoil = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, soilScalarSetIndex); - if (dataAccessObjectSoil.isNull()) - { - dataAccessObjectSoil = new ScalarDataAccessZeroForAllCells; - } - - cvf::ref dataAccessObjectSgas = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, sgasScalarSetIndex); - if (dataAccessObjectSgas.isNull()) - { - dataAccessObjectSgas = new ScalarDataAccessZeroForAllCells; - } - - cvf::ref dataAccessObjectSwat = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, swatScalarSetIndex); - if (dataAccessObjectSwat.isNull()) - { - dataAccessObjectSwat = new ScalarDataAccessZeroForAllCells; - } - - double soilRange = soilMax - soilMin; - double soilFactor = 255.0 / soilRange; - - double sgasRange = sgasMax - sgasMin; - double sgasFactor = 255.0 / sgasRange; - - double swatRange = swatMax - swatMin; - double swatFactor = 255.0 / swatRange; - - size_t numVertices = quadsToGridCells.size()*4; - - colorArray->resize(numVertices); - - cvf::Color3ub ternaryColorByte; - double v, vNormalized; - -#pragma omp parallel for private(ternaryColorByte, v, vNormalized) - for (int idx = 0; idx < static_cast(quadsToGridCells.size()); idx++) - { - size_t gridCellIndex = quadsToGridCells[idx]; - - { - v = dataAccessObjectSgas->cellScalar(gridCellIndex); - vNormalized = (v - sgasMin) * sgasFactor; - - vNormalized = cvf::Math::clamp(vNormalized, 0.0, 255.0); - ternaryColorByte.r() = vNormalized; - } - - { - v = dataAccessObjectSoil->cellScalar(gridCellIndex); - vNormalized = (v - soilMin) * soilFactor; - - vNormalized = cvf::Math::clamp(vNormalized, 0.0, 255.0); - ternaryColorByte.g() = vNormalized; - } - - { - v = dataAccessObjectSwat->cellScalar(gridCellIndex); - vNormalized = (v - swatMin) * swatFactor; - - vNormalized = cvf::Math::clamp(vNormalized, 0.0, 255.0); - ternaryColorByte.b() = vNormalized; - } - - size_t j; - for (j = 0; j < 4; j++) - { - colorArray->set(idx*4 + j, ternaryColorByte); - } - } -} diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.h b/ApplicationCode/ModelVisualization/RivGridPartMgr.h index d205256381..a1b29cdb37 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -34,31 +36,6 @@ namespace cvf class RimResultSlot; class RimCellEdgeResultSlot; -class RimFaultCollection; - - - -//================================================================================================== -/// -/// -//================================================================================================== -class RivTransmissibilityColorMapper -{ -public: - static void updateCombinedTransmissibilityTextureCoordinates( - RimResultSlot* cellResultSlot, - const RigGridBase* grid, - cvf::Vec2fArray* textureCoords, - const std::vector& quadsToFaceTypes, - const std::vector& quadsToGridCells); - - static void updateTernarySaturationColorArray( - size_t timeStepIndex, - RimResultSlot* cellResultSlot, - const RigGridBase* grid, - cvf::Color3ubArray* colorArray, - const std::vector& quadsToGridCells); -}; @@ -73,7 +50,7 @@ class RivTransmissibilityColorMapper class RivGridPartMgr: public cvf::Object { public: - RivGridPartMgr(const RigGridBase* grid, size_t gridIdx, const RimFaultCollection* rimFaultCollection); + RivGridPartMgr(const RigGridBase* grid, size_t gridIdx); ~RivGridPartMgr(); void setTransform(cvf::Transform* scaleTransform); void setCellVisibility(cvf::UByteArray* cellVisibilities ); @@ -87,10 +64,8 @@ class RivGridPartMgr: public cvf::Object void appendPartsToModel(cvf::ModelBasicList* model); - static cvf::ref createPerVertexColoringEffect(float opacity); - private: - void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder, bool faultGeometry); + void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder); private: size_t m_gridIdx; @@ -108,15 +83,5 @@ class RivGridPartMgr: public cvf::Object cvf::ref m_surfaceGridLines; - // Fault visualization - cvf::StructGridGeometryGenerator m_faultGenerator; - RigFaultFaceVisibilityFilter m_faultFaceFilter; - cvf::ref m_faultFaces; - cvf::ref m_faultFacesTextureCoords; - - cvf::ref m_faultGridLines; - cvf::ref m_cellVisibility; - - const RimFaultCollection* m_rimFaultCollection; }; diff --git a/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.cpp index f146190167..8f438f4763 100644 --- a/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -98,13 +99,13 @@ void RivNNCGeometryGenerator::computeArrays() if ((*allCells)[conn.m_c1GlobIdx].hostGrid() == m_grid.p()) { - size_t cell1GridLocalIdx = (*allCells)[conn.m_c1GlobIdx].cellIndex(); + size_t cell1GridLocalIdx = (*allCells)[conn.m_c1GlobIdx].gridLocalCellIndex(); cell1Visible = (*m_cellVisibility)[cell1GridLocalIdx]; } if ((*allCells)[conn.m_c2GlobIdx].hostGrid() == m_grid.p()) { - size_t cell2GridLocalIdx = (*allCells)[conn.m_c2GlobIdx].cellIndex(); + size_t cell2GridLocalIdx = (*allCells)[conn.m_c2GlobIdx].gridLocalCellIndex(); cell2Visible = (*m_cellVisibility)[cell2GridLocalIdx]; } @@ -144,12 +145,19 @@ void RivNNCGeometryGenerator::computeArrays() /// Calculates the texture coordinates in a "nearly" one dimensional texture. /// Undefined values are coded with a y-texture coordinate value of 1.0 instead of the normal 0.5 //-------------------------------------------------------------------------------------------------- -void RivNNCGeometryGenerator::textureCoordinates(cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper) const +void RivNNCGeometryGenerator::textureCoordinates(cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, size_t scalarResultIndex) const { size_t numVertices = m_vertices->size(); textureCoords->resize(numVertices); cvf::Vec2f* rawPtr = textureCoords->ptr(); + + const std::vector* nncResultVals = m_nncData->connectionScalarResult(scalarResultIndex); + if (!nncResultVals) + { + textureCoords->setAll(cvf::Vec2f(0.0f, 1.0f)); + return; + } double cellScalarValue; cvf::Vec2f texCoord; @@ -157,7 +165,7 @@ void RivNNCGeometryGenerator::textureCoordinates(cvf::Vec2fArray* textureCoords, #pragma omp parallel for private(texCoord, cellScalarValue) for (int tIdx = 0; tIdx < static_cast(m_triangleIndexToNNCIndex->size()); tIdx++) { - cellScalarValue = m_nncData->connections()[(*m_triangleIndexToNNCIndex)[tIdx]].m_transmissibility; + cellScalarValue = (*nncResultVals)[(*m_triangleIndexToNNCIndex)[tIdx]]; texCoord = mapper->mapToTextureCoord(cellScalarValue); if (cellScalarValue == HUGE_VAL || cellScalarValue != cellScalarValue) // a != a is true for NAN's { diff --git a/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.h b/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.h index 54c5ddf38a..60affaf6b5 100644 --- a/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -44,7 +45,7 @@ class RivNNCGeometryGenerator : public cvf::Object void setCellVisibility( const cvf::UByteArray* cellVisibilities, const RigGridBase * grid); void textureCoordinates(cvf::Vec2fArray* textureCoords, - const cvf::ScalarMapper* mapper) const; + const cvf::ScalarMapper* mapper, size_t scalarResultIndex) const; // Mapping between cells and geometry cvf::ref > triangleToNNCIndex() const; diff --git a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp index edf8642a9c..b6ec6a08d9 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -25,23 +26,31 @@ #include "cafPdmFieldCvfColor.h" -#include "RimFaultCollection.h" #include "RigMainGrid.h" - +#include "RimFaultCollection.h" +#include "RimFaultResultSlot.h" +#include "RimReservoirView.h" +#include "RimResultSlot.h" +#include "RimCase.h" +#include "RigCaseData.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RivReservoirFaultsPartMgr::RivReservoirFaultsPartMgr(const RigMainGrid* grid, const RimFaultCollection* faultCollection) -: m_faultCollection(faultCollection) +RivReservoirFaultsPartMgr::RivReservoirFaultsPartMgr(const RigMainGrid* grid, RimReservoirView* reservoirView) +: m_reservoirView(reservoirView) { CVF_ASSERT(grid); - if (faultCollection) + if (reservoirView) { - for (size_t i = 0; i < faultCollection->faults.size(); i++) + RimFaultCollection* faultCollection = reservoirView->faultCollection(); + if (faultCollection) { - m_faultParts.push_back(new RivFaultPartMgr(grid, faultCollection, faultCollection->faults[i])); + for (size_t i = 0; i < faultCollection->faults.size(); i++) + { + m_faultParts.push_back(new RivFaultPartMgr(grid, faultCollection, faultCollection->faults[i])); + } } } @@ -83,55 +92,87 @@ void RivReservoirFaultsPartMgr::appendPartsToModel(cvf::ModelBasicList* model) { CVF_ASSERT(model != NULL); - if (!m_faultCollection) return; + RimFaultCollection* faultCollection = m_reservoirView->faultCollection(); + if (!faultCollection) return; - bool isShowingGrid = m_faultCollection->isGridVisualizationMode(); - if (!m_faultCollection->showFaultCollection() && !isShowingGrid) return; + + bool isShowingGrid = faultCollection->isGridVisualizationMode(); + if (!faultCollection->showFaultCollection() && !isShowingGrid) return; // Check match between model fault count and fault parts - CVF_ASSERT(m_faultCollection->faults.size() == m_faultParts.size()); + CVF_ASSERT(faultCollection->faults.size() == m_faultParts.size()); cvf::ModelBasicList parts; - for (size_t i = 0; i < m_faultCollection->faults.size(); i++) + for (size_t i = 0; i < faultCollection->faults.size(); i++) { - const RimFault* rimFault = m_faultCollection->faults[i]; + const RimFault* rimFault = faultCollection->faults[i]; cvf::ref rivFaultPart = m_faultParts[i]; CVF_ASSERT(rivFaultPart.notNull()); // Parts that is overridden by the grid settings - bool forceDisplayOfFault = isShowingGrid; - if (m_forceVisibility) + bool forceDisplayOfFault = false; + if (!faultCollection->showFaultsOutsideFilters()) + { + forceDisplayOfFault = isShowingGrid; + } + + if (m_forceVisibility && isShowingGrid) { forceDisplayOfFault = true; } - if (rimFault->showFault() || forceDisplayOfFault) + if ( (faultCollection->showFaultCollection() && rimFault->showFault()) || forceDisplayOfFault) { - if (m_faultCollection->showFaultFaces() || forceDisplayOfFault) + if (faultCollection->showFaultFaces() || forceDisplayOfFault) { rivFaultPart->appendNativeFaultFacesToModel(&parts); } - if (m_faultCollection->showOppositeFaultFaces() || forceDisplayOfFault) + if (faultCollection->showOppositeFaultFaces() || forceDisplayOfFault) { rivFaultPart->appendOppositeFaultFacesToModel(&parts); } - if (m_faultCollection->showFaultFaces() || m_faultCollection->showOppositeFaultFaces() || m_faultCollection->showNNCs() || forceDisplayOfFault) + if (faultCollection->showFaultFaces() || faultCollection->showOppositeFaultFaces() || faultCollection->showNNCs() || forceDisplayOfFault) { rivFaultPart->appendMeshLinePartsToModel(&parts); } } // Parts that is not overridden by the grid settings + RimFaultResultSlot* faultResultSlot = m_reservoirView->faultResultSettings(); + RimResultSlot* cellResultSlot = m_reservoirView->cellResult(); - if (rimFault->showFault() && m_faultCollection->showFaultCollection()) + if (rimFault->showFault() && faultCollection->showFaultCollection()) { - if (m_faultCollection->showNNCs()) + if (faultCollection->showNNCs()) { - rivFaultPart->appendNNCFacesToModel(&parts); + bool showNncs = true; + if (faultCollection->hideNncsWhenNoResultIsAvailable()) + { + size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; + if (faultResultSlot->showCustomFaultResult()) + { + scalarResultIndex = faultResultSlot->customFaultResult()->scalarResultIndex(); + } + else + { + scalarResultIndex = cellResultSlot->scalarResultIndex(); + } + + RigMainGrid* mainGrid = m_reservoirView->eclipseCase()->reservoirData()->mainGrid(); + if (!(mainGrid && mainGrid->nncData()->hasScalarValues(scalarResultIndex))) + { + showNncs = false; + } + } + + if (showNncs) + { + rivFaultPart->appendNNCFacesToModel(&parts); + } } } } @@ -161,16 +202,23 @@ void RivReservoirFaultsPartMgr::applySingleColorEffect() //-------------------------------------------------------------------------------------------------- void RivReservoirFaultsPartMgr::updateColors(size_t timeStepIndex, RimResultSlot* cellResultSlot) { - if (m_faultCollection->showResultsOnFaults()) + if (!m_reservoirView) return; + + RimFaultCollection* faultCollection = m_reservoirView->faultCollection(); + CVF_ASSERT(faultCollection); + + for (size_t i = 0; i < faultCollection->faults.size(); i++) { - for (size_t i = 0; i < m_faultParts.size(); i++) + RimFault* rimFault = faultCollection->faults[i]; + + if (cellResultSlot && (cellResultSlot->hasResult() || cellResultSlot->isTernarySaturationSelected()) ) { m_faultParts[i]->updateCellResultColor(timeStepIndex, cellResultSlot); } - } - else - { - applySingleColorEffect(); + else + { + m_faultParts[i]->applySingleColorEffect(); + } } } @@ -191,21 +239,23 @@ void RivReservoirFaultsPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, void RivReservoirFaultsPartMgr::appendLabelPartsToModel(cvf::ModelBasicList* model) { CVF_ASSERT(model != NULL); + if (!m_reservoirView) return; - if (!m_faultCollection) return; + RimFaultCollection* faultCollection = m_reservoirView->faultCollection(); + CVF_ASSERT(faultCollection); - if (!m_faultCollection->showFaultCollection()) return; + if (!faultCollection->showFaultCollection()) return; - if (!m_faultCollection->showFaultLabel() ) return; + if (!faultCollection->showFaultLabel() ) return; // Check match between model fault count and fault parts - CVF_ASSERT(m_faultCollection->faults.size() == m_faultParts.size()); + CVF_ASSERT(faultCollection->faults.size() == m_faultParts.size()); cvf::ModelBasicList parts; - for (size_t i = 0; i < m_faultCollection->faults.size(); i++) + for (size_t i = 0; i < faultCollection->faults.size(); i++) { - const RimFault* rimFault = m_faultCollection->faults[i]; + const RimFault* rimFault = faultCollection->faults[i]; cvf::ref rivFaultPart = m_faultParts[i]; CVF_ASSERT(rivFaultPart.notNull()); diff --git a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.h index 105b20468f..7723319ce0 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -31,7 +32,7 @@ namespace cvf class RimResultSlot; class RimCellEdgeResultSlot; -class RimFaultCollection; +class RimReservoirView; //================================================================================================== /// @@ -39,7 +40,7 @@ class RimFaultCollection; class RivReservoirFaultsPartMgr : public cvf::Object { public: - RivReservoirFaultsPartMgr(const RigMainGrid* grid, const RimFaultCollection* faultCollection); + RivReservoirFaultsPartMgr(const RigMainGrid* grid, RimReservoirView* reservoirView); ~RivReservoirFaultsPartMgr(); void setTransform(cvf::Transform* scaleTransform); @@ -59,7 +60,7 @@ class RivReservoirFaultsPartMgr : public cvf::Object private: cvf::ref m_scaleTransform; - const RimFaultCollection* m_faultCollection; + caf::PdmPointer m_reservoirView; cvf::Collection m_faultParts; bool m_forceVisibility; }; diff --git a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp index 5ac14e77ce..c11bdfaac3 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -28,7 +30,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivReservoirPartMgr::clearAndSetReservoir(const RigCaseData* eclipseCase, const RimFaultCollection* faultCollection) +void RivReservoirPartMgr::clearAndSetReservoir(const RigCaseData* eclipseCase, RimReservoirView* reservoirView) { m_allGrids.clear(); @@ -38,13 +40,13 @@ void RivReservoirPartMgr::clearAndSetReservoir(const RigCaseData* eclipseCase, c eclipseCase->allGrids(&grids); for (size_t i = 0; i < grids.size() ; ++i) { - m_allGrids.push_back(new RivGridPartMgr(grids[i], i, faultCollection)); + m_allGrids.push_back(new RivGridPartMgr(grids[i], i)); } if (eclipseCase->mainGrid()) { // Faults read from file are present only on main grid - m_faultsPartMgr = new RivReservoirFaultsPartMgr(eclipseCase->mainGrid(), faultCollection); + m_faultsPartMgr = new RivReservoirFaultsPartMgr(eclipseCase->mainGrid(), reservoirView); } } } @@ -197,3 +199,15 @@ void RivReservoirPartMgr::setFaultForceVisibility(bool isGeneratedByFilter) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivReservoirPartMgr::updateFaultCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot) +{ + if (m_faultsPartMgr.notNull()) + { + m_faultsPartMgr->updateCellEdgeResultColor(timeStepIndex, cellResultSlot, cellEdgeResultSlot); + } + +} + diff --git a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h index 7f07979603..1e9e2b894b 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -33,7 +35,7 @@ class RimResultSlot; class RimCellEdgeResultSlot; class RivGridPartMgr; class RigCaseData; -class RimFaultCollection; +class RimReservoirView; //================================================================================================== /// @@ -45,7 +47,7 @@ class RimFaultCollection; class RivReservoirPartMgr: public cvf::Object { public: - void clearAndSetReservoir(const RigCaseData* eclipseCase, const RimFaultCollection* faultCollection); + void clearAndSetReservoir(const RigCaseData* eclipseCase, RimReservoirView* reservoirView); void setTransform(cvf::Transform* scaleTransform); void setCellVisibility(size_t gridIndex, cvf::UByteArray* cellVisibilities ); void setFaultForceVisibility(bool isGeneratedByFilter); @@ -64,7 +66,9 @@ class RivReservoirPartMgr: public cvf::Object // Faults void updateFaultColors(size_t timeStepIndex, RimResultSlot* cellResultSlot); - void appendFaultPartsToModel(cvf::ModelBasicList* model); + void updateFaultCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, + RimCellEdgeResultSlot* cellEdgeResultSlot); + void appendFaultPartsToModel(cvf::ModelBasicList* model); void appendFaultLabelPartsToModel(cvf::ModelBasicList* model); private: diff --git a/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp index 842990aed1..0ac416a076 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,6 +22,7 @@ #include "RivReservoirPipesPartMgr.h" #include "RimReservoirView.h" +#include "RimWell.h" #include "RimWellCollection.h" #include "RivWellPipesPartMgr.h" #include "RivWellHeadPartMgr.h" diff --git a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp index 3f78c6d111..f094460efd 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,26 +19,27 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaStdInclude.h" + #include "RivReservoirViewPartMgr.h" -#include "RivGridPartMgr.h" -#include "RimReservoirView.h" + +#include "RigCaseCellResultsData.h" #include "RigCaseData.h" #include "RigGridBase.h" -#include "RigCaseCellResultsData.h" -#include "RigGridScalarDataAccess.h" +#include "RigResultAccessorFactory.h" + +#include "Rim3dOverlayInfoConfig.h" #include "RimCase.h" -#include "RimCellRangeFilterCollection.h" -#include "RimWellCollection.h" +#include "RimCellEdgeResultSlot.h" #include "RimCellPropertyFilterCollection.h" +#include "RimCellRangeFilterCollection.h" +#include "RimFaultCollection.h" +#include "RimReservoirCellResultsStorage.h" +#include "RimReservoirView.h" #include "RimResultDefinition.h" - -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" - #include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimWellCollection.h" + +#include "RivGridPartMgr.h" //-------------------------------------------------------------------------------------------------- /// @@ -151,7 +154,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geom m_propFilteredGeometryFramesNeedsRegen[i] = true; if (m_propFilteredGeometryFrames[i].notNull()) { - m_propFilteredGeometryFrames[i]->clearAndSetReservoir(eclipseCase, m_reservoirView->faultCollection()); + m_propFilteredGeometryFrames[i]->clearAndSetReservoir(eclipseCase, m_reservoirView); m_propFilteredGeometryFrames[i]->setTransform(m_scaleTransform.p()); } } @@ -163,7 +166,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geom m_propFilteredWellGeometryFramesNeedsRegen[i] = true; if (m_propFilteredWellGeometryFrames[i].notNull()) { - m_propFilteredWellGeometryFrames[i]->clearAndSetReservoir(eclipseCase, m_reservoirView->faultCollection()); + m_propFilteredWellGeometryFrames[i]->clearAndSetReservoir(eclipseCase, m_reservoirView); m_propFilteredWellGeometryFrames[i]->setTransform(m_scaleTransform.p()); } } @@ -171,7 +174,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geom else { m_geometriesNeedsRegen[geomType] = true; - m_geometries[geomType].clearAndSetReservoir(eclipseCase, m_reservoirView->faultCollection()); + m_geometries[geomType].clearAndSetReservoir(eclipseCase, m_reservoirView); m_geometries[geomType].setTransform(m_scaleTransform.p()); } } @@ -238,7 +241,7 @@ void RivReservoirViewPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicL void RivReservoirViewPartMgr::createGeometry(ReservoirGeometryCacheType geometryType) { RigCaseData* res = m_reservoirView->eclipseCase()->reservoirData(); - m_geometries[geometryType].clearAndSetReservoir(res, m_reservoirView->faultCollection()); + m_geometries[geometryType].clearAndSetReservoir(res, m_reservoirView); m_geometries[geometryType].setTransform(m_scaleTransform.p()); std::vector grids; @@ -394,7 +397,7 @@ void RivReservoirViewPartMgr::createPropertyFilteredNoneWellCellGeometry(size_t if ( m_propFilteredGeometryFrames[frameIndex].isNull()) m_propFilteredGeometryFrames[frameIndex] = new RivReservoirPartMgr; - m_propFilteredGeometryFrames[frameIndex]->clearAndSetReservoir(res, m_reservoirView->faultCollection()); + m_propFilteredGeometryFrames[frameIndex]->clearAndSetReservoir(res, m_reservoirView); m_propFilteredGeometryFrames[frameIndex]->setTransform(m_scaleTransform.p()); std::vector grids; @@ -471,7 +474,7 @@ void RivReservoirViewPartMgr::createPropertyFilteredWellGeometry(size_t frameInd if ( m_propFilteredWellGeometryFrames[frameIndex].isNull()) m_propFilteredWellGeometryFrames[frameIndex] = new RivReservoirPartMgr; - m_propFilteredWellGeometryFrames[frameIndex]->clearAndSetReservoir(res, m_reservoirView->faultCollection()); + m_propFilteredWellGeometryFrames[frameIndex]->clearAndSetReservoir(res, m_reservoirView); m_propFilteredWellGeometryFrames[frameIndex]->setTransform(m_scaleTransform.p()); std::vector grids; @@ -561,11 +564,11 @@ void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisib for (int cellIndex = 0; cellIndex < static_cast(grid->cellCount()); cellIndex++) { const RigCell& cell = grid->cell(cellIndex); - size_t globalCellIndex = cell.mainGridCellIndex(); + size_t reservoirCellIndex = cell.mainGridCellIndex(); if ( !invalidCellsIsVisible && cell.isInvalid() - || !inactiveCellsIsVisible && !activeCellInfo->isActive(globalCellIndex) - || !activeCellsIsVisible && activeCellInfo->isActive(globalCellIndex) + || !inactiveCellsIsVisible && !activeCellInfo->isActive(reservoirCellIndex) + || !activeCellsIsVisible && activeCellInfo->isActive(reservoirCellIndex) //|| mainGridIsVisible && (cell.subGrid() != NULL) // this is handled on global level instead || (*cellIsInWellStatuses)[cellIndex] ) @@ -712,7 +715,7 @@ void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVis const double lowerBound = (*pfIt)->lowerBound(); const double upperBound = (*pfIt)->upperBound(); - size_t scalarResultIndex = (*pfIt)->resultDefinition->gridScalarIndex(); + size_t scalarResultIndex = (*pfIt)->resultDefinition->scalarResultIndex(); size_t adjustedTimeStepIndex = timeStepIndex; @@ -727,8 +730,8 @@ void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVis RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel((*pfIt)->resultDefinition()->porosityModel()); RigCaseData* eclipseCase = propFilterColl->reservoirView()->eclipseCase()->reservoirData(); - cvf::ref dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, adjustedTimeStepIndex, scalarResultIndex); - CVF_ASSERT(dataAccessObject.notNull()); + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, grid->gridIndex(), porosityModel, adjustedTimeStepIndex, (*pfIt)->resultDefinition->resultVariable(), (*pfIt)->resultDefinition->resultType()); + CVF_ASSERT(resultAccessor.notNull()); //#pragma omp parallel for schedule(dynamic) for (int cellIndex = 0; cellIndex < static_cast(grid->cellCount()); cellIndex++) @@ -737,7 +740,7 @@ void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVis { size_t resultValueIndex = cellIndex; - double scalarValue = dataAccessObject->cellScalar(resultValueIndex); + double scalarValue = resultAccessor->cellScalar(resultValueIndex); if (lowerBound <= scalarValue && scalarValue <= upperBound) { if (filterType == RimCellFilter::EXCLUDE) @@ -794,7 +797,16 @@ void RivReservoirViewPartMgr::updateCellResultColor(ReservoirGeometryCacheType g void RivReservoirViewPartMgr::updateCellEdgeResultColor(ReservoirGeometryCacheType geometryType, size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot) { RivReservoirPartMgr * pmgr = reservoirPartManager( geometryType, timeStepIndex ); - pmgr->updateCellEdgeResultColor(timeStepIndex, cellResultSlot, cellEdgeResultSlot ); + pmgr->updateCellEdgeResultColor(timeStepIndex, cellResultSlot, cellEdgeResultSlot); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivReservoirViewPartMgr::updateFaultCellEdgeResultColor(ReservoirGeometryCacheType geometryType, size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot) +{ + RivReservoirPartMgr * pmgr = reservoirPartManager(geometryType, timeStepIndex); + pmgr->updateFaultCellEdgeResultColor(timeStepIndex, cellResultSlot, cellEdgeResultSlot); } //-------------------------------------------------------------------------------------------------- @@ -905,6 +917,10 @@ RivReservoirViewPartMgr::ReservoirGeometryCacheType RivReservoirViewPartMgr::geo //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::appendFaultLabelsStaticGeometryPartsToModel(cvf::ModelBasicList* model, ReservoirGeometryCacheType geometryType) { + if (m_geometriesNeedsRegen[geometryType]) + { + createGeometry(geometryType); + } m_geometries[geometryType].appendFaultLabelPartsToModel(model); } @@ -921,5 +937,9 @@ void RivReservoirViewPartMgr::appendFaultLabelsDynamicGeometryPartsToModel(cvf:: //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::setFaultForceVisibilityForGeometryType(ReservoirGeometryCacheType geometryType, bool forceVisibility) { + if (m_geometriesNeedsRegen[geometryType]) + { + createGeometry(geometryType); + } m_geometries[geometryType].setFaultForceVisibility(forceVisibility); } diff --git a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h index 796835ad13..f5fce9e94e 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -66,12 +68,16 @@ class RivReservoirViewPartMgr: public cvf::Object void updateCellResultColor (ReservoirGeometryCacheType geometryType, size_t timeStepIndex, RimResultSlot* cellResultSlot); void updateCellEdgeResultColor(ReservoirGeometryCacheType geometryType, size_t timeStepIndex, - RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot); + RimResultSlot* cellResultSlot, + RimCellEdgeResultSlot* cellEdgeResultSlot); // Faults void appendFaultsStaticGeometryPartsToModel(cvf::ModelBasicList* model, ReservoirGeometryCacheType geometryType); void appendFaultsDynamicGeometryPartsToModel(cvf::ModelBasicList* model, ReservoirGeometryCacheType geometryType, size_t frameIndex); void updateFaultColors(ReservoirGeometryCacheType geometryType, size_t timeStepIndex, RimResultSlot* cellResultSlot); + void updateFaultCellEdgeResultColor( ReservoirGeometryCacheType geometryType, size_t timeStepIndex, + RimResultSlot* cellResultSlot, + RimCellEdgeResultSlot* cellEdgeResultSlot); // Fault labels ReservoirGeometryCacheType geometryTypeForFaultLabels(const std::vector& geometryTypes) const; diff --git a/ApplicationCode/ModelVisualization/RivResultToTextureMapper.h b/ApplicationCode/ModelVisualization/RivResultToTextureMapper.h new file mode 100644 index 0000000000..e70ac7d6f3 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivResultToTextureMapper.h @@ -0,0 +1,65 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigPipeInCellEvaluator.h" + +#include "cvfVector2.h" +#include "cvfScalarMapper.h" +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfStructGrid.h" + +#include + +class RivResultToTextureMapper : public cvf::Object +{ +public: + RivResultToTextureMapper(const cvf::ScalarMapper* scalarMapper, + const RigPipeInCellEvaluator* pipeInCellEvaluator) + : m_scalarMapper(scalarMapper), m_pipeInCellEvaluator(pipeInCellEvaluator) + {} + + cvf::Vec2f getTexCoord(double resultValue, size_t cellIndex) const + { + cvf::Vec2f texCoord(0,0); + + if (resultValue == HUGE_VAL || resultValue != resultValue) // a != a is true for NAN's + { + texCoord[1] = 1.0f; + return texCoord; + } + + texCoord = m_scalarMapper->mapToTextureCoord(resultValue); + + if (!m_pipeInCellEvaluator->isWellPipeInCell(cellIndex)) + { + texCoord[1] = 0; // Set the Y texture coordinate to the opaque line in the texture + } + + return texCoord; + } + +private: + cvf::cref m_scalarMapper; + cvf::cref m_pipeInCellEvaluator; +}; + + diff --git a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp new file mode 100644 index 0000000000..cac3315d34 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp @@ -0,0 +1,139 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RivScalarMapperUtils.h" + +#include "RimCellEdgeResultSlot.h" +#include "RimLegendConfig.h" +#include "RimReservoirView.h" +#include "RimResultSlot.h" +#include "RimTernaryLegendConfig.h" + +#include "RivCellEdgeEffectGenerator.h" +#include "RivCellEdgeGeometryUtils.h" +#include "RivTernaryScalarMapper.h" +#include "RivTernaryScalarMapperEffectGenerator.h" + +#include "cafEffectGenerator.h" + +#include "cvfDrawableGeo.h" +#include "cvfPart.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivScalarMapperUtils::applyTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling) +{ + CVF_ASSERT(part && textureCoords && mapper); + + cvf::DrawableGeo* dg = dynamic_cast(part->drawable()); + if (dg) dg->setTextureCoordArray(textureCoords); + + cvf::ref scalarEffect = RivScalarMapperUtils::createScalarMapperEffect(mapper, opacityLevel, faceCulling); + part->setEffect(scalarEffect.p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivScalarMapperUtils::applyTernaryTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const RivTernaryScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling) +{ + CVF_ASSERT(part && textureCoords && mapper); + + cvf::DrawableGeo* dg = dynamic_cast(part->drawable()); + if (dg) dg->setTextureCoordArray(textureCoords); + + cvf::ref scalarEffect = RivScalarMapperUtils::createTernaryScalarMapperEffect(mapper, opacityLevel, faceCulling); + part->setEffect(scalarEffect.p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivScalarMapperUtils::createCellEdgeEffect(cvf::DrawableGeo* dg, + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, + size_t gridIndex, + size_t timeStepIndex, + RimResultSlot* cellResultSlot, + RimCellEdgeResultSlot* cellEdgeResultSlot, + float opacityLevel, + cvf::Color3f defaultColor, + caf::FaceCulling faceCulling) +{ + CellEdgeEffectGenerator cellFaceEffectGen(cellEdgeResultSlot->legendConfig()->scalarMapper()); + + if (cellResultSlot->isTernarySaturationSelected()) + { + RivCellEdgeGeometryUtils::addTernaryCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultSlot, cellEdgeResultSlot, + quadToCellFaceMapper, dg, gridIndex, opacityLevel); + + RivTernaryScalarMapper* ternaryCellScalarMapper = cellResultSlot->ternaryLegendConfig()->scalarMapper(); + cellFaceEffectGen.setTernaryScalarMapper(ternaryCellScalarMapper); + } + else + { + RivCellEdgeGeometryUtils::addCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultSlot, cellEdgeResultSlot, + quadToCellFaceMapper, dg, gridIndex, opacityLevel); + + cvf::ScalarMapper* cellScalarMapper = cellResultSlot->legendConfig()->scalarMapper(); + cellFaceEffectGen.setScalarMapper(cellScalarMapper); + } + + cellFaceEffectGen.setOpacityLevel(opacityLevel); + cellFaceEffectGen.setDefaultCellColor(defaultColor); + cellFaceEffectGen.setFaceCulling(faceCulling); + + cvf::ref eff = cellFaceEffectGen.generateEffect(); + return eff; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivScalarMapperUtils::createScalarMapperEffect(const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling) +{ + CVF_ASSERT(mapper); + + caf::PolygonOffset polygonOffset = caf::PO_1; + caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); + scalarEffgen.setOpacityLevel(opacityLevel); + scalarEffgen.setFaceCulling(faceCulling); + + cvf::ref scalarEffect = scalarEffgen.generateEffect(); + + return scalarEffect; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivScalarMapperUtils::createTernaryScalarMapperEffect(const RivTernaryScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling) +{ + CVF_ASSERT(mapper); + + caf::PolygonOffset polygonOffset = caf::PO_1; + RivTernaryScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); + scalarEffgen.setOpacityLevel(opacityLevel); + scalarEffgen.setFaceCulling(faceCulling); + cvf::ref scalarEffect = scalarEffgen.generateEffect(); + + return scalarEffect; +} + diff --git a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h new file mode 100644 index 0000000000..64bd98dcee --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h @@ -0,0 +1,63 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "cafEffectGenerator.h" + +#include "cvfBase.h" +#include "cvfArray.h" + +namespace cvf +{ + class ScalarMapper; + class Part; + class Effect; + class StructGridQuadToCellFaceMapper; + class DrawableGeo; +} + +class RivTernaryScalarMapper; +class RimResultSlot; +class RimCellEdgeResultSlot; + +//================================================================================================== +/// +//================================================================================================== +class RivScalarMapperUtils +{ +public: + static void applyTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling); + static void applyTernaryTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const RivTernaryScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling); + + static cvf::ref createCellEdgeEffect(cvf::DrawableGeo* dg, + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, + size_t gridIndex, + size_t timeStepIndex, + RimResultSlot* cellResultSlot, + RimCellEdgeResultSlot* cellEdgeResultSlot, + float opacityLevel, + cvf::Color3f defaultColor, + caf::FaceCulling faceCulling); + +private: + static cvf::ref createScalarMapperEffect(const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling); + static cvf::ref createTernaryScalarMapperEffect(const RivTernaryScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling); +}; + diff --git a/ApplicationCode/ModelVisualization/RivSourceInfo.cpp b/ApplicationCode/ModelVisualization/RivSourceInfo.cpp index 9df69e03a9..4025bd1f9a 100644 --- a/ApplicationCode/ModelVisualization/RivSourceInfo.cpp +++ b/ApplicationCode/ModelVisualization/RivSourceInfo.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,14 +18,15 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RivSourceInfo.h" +#include "cvfStructGridGeometryGenerator.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RivSourceInfo::hasCellIndices() const +bool RivSourceInfo::hasCellFaceMapping() const { - return m_cellIndices.notNull(); + return m_cellFaceFromTriangleMapper.notNull(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ModelVisualization/RivSourceInfo.h b/ApplicationCode/ModelVisualization/RivSourceInfo.h index de670c52a7..5c53214770 100644 --- a/ApplicationCode/ModelVisualization/RivSourceInfo.h +++ b/ApplicationCode/ModelVisualization/RivSourceInfo.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -21,17 +22,15 @@ #include "cvfBase.h" #include "cvfObject.h" #include "cvfArray.h" -#include "cvfStructGrid.h" +#include "cvfStructGridGeometryGenerator.h" class RivSourceInfo : public cvf::Object { public: - bool hasCellIndices() const; + bool hasCellFaceMapping() const; bool hasNNCIndices() const; public: - cvf::ref > m_cellIndices; - cvf::ref > m_faceTypes; - - cvf::ref > m_NNCIndices; + cvf::cref m_cellFaceFromTriangleMapper; + cvf::ref > m_NNCIndices; }; diff --git a/ApplicationCode/ModelVisualization/RivTernaryResultToTextureMapper.h b/ApplicationCode/ModelVisualization/RivTernaryResultToTextureMapper.h new file mode 100644 index 0000000000..45c8604585 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivTernaryResultToTextureMapper.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigPipeInCellEvaluator.h" + +#include "RivTernaryScalarMapper.h" + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfStructGrid.h" +#include "cvfVector2.h" + +#include + +class RivTernaryResultToTextureMapper : public cvf::Object +{ +public: + RivTernaryResultToTextureMapper(const RivTernaryScalarMapper* scalarMapper, const RigPipeInCellEvaluator* pipeInCellEvaluator) + : m_scalarMapper(scalarMapper), m_pipeInCellEvaluator(pipeInCellEvaluator) + {} + + cvf::Vec2f getTexCoord(double soil, double sgas, size_t cellIndex) const + { + bool isTransparent = m_pipeInCellEvaluator->isWellPipeInCell(cellIndex); + + return m_scalarMapper->mapToTextureCoord(soil, sgas, isTransparent); + } + +private: + cvf::cref m_scalarMapper; + cvf::cref m_pipeInCellEvaluator; +}; + + diff --git a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp index 651297c813..b01401826f 100644 --- a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp +++ b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -41,7 +42,7 @@ RivTernarySaturationOverlayItem::RivTernarySaturationOverlayItem(cvf::Font* font) : m_textColor(cvf::Color3::BLACK), m_font(font), - m_size(100, 120) + m_size(100, 140) { } @@ -121,24 +122,48 @@ void RivTernarySaturationOverlayItem::render(cvf::OpenGLContext* oglContext, con cvf::TextDrawer textDrawer(m_font.p()); textDrawer.setTextColor(m_textColor); + float lineHeightInPixels = 10; + + float textPosY = static_cast(size.y() - 10); + for (size_t it = 0; it < m_titleStrings.size(); it++) + { + cvf::Vec2f pos(5, textPosY); + textDrawer.addText(m_titleStrings[it], pos); + + textPosY -= lineHeightInPixels; + } + + cvf::Vec2f pos(5, textPosY); + textDrawer.addText("TERNARY", pos); + textPosY -= lineHeightInPixels; + textPosY -= 2; + + { + cvf::uint sgasTextWidth = m_font->textExtent("SGAS").x(); + textDrawer.addText("SGAS", cvf::Vec2f(static_cast( (size.x() / 2) - sgasTextWidth / 2 ), textPosY)); + + cvf::uint sgasRangeTextWidth = m_font->textExtent(m_sgasRange).x(); + textPosY -= lineHeightInPixels; + textDrawer.addText(m_sgasRange, cvf::Vec2f(static_cast( (size.x() / 2) - sgasRangeTextWidth / 2 ), textPosY)); + } + textDrawer.addText("SWAT", cvf::Vec2f(0.0, 10.0)); textDrawer.addText(m_swatRange, cvf::Vec2f(0.0, 0.0)); - textDrawer.addText("SOIL", cvf::Vec2f(static_cast(size.x() - 25), 10.0)); - - float soilRangePos = static_cast(size.x() - 40); - if (m_soilRange.size() < 6) { - soilRangePos += 15; - } - textDrawer.addText(m_soilRange, cvf::Vec2f(soilRangePos, 0.0)); + cvf::uint soilTextWidth = m_font->textExtent("SOIL").x(); + textDrawer.addText("SOIL", cvf::Vec2f(static_cast(size.x() - soilTextWidth), 10.0)); - textDrawer.addText("SGAS", cvf::Vec2f(static_cast( (size.x() / 2) - 17 ), static_cast(size.y() - 10))); - textDrawer.addText(m_sgasRange, cvf::Vec2f(static_cast( (size.x() / 2) - 17 ), static_cast(size.y() - 20))); + cvf::uint soilRangeTextWidth = m_font->textExtent(m_soilRange).x(); + float soilRangePos = static_cast(size.x()) - soilRangeTextWidth; + + textDrawer.addText(m_soilRange, cvf::Vec2f(soilRangePos, 0.0)); + } textDrawer.renderSoftware(oglContext, camera); - renderAxisImmediateMode(oglContext); + textPosY -= 3; + renderAxisImmediateMode(textPosY, oglContext); CVF_CHECK_OGL(oglContext); } @@ -148,7 +173,7 @@ void RivTernarySaturationOverlayItem::render(cvf::OpenGLContext* oglContext, con //-------------------------------------------------------------------------------------------------- /// Draw the axis using immediate mode OpenGL //-------------------------------------------------------------------------------------------------- -void RivTernarySaturationOverlayItem::renderAxisImmediateMode(cvf::OpenGLContext* oglContext) +void RivTernarySaturationOverlayItem::renderAxisImmediateMode(float upperBoundY, cvf::OpenGLContext* oglContext) { #ifdef CVF_OPENGL_ES CVF_UNUSED(layout); @@ -166,7 +191,7 @@ void RivTernarySaturationOverlayItem::renderAxisImmediateMode(cvf::OpenGLContext cvf::Color3ub colC(cvf::Color3::RED); float lowerBoundY = 20; - float upperBoundY = static_cast(m_size.y() - 20); + //float upperBoundY = static_cast(m_size.y() - 20); cvf::Vec3f a(0, lowerBoundY, 0); cvf::Vec3f b(static_cast(m_size.x()), lowerBoundY, 0); @@ -219,4 +244,20 @@ void RivTernarySaturationOverlayItem::setRangeText(const cvf::String& soilRange, m_swatRange = swatRange; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTernarySaturationOverlayItem::setTitle(const cvf::String& title) +{ + // Title + if (title.isEmpty()) + { + m_titleStrings.clear(); + } + else + { + m_titleStrings = title.split("\n"); + } +} + diff --git a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h index ca145cf496..f2cdf4eb7a 100644 --- a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h +++ b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -48,12 +49,13 @@ class RivTernarySaturationOverlayItem : public cvf::OverlayItem virtual void renderSoftware(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size); void setSize(const cvf::Vec2ui& size); - void setAxisLabelsColor(const cvf::Color3f& color); + void setTitle(const cvf::String& title); + private: void render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size, bool software); - void renderAxisImmediateMode(cvf::OpenGLContext* oglContext); + void renderAxisImmediateMode(float upperY, cvf::OpenGLContext* oglContext); private: cvf::Color3f m_textColor; // Text color @@ -64,5 +66,7 @@ class RivTernarySaturationOverlayItem : public cvf::OverlayItem cvf::String m_swatRange; cvf::Vec2ui m_size; // Pixel size of draw area + + std::vector m_titleStrings; }; diff --git a/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.cpp b/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.cpp new file mode 100644 index 0000000000..b16a8d3c7c --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.cpp @@ -0,0 +1,130 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RivTernaryScalarMapper.h" +#include "cvfTextureImage.h" + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivTernaryScalarMapper::RivTernaryScalarMapper(const cvf::Color3f& undefScalarColor) +: m_undefScalarColor(undefScalarColor), + m_textureSize(128, 256) +{ + setTernaryRanges(0.0, 1.0, 0.0, 1.0); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2f RivTernaryScalarMapper::mapToTextureCoord(double soil, double sgas, bool isTransparent) const +{ + double soilNormalized = (soil - m_rangeMinSoil) * m_soilFactor; + soilNormalized = cvf::Math::clamp(soilNormalized, 0.0, 1.0); + + double sgasNormalized = (sgas - m_rangeMinSgas) * m_sgasFactor; + sgasNormalized = cvf::Math::clamp(sgasNormalized, 0.0, 1.0 - soilNormalized); + sgasNormalized /= 2.0; + + if (isTransparent) + { + sgasNormalized += 0.5; + } + + cvf::Vec2f texCoord(static_cast(soilNormalized), static_cast(sgasNormalized)); + return texCoord; +} + +//-------------------------------------------------------------------------------------------------- +/// F * +/// * * +/// * * +/// * * Texture in this region is assigned the given opacity level +/// * * +/// D *********** E +/// C * SGAS +/// * * +/// * * Texture in this region is opaque +/// * * +/// * * +/// A *********** B +/// SWAT SOIL +//-------------------------------------------------------------------------------------------------- +bool RivTernaryScalarMapper::updateTexture(cvf::TextureImage* image, float opacityLevel) const +{ + CVF_ASSERT(image); + image->allocate(m_textureSize.x(), m_textureSize.y()); + + // For now fill with white so we can see any errors more easily + image->fill(cvf::Color4ub(cvf::Color3::WHITE)); + + + + cvf::uint halfTextureHeight = m_textureSize.y() / 2; + + // Create texture + + float xStride = static_cast(1.0f / m_textureSize.x()); + float yStride = static_cast(1.0f / halfTextureHeight); + + float sgas_red = 0.0f; + for (cvf::uint yPos = 0; yPos < halfTextureHeight; yPos++) + { + float soil_green = 0.0f; + for (cvf::uint xPos = 0; xPos < m_textureSize.x() - yPos; xPos++) + { + float swat_blue = 1.0f - sgas_red - soil_green; + + cvf::Color3f floatCol(sgas_red, soil_green, swat_blue); + + cvf::ubyte rByteCol = floatCol.rByte(); + cvf::ubyte gByteCol = floatCol.gByte(); + cvf::ubyte bByteCol = floatCol.bByte(); + + const cvf::Color4ub clr(rByteCol, gByteCol, bByteCol, 255); + image->setPixel(xPos, yPos, clr); + + // Set opacity + const cvf::Color4ub clrOpacity(rByteCol, gByteCol, bByteCol, static_cast(255 * opacityLevel)); + image->setPixel(xPos, yPos + halfTextureHeight, clrOpacity); + + soil_green += xStride; + } + sgas_red += yStride; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTernaryScalarMapper::setTernaryRanges(double soilLower, double soilUpper, double sgasLower, double sgasUpper) +{ + m_rangeMinSoil = soilLower; + m_rangeMaxSoil = soilUpper; + m_soilFactor = 1.0 / (soilUpper - soilLower); + + m_rangeMinSgas = sgasLower; + m_rangeMaxSgas = sgasUpper; + m_sgasFactor = 1.0 / (sgasUpper - sgasLower); +} + diff --git a/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.h b/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.h new file mode 100644 index 0000000000..68c17b058e --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.h @@ -0,0 +1,57 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "cvfBase.h" +#include "cvfObject.h" +#include "cvfVector2.h" +#include "cvfColor3.h" + +namespace cvf +{ + class TextureImage; +} + +//================================================================================================== +/// +//================================================================================================== +class RivTernaryScalarMapper : public cvf::Object +{ +public: + RivTernaryScalarMapper(const cvf::Color3f& undefScalarColor); + + void setTernaryRanges(double soilLower, double soilUpper, double sgasLower, double sgasUpper); + + cvf::Vec2f mapToTextureCoord(double soil, double sgas, bool isTransparent) const; + bool updateTexture(cvf::TextureImage* image, float opacityLevel) const; + +private: + cvf::Color3f m_undefScalarColor; + cvf::Vec2ui m_textureSize; + + double m_rangeMaxSoil; + double m_rangeMinSoil; + double m_soilFactor; + + double m_rangeMaxSgas; + double m_rangeMinSgas; + double m_sgasFactor; +}; + diff --git a/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.cpp b/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.cpp new file mode 100644 index 0000000000..60b7630413 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.cpp @@ -0,0 +1,245 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RivTernaryScalarMapperEffectGenerator.h" + +#include "RivTernaryScalarMapper.h" + +#include "cvfRenderStateBlending.h" +#include "cvfRenderStateCullFace.h" +#include "cvfRenderStateDepth.h" +#include "cvfRenderStateTextureBindings.h" +#include "cvfRenderState_FF.h" +#include "cvfSampler.h" +#include "cvfShaderProgram.h" +#include "cvfShaderProgramGenerator.h" +#include "cvfShaderSourceProvider.h" +#include "cvfTexture.h" +#include "cvfTexture2D_FF.h" + + + +//================================================================================================== +// +// RivTernaryScalarMapperEffectGenerator +// +//================================================================================================== + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivTernaryScalarMapperEffectGenerator::RivTernaryScalarMapperEffectGenerator(const RivTernaryScalarMapper* scalarMapper, caf::PolygonOffset polygonOffset) + : m_undefinedColor(cvf::Color3::GRAY) +{ + m_scalarMapper = scalarMapper; + m_polygonOffset = polygonOffset; + m_opacityLevel = 1.0f; + m_faceCulling = caf::FC_NONE; + m_enableDepthWrite = true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTernaryScalarMapperEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) const +{ + cvf::ref eff = effect; + + cvf::ShaderProgramGenerator gen("ScalarMapperMeshEffectGenerator", cvf::ShaderSourceProvider::instance()); + gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); + gen.addFragmentCode(cvf::ShaderSourceRepository::src_Texture); + gen.addFragmentCode(caf::CommonShaderSources::light_AmbientDiffuse()); + gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard); + + cvf::ref prog = gen.generate(); + eff->setShaderProgram(prog.p()); + + // Result mapping texture + + m_textureImage = new cvf::TextureImage(); + m_scalarMapper->updateTexture(m_textureImage.p(), m_opacityLevel); + + cvf::ref texture = new cvf::Texture(m_textureImage.p()); + cvf::ref sampler = new cvf::Sampler; + sampler->setWrapMode(cvf::Sampler::CLAMP_TO_EDGE); + sampler->setMinFilter(cvf::Sampler::NEAREST); + sampler->setMagFilter(cvf::Sampler::NEAREST); + + cvf::ref texBind = new cvf::RenderStateTextureBindings; + texBind->addBinding(texture.p(), sampler.p(), "u_texture2D"); + eff->setRenderState(texBind.p()); + + // Hardware independent: + + updateCommonEffect(eff.p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTernaryScalarMapperEffectGenerator::updateForFixedFunctionRendering(cvf::Effect* effect) const +{ + cvf::ref eff = effect; + + cvf::ref mat = new cvf::RenderStateMaterial_FF(cvf::Color3::WHITE); + eff->setRenderState(mat.p()); + + cvf::ref lighting = new cvf::RenderStateLighting_FF; + lighting->enableTwoSided(true); + eff->setRenderState(lighting.p()); + + // Result mapping texture + + m_textureImage = new cvf::TextureImage; + m_scalarMapper->updateTexture(m_textureImage.p(), m_opacityLevel); + + cvf::ref texture = new cvf::Texture2D_FF(m_textureImage.p()); + texture->setWrapMode(cvf::Texture2D_FF::CLAMP); + texture->setMinFilter(cvf::Texture2D_FF::NEAREST); + texture->setMagFilter(cvf::Texture2D_FF::NEAREST); + cvf::ref texMapping = new cvf::RenderStateTextureMapping_FF(texture.p()); + eff->setRenderState(texMapping.p()); + + // Hardware independent: + + updateCommonEffect(eff.p()); + +} + +//-------------------------------------------------------------------------------------------------- +/// It also modifies the texture, and adds two more pixel lines +/// one with a transparent version of the legend color, and one with color for undefined values +//-------------------------------------------------------------------------------------------------- +void RivTernaryScalarMapperEffectGenerator::updateCommonEffect(cvf::Effect* effect) const +{ + CVF_ASSERT(effect); + + if (m_polygonOffset != caf::PO_NONE) + { + cvf::ref polyOffset = EffectGenerator::createAndConfigurePolygonOffsetRenderState(m_polygonOffset); + effect->setRenderState(polyOffset.p()); + } + + // Simple transparency + if (m_opacityLevel < 1.0f) + { + cvf::ref blender = new cvf::RenderStateBlending; + blender->configureTransparencyBlending(); + effect->setRenderState(blender.p()); + } + + // Backface culling + if (m_faceCulling != caf::FC_NONE) + { + cvf::ref faceCulling = new cvf::RenderStateCullFace; + if (m_faceCulling == caf::FC_BACK) + { + faceCulling->setMode(cvf::RenderStateCullFace::BACK); + } + else if (m_faceCulling == caf::FC_FRONT) + { + faceCulling->setMode(cvf::RenderStateCullFace::FRONT); + } + else if (m_faceCulling == caf::FC_FRONT_AND_BACK) + { + faceCulling->setMode(cvf::RenderStateCullFace::FRONT_AND_BACK); + } + + effect->setRenderState(faceCulling.p()); + } + + if (!m_enableDepthWrite) + { + cvf::ref depth = new cvf::RenderStateDepth; + depth->enableDepthWrite(false); + effect->setRenderState(depth.p()); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RivTernaryScalarMapperEffectGenerator::isEqual(const EffectGenerator* other) const +{ + const RivTernaryScalarMapperEffectGenerator* otherTextureResultEffect = dynamic_cast(other); + + if (otherTextureResultEffect) + { + if (m_scalarMapper.p() == otherTextureResultEffect->m_scalarMapper + && m_polygonOffset == otherTextureResultEffect->m_polygonOffset + && m_opacityLevel == otherTextureResultEffect->m_opacityLevel + && m_undefinedColor == otherTextureResultEffect->m_undefinedColor + && m_faceCulling == otherTextureResultEffect->m_faceCulling + && m_enableDepthWrite == otherTextureResultEffect->m_enableDepthWrite) + { + cvf::ref texImg2 = new cvf::TextureImage; + otherTextureResultEffect->m_scalarMapper->updateTexture(texImg2.p(), m_opacityLevel); + + return RivTernaryScalarMapperEffectGenerator::isImagesEqual(m_textureImage.p(), texImg2.p()); + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::EffectGenerator* RivTernaryScalarMapperEffectGenerator::copy() const +{ + RivTernaryScalarMapperEffectGenerator* scEffGen = new RivTernaryScalarMapperEffectGenerator(m_scalarMapper.p(), m_polygonOffset); + scEffGen->m_textureImage = m_textureImage; + scEffGen->m_opacityLevel = m_opacityLevel; + scEffGen->m_undefinedColor = m_undefinedColor; + scEffGen->m_faceCulling = m_faceCulling; + scEffGen->m_enableDepthWrite = m_enableDepthWrite; + + return scEffGen; +} + + +//-------------------------------------------------------------------------------------------------- +/// Tests whether two texture images are equal. It might in some rare cases not detect the difference +/// but to make the comparison fast only some sampling points are used. If both pointers are NULL, +/// they are considered equal. +//-------------------------------------------------------------------------------------------------- +bool RivTernaryScalarMapperEffectGenerator::isImagesEqual(const cvf::TextureImage* texImg1, const cvf::TextureImage* texImg2) +{ + if (texImg1 == NULL && texImg2 == NULL) return true; + + if (texImg1 != NULL && texImg2 != NULL + && texImg1->height() == texImg2->height() + && texImg1->width() == texImg2->width() + && texImg1->width() > 0 && texImg1->height() > 0 + && texImg1->pixel(0, 0) == texImg2->pixel(0, 0) + && texImg1->pixel(texImg1->width() - 1, texImg1->height() - 1) == texImg2->pixel(texImg1->width() - 1, texImg1->height() - 1) + && texImg1->pixel(texImg1->width() / 2, texImg1->height() / 2) == texImg2->pixel(texImg1->width() / 2, texImg1->height() / 2) + && texImg1->pixel(texImg1->width() / 4, texImg1->height() / 4) == texImg2->pixel(texImg1->width() / 4, texImg1->height() / 4) + && texImg1->pixel(texImg1->width() / 2 + texImg1->width() / 4, texImg1->height() / 2 + texImg1->height() / 4) == texImg2->pixel(texImg1->width() / 2 + texImg1->width() / 4, texImg1->height() / 2 + texImg1->height() / 4) + ) + { + return true; + } + + return false; +} + diff --git a/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.h b/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.h new file mode 100644 index 0000000000..d45121421b --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.h @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "cafEffectGenerator.h" + +class RivTernaryScalarMapper; + +namespace cvf +{ + class TextureImage; +} + +//================================================================================================== +// +// ScalarMapperEffectGenerator +// +//================================================================================================== +class RivTernaryScalarMapperEffectGenerator : public caf::EffectGenerator +{ +public: + RivTernaryScalarMapperEffectGenerator(const RivTernaryScalarMapper* scalarMapper, caf::PolygonOffset polygonOffset); + + void setOpacityLevel(float opacity) { m_opacityLevel = cvf::Math::clamp(opacity, 0.0f, 1.0f); } + void setUndefinedColor(cvf::Color3f color) { m_undefinedColor = color; } + void setFaceCulling(caf::FaceCulling faceCulling) { m_faceCulling = faceCulling; } + void enableDepthWrite(bool enableWrite) { m_enableDepthWrite = enableWrite; } + + +public: + static bool isImagesEqual(const cvf::TextureImage* texImg1, const cvf::TextureImage* texImg2); + +protected: + virtual bool isEqual(const caf::EffectGenerator* other) const; + virtual caf::EffectGenerator* copy() const; + + virtual void updateForShaderBasedRendering(cvf::Effect* effect) const; + virtual void updateForFixedFunctionRendering(cvf::Effect* effect) const; + +private: + void updateCommonEffect(cvf::Effect* effect) const; + +private: + cvf::cref m_scalarMapper; + mutable cvf::ref m_textureImage; + caf::PolygonOffset m_polygonOffset; + float m_opacityLevel; + cvf::Color3f m_undefinedColor; + caf::FaceCulling m_faceCulling; + bool m_enableDepthWrite; +}; + diff --git a/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp new file mode 100644 index 0000000000..edef41aca8 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp @@ -0,0 +1,115 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RivTernaryTextureCoordsCreator.h" + +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigPipeInCellEvaluator.h" +#include "RigResultAccessorFactory.h" +#include "RigTernaryResultAccessor2d.h" + +#include "RimCase.h" +#include "RimReservoirView.h" +#include "RimResultSlot.h" +#include "RimTernaryLegendConfig.h" +#include "RimWellCollection.h" + +#include "RivTernaryResultToTextureMapper.h" +#include "RivTernaryScalarMapper.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivTernaryTextureCoordsCreator::RivTernaryTextureCoordsCreator( + RimResultSlot* cellResultSlot, + RimTernaryLegendConfig* ternaryLegendConfig, + size_t timeStepIndex, + size_t gridIndex, + const cvf::StructGridQuadToCellFaceMapper* quadMapper) +{ + RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); + + m_quadMapper = quadMapper; + CVF_ASSERT(quadMapper && eclipseCase ); + + size_t resTimeStepIdx = timeStepIndex; + + if (cellResultSlot->hasStaticResult()) resTimeStepIdx = 0; + + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); + + cvf::ref soil = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SOIL"); + cvf::ref sgas = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SGAS"); + cvf::ref swat = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SWAT"); + + m_resultAccessor = new RigTernaryResultAccessor(); + m_resultAccessor->setTernaryResultAccessors(soil.p(), sgas.p(), swat.p()); + + cvf::ref pipeInCellEval = new RigPipeInCellEvaluator( cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex), + eclipseCase->gridCellToWellIndex(gridIndex)); + + const RivTernaryScalarMapper* mapper = ternaryLegendConfig->scalarMapper(); + + m_texMapper = new RivTernaryResultToTextureMapper(mapper, pipeInCellEval.p()); + CVF_ASSERT(m_texMapper.notNull()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTernaryTextureCoordsCreator::createTextureCoords(cvf::Vec2fArray* quadTextureCoords) +{ + createTextureCoords(quadTextureCoords, m_quadMapper.p(), m_resultAccessor.p(), m_texMapper.p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTernaryTextureCoordsCreator::createTextureCoords( + cvf::Vec2fArray* quadTextureCoords, + const cvf::StructGridQuadToCellFaceMapper* quadMapper, + const RigTernaryResultAccessor* resultAccessor, + const RivTernaryResultToTextureMapper* texMapper) +{ + CVF_ASSERT(quadTextureCoords && quadMapper && resultAccessor && texMapper); + + size_t numVertices = quadMapper->quadCount()*4; + quadTextureCoords->resize(numVertices); + cvf::Vec2f* rawPtr = quadTextureCoords->ptr(); + + cvf::Vec2d resultValue; + cvf::Vec2f texCoord; + +#pragma omp parallel for private(texCoord, resultValue) + for (int i = 0; i < static_cast(quadMapper->quadCount()); i++) + { + cvf::StructGridInterface::FaceType faceId = quadMapper->cellFace(i); + size_t cellIdx = quadMapper->cellIndex(i); + + resultValue = resultAccessor->cellFaceScalar(cellIdx, faceId); + texCoord = texMapper->getTexCoord(resultValue.x(), resultValue.y(), cellIdx); + + size_t j; + for (j = 0; j < 4; j++) + { + rawPtr[i*4 + j] = texCoord; + } + } +} diff --git a/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.h b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.h new file mode 100644 index 0000000000..d209c018f0 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.h @@ -0,0 +1,62 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigTernaryResultAccessor2d.h" +#include "RivTernaryResultToTextureMapper.h" + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfArray.h" + +class RimResultSlot; +class RimTernaryLegendConfig; + +namespace cvf +{ + class StructGridQuadToCellFaceMapper; +} + + +//================================================================================================== +/// +//================================================================================================== +class RivTernaryTextureCoordsCreator +{ +public: + RivTernaryTextureCoordsCreator( RimResultSlot* cellResultSlot, + RimTernaryLegendConfig* ternaryLegendConfig, + size_t timeStepIndex, + size_t gridIndex, + const cvf::StructGridQuadToCellFaceMapper* quadMapper); + + void createTextureCoords(cvf::Vec2fArray* quadTextureCoords); + +private: + static void createTextureCoords(cvf::Vec2fArray* quadTextureCoords, + const cvf::StructGridQuadToCellFaceMapper* quadMapper, + const RigTernaryResultAccessor* resultAccessor, + const RivTernaryResultToTextureMapper* texMapper); + +private: + cvf::cref m_quadMapper; + cvf::ref m_resultAccessor; + cvf::ref m_texMapper; +}; diff --git a/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.cpp b/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.cpp new file mode 100644 index 0000000000..4b3b8e6301 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.cpp @@ -0,0 +1,114 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RivTextureCoordsCreator.h" + +#include "RimResultSlot.h" +#include "RigCaseData.h" +#include "RimReservoirView.h" +#include "RimCase.h" +#include "RigCaseCellResultsData.h" +#include "RigResultAccessorFactory.h" +#include "RigPipeInCellEvaluator.h" +#include "RivResultToTextureMapper.h" +#include "RimWellCollection.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivTextureCoordsCreator::RivTextureCoordsCreator(RimResultSlot* cellResultSlot, size_t timeStepIndex, size_t gridIndex, const cvf::StructGridQuadToCellFaceMapper* quadMapper) +{ + RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); + + m_quadMapper = quadMapper; + CVF_ASSERT(quadMapper && eclipseCase ); + + size_t resTimeStepIdx = timeStepIndex; + + if (cellResultSlot->hasStaticResult()) resTimeStepIdx = 0; + + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); + + m_resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, cellResultSlot->resultVariable()); + + cvf::ref pipeInCellEval = new RigPipeInCellEvaluator(cellResultSlot->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex), + eclipseCase->gridCellToWellIndex(gridIndex)); + + const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper(); + + m_texMapper = new RivResultToTextureMapper(mapper, pipeInCellEval.p()); + CVF_ASSERT(m_texMapper.notNull()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RivTextureCoordsCreator::isValid() +{ + if (m_quadMapper.isNull() || m_resultAccessor.isNull() || m_texMapper.isNull()) + { + return false; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTextureCoordsCreator::createTextureCoords(cvf::Vec2fArray* quadTextureCoords) +{ + createTextureCoords(quadTextureCoords, m_quadMapper.p(), m_resultAccessor.p(), m_texMapper.p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivTextureCoordsCreator::createTextureCoords( + cvf::Vec2fArray* quadTextureCoords, + const cvf::StructGridQuadToCellFaceMapper* quadMapper, + const RigResultAccessor* resultAccessor, + const RivResultToTextureMapper* texMapper) +{ + CVF_ASSERT(quadTextureCoords && quadMapper && resultAccessor && texMapper); + + size_t numVertices = quadMapper->quadCount()*4; + quadTextureCoords->resize(numVertices); + cvf::Vec2f* rawPtr = quadTextureCoords->ptr(); + + double resultValue; + cvf::Vec2f texCoord; + +#pragma omp parallel for private(texCoord, resultValue) + for (int i = 0; i < static_cast(quadMapper->quadCount()); i++) + { + cvf::StructGridInterface::FaceType faceId = quadMapper->cellFace(i); + size_t cellIdx = quadMapper->cellIndex(i); + + resultValue = resultAccessor->cellFaceScalar(cellIdx, faceId); + texCoord = texMapper->getTexCoord(resultValue, cellIdx); + + size_t j; + for (j = 0; j < 4; j++) + { + rawPtr[i*4 + j] = texCoord; + } + } +} + diff --git a/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.h b/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.h new file mode 100644 index 0000000000..7c1a4f174d --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.h @@ -0,0 +1,58 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "cvfBase.h" +#include "cvfObject.h" +#include "cvfArray.h" + +class RimResultSlot; +class RigResultAccessor; +class RivResultToTextureMapper; + +namespace cvf +{ + class StructGridQuadToCellFaceMapper; +} + + +class RivTextureCoordsCreator +{ +public: + RivTextureCoordsCreator(RimResultSlot* cellResultSlot, + size_t timeStepIndex, + size_t gridIndex, + const cvf::StructGridQuadToCellFaceMapper* quadMapper); + + bool isValid(); + + void createTextureCoords(cvf::Vec2fArray* quadTextureCoords); + +private: + + static void createTextureCoords(cvf::Vec2fArray* quadTextureCoords, + const cvf::StructGridQuadToCellFaceMapper* quadMapper, + const RigResultAccessor* resultAccessor, + const RivResultToTextureMapper* texMapper); + cvf::cref m_quadMapper; + cvf::ref m_resultAccessor; + cvf::ref m_texMapper; +}; + diff --git a/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp index 3878329c7c..7b64b4f8be 100644 --- a/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -41,7 +43,7 @@ #include "RimCellRangeFilterCollection.h" #include "RimCellPropertyFilterCollection.h" #include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "RimResultSlot.h" #include "RimLegendConfig.h" diff --git a/ApplicationCode/ModelVisualization/RivWellPathCollectionPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellPathCollectionPartMgr.cpp index ee443be4ee..f2f7714f77 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathCollectionPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellPathCollectionPartMgr.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,27 +18,11 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RivWellPathCollectionPartMgr.h" -#include "RimProject.h" -#include "RimCase.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimScriptCollection.h" -#include "RimReservoirView.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimCaseCollection.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" + +#include "RimWellPath.h" #include "RimWellPathCollection.h" #include "RivWellPathPartMgr.h" -#include "RimWellPathCollection.h" -#include "RimCellRangeFilterCollection.h" -#include "RimOilField.h" -#include "RimAnalysisModels.h" //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ModelVisualization/RivWellPathCollectionPartMgr.h b/ApplicationCode/ModelVisualization/RivWellPathCollectionPartMgr.h index 8e5963d543..5f0171bc8c 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathCollectionPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellPathCollectionPartMgr.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,14 +20,25 @@ #pragma once - +#include "cvfBase.h" #include "cvfCollection.h" +#include "cafPdmPointer.h" +#include "cvfVector3.h" +#include "cvfBoundingBox.h" +#include "cvfTransform.h" + #include "cafPdmPointer.h" class RimWellPathCollection; class RimProject; class RivWellPathPartMgr; +namespace cvf +{ + class ModelBasicList; +} + + class RivWellPathCollectionPartMgr : public cvf::Object { public: diff --git a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp index 1ba6b3a2a1..6bc354e569 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -23,7 +25,7 @@ #include "RimCase.h" #include "RimProject.h" #include "RimWellPathCollection.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "RimIdenticalGridCaseGroup.h" #include "RimScriptCollection.h" #include "RimCaseCollection.h" diff --git a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.h b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.h index b1dc9ed3c8..0f01a673cd 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -28,6 +30,8 @@ namespace cvf class ModelBasicList; class Transform; class Effect; + class DrawableGeo; + class ScalarMapper; } class RivPipeGeometryGenerator; diff --git a/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp index 592da5a8a9..546a57fd57 100644 --- a/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -36,8 +38,9 @@ #include "RimCase.h" #include "RimReservoirView.h" +#include "RimWell.h" #include "RimWellCollection.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "RimResultSlot.h" #include "RimCellEdgeResultSlot.h" diff --git a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake index 1b265e3dd2..acfb39020e 100644 --- a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake @@ -39,7 +39,7 @@ ${CEE_CURRENT_LIST_DIR}RimBinaryExportSettings.h ${CEE_CURRENT_LIST_DIR}Rim3dOverlayInfoConfig.h ${CEE_CURRENT_LIST_DIR}RimUiTreeModelPdm.h ${CEE_CURRENT_LIST_DIR}RimUiTreeView.h -${CEE_CURRENT_LIST_DIR}RimReservoirCellResultsCacher.h +${CEE_CURRENT_LIST_DIR}RimReservoirCellResultsStorage.h ${CEE_CURRENT_LIST_DIR}RimStatisticsCaseEvaluator.h ${CEE_CURRENT_LIST_DIR}RimMimeData.h ${CEE_CURRENT_LIST_DIR}RimCommandObject.h @@ -48,6 +48,9 @@ ${CEE_CURRENT_LIST_DIR}RimFault.h ${CEE_CURRENT_LIST_DIR}RimFaultCollection.h ${CEE_CURRENT_LIST_DIR}RimMockModelSettings.h ${CEE_CURRENT_LIST_DIR}RimTernaryLegendConfig.h +${CEE_CURRENT_LIST_DIR}RimFaultResultSlot.h +${CEE_CURRENT_LIST_DIR}RimNoCommonAreaNNC.h +${CEE_CURRENT_LIST_DIR}RimNoCommonAreaNncCollection.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -85,7 +88,7 @@ ${CEE_CURRENT_LIST_DIR}RimBinaryExportSettings.cpp ${CEE_CURRENT_LIST_DIR}Rim3dOverlayInfoConfig.cpp ${CEE_CURRENT_LIST_DIR}RimUiTreeModelPdm.cpp ${CEE_CURRENT_LIST_DIR}RimUiTreeView.cpp -${CEE_CURRENT_LIST_DIR}RimReservoirCellResultsCacher.cpp +${CEE_CURRENT_LIST_DIR}RimReservoirCellResultsStorage.cpp ${CEE_CURRENT_LIST_DIR}RimStatisticsCaseEvaluator.cpp ${CEE_CURRENT_LIST_DIR}RimMimeData.cpp ${CEE_CURRENT_LIST_DIR}RimCommandObject.cpp @@ -94,6 +97,9 @@ ${CEE_CURRENT_LIST_DIR}RimFault.cpp ${CEE_CURRENT_LIST_DIR}RimFaultCollection.cpp ${CEE_CURRENT_LIST_DIR}RimMockModelSettings.cpp ${CEE_CURRENT_LIST_DIR}RimTernaryLegendConfig.cpp +${CEE_CURRENT_LIST_DIR}RimFaultResultSlot.cpp +${CEE_CURRENT_LIST_DIR}RimNoCommonAreaNNC.cpp +${CEE_CURRENT_LIST_DIR}RimNoCommonAreaNncCollection.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index 347895c6a1..9165ad92dc 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,20 +20,18 @@ #include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirView.h" -#include "RiuViewer.h" -#include "RimCase.h" +#include "RigCaseCellResultsData.h" #include "RigCaseData.h" -#include "RimResultSlot.h" +#include "RimCase.h" #include "RimCellEdgeResultSlot.h" -#include "RimReservoirCellResultsCacher.h" - #include "RimCellPropertyFilterCollection.h" -#include "RimCellRangeFilterCollection.h" - +#include "RimFaultCollection.h" +#include "RimFaultResultSlot.h" +#include "RimReservoirCellResultsStorage.h" +#include "RimReservoirView.h" +#include "RimResultSlot.h" #include "RimWellCollection.h" -#include "cafPdmFieldCvfMat4d.h" -#include "RigCaseCellResultsData.h" +#include "RiuViewer.h" CAF_PDM_SOURCE_INIT(Rim3dOverlayInfoConfig, "View3dOverlayInfoConfig"); @@ -84,7 +84,7 @@ void Rim3dOverlayInfoConfig::setPosition(cvf::Vec2ui position) //-------------------------------------------------------------------------------------------------- void Rim3dOverlayInfoConfig::update3DInfo() { - this->updateUiIconFromState(active); + this->updateUiIconFromToggleField(); if (!m_reservoirView) return; if (!m_reservoirView->viewer()) return; @@ -119,8 +119,8 @@ void Rim3dOverlayInfoConfig::update3DInfo() { caseName = m_reservoirView->eclipseCase()->caseUserDescription(); totCellCount = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cells().size()); - size_t mxActCellCount = m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->globalActiveCellCount(); - size_t frActCellCount = m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->globalActiveCellCount(); + size_t mxActCellCount = m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->reservoirActiveCellCount(); + size_t frActCellCount = m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->reservoirActiveCellCount(); if (frActCellCount > 0) activeCellCountText += "Matrix : "; activeCellCountText += QString::number(mxActCellCount); if (frActCellCount > 0) activeCellCountText += " Fracture : " + QString::number(frActCellCount); @@ -152,7 +152,7 @@ void Rim3dOverlayInfoConfig::update3DInfo() double min, max; double p10, p90; double mean; - size_t scalarIndex = m_reservoirView->cellResult()->gridScalarIndex(); + size_t scalarIndex = m_reservoirView->cellResult()->scalarResultIndex(); m_reservoirView->currentGridCellResults()->cellResults()->minMaxCellScalarValues(scalarIndex, min, max); m_reservoirView->currentGridCellResults()->cellResults()->p10p90CellScalarValues(scalarIndex, p10, p90); m_reservoirView->currentGridCellResults()->cellResults()->meanCellScalarValues(scalarIndex, mean); @@ -162,7 +162,7 @@ void Rim3dOverlayInfoConfig::update3DInfo() infoText += QString("" "
MinP10 Mean P90 Max
%1 %2 %3 %4 %5
").arg(min).arg(p10).arg(mean).arg(p90).arg(max); - if (m_reservoirView->faultCollection()->showResultsOnFaults()) + if (m_reservoirView->faultResultSettings()->hasValidCustomResult()) { QString faultMapping; bool isShowingGrid = m_reservoirView->faultCollection()->isGridVisualizationMode(); @@ -187,6 +187,8 @@ void Rim3dOverlayInfoConfig::update3DInfo() } infoText += QString("Fault results: %1
").arg(faultMapping); + + infoText += QString("Fault Property: %1
").arg(m_reservoirView->faultResultSettings()->customFaultResult()->resultVariable()); } } else @@ -224,7 +226,7 @@ void Rim3dOverlayInfoConfig::update3DInfo() double p10, p90; double mean; - size_t scalarIndex = m_reservoirView->cellResult()->gridScalarIndex(); + size_t scalarIndex = m_reservoirView->cellResult()->scalarResultIndex(); m_reservoirView->currentGridCellResults()->cellResults()->minMaxCellScalarValues(scalarIndex, min, max); m_reservoirView->currentGridCellResults()->cellResults()->p10p90CellScalarValues(scalarIndex, p10, p90); m_reservoirView->currentGridCellResults()->cellResults()->meanCellScalarValues(scalarIndex, mean); diff --git a/ApplicationCode/ProjectDataModel/RimAnalysisModels.cpp b/ApplicationCode/ProjectDataModel/RimAnalysisModels.cpp index e0968679fa..5a3f8f9408 100644 --- a/ApplicationCode/ProjectDataModel/RimAnalysisModels.cpp +++ b/ApplicationCode/ProjectDataModel/RimAnalysisModels.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,37 +18,17 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimAnalysisModels.h" -#include "RiaApplication.h" -#include "RimProject.h" -#include "cafAppEnum.h" -#include "RimReservoirView.h" - -#include "RimIdenticalGridCaseGroup.h" #include "RiaApplication.h" - -#include "RigGridManager.h" #include "RigCaseData.h" -#include "RimResultCase.h" -#include "RimWellPathCollection.h" - - -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimWellCollection.h" +#include "RigGridManager.h" +#include "RimCase.h" #include "RimCaseCollection.h" -#include "RimResultSlot.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RimProject.h" #include "RimStatisticsCase.h" -#include "RimOilField.h" -#include "RimScriptCollection.h" + CAF_PDM_SOURCE_INIT(RimAnalysisModels, "ResInsightAnalysisModels"); //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimAnalysisModels.h b/ApplicationCode/ProjectDataModel/RimAnalysisModels.h index b36cd1d28e..44673a9b8c 100644 --- a/ApplicationCode/ProjectDataModel/RimAnalysisModels.h +++ b/ApplicationCode/ProjectDataModel/RimAnalysisModels.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,7 +20,11 @@ #pragma once -#include "cafPdmDocument.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPointer.h" + +#include "cvfObject.h" class RimCase; class RigGridManager; diff --git a/ApplicationCode/ProjectDataModel/RimCase.cpp b/ApplicationCode/ProjectDataModel/RimCase.cpp index e412c1557e..9343c17afe 100644 --- a/ApplicationCode/ProjectDataModel/RimCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimCase.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,51 +18,30 @@ // ///////////////////////////////////////////////////////////////////////////////// -//#include "RiaStdInclude.h" #include "RimCase.h" -#include -#include -#include -#include +#include "RiaApplication.h" +#include "RiaPreferences.h" -#include "RifReaderEclipseOutput.h" -#include "RifReaderMockModel.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" -#include "RimReservoirView.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimCellRangeFilter.h" -#include "RimCellRangeFilterCollection.h" +#include "RimCaseCollection.h" +#include "RimCellEdgeResultSlot.h" #include "RimCellPropertyFilter.h" #include "RimCellPropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimWellCollection.h" -#include "RimWellPathCollection.h" - -#include "RimScriptCollection.h" - -#include "RigCaseData.h" -#include "RigMainGrid.h" -#include "RigCaseCellResultsData.h" - -#include "cvfAssert.h" +#include "RimReservoirCellResultsStorage.h" +#include "RimReservoirView.h" +#include "RimResultSlot.h" -#include "cafPdmFieldCvfColor.h" +#include "cafPdmDocument.h" +#include "cafProgressInfo.h" -#include "cafPdmUiPushButtonEditor.h" +#include +#include +#include +#include -#include -#include "RimProject.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimResultSlot.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCaseCollection.h" -#include "RimOilField.h" -#include "RimAnalysisModels.h" -#include "cafProgressInfo.h" CAF_PDM_SOURCE_INIT(RimCase, "RimReservoir"); @@ -159,6 +140,8 @@ RimReservoirView* RimCase::createAndAddReservoirView() RimReservoirView* riv = new RimReservoirView(); riv->setEclipseCase(this); + caf::PdmDocument::updateUiIconStateRecursively(riv); + size_t i = reservoirViews().size(); riv->name = QString("View %1").arg(i + 1); @@ -324,9 +307,13 @@ void RimCase::computeCachedData() rigEclipseCase->mainGrid()->computeCachedData(); pInf.incrementProgress(); - pInf.setProgressDescription("Calculating faults"); - rigEclipseCase->mainGrid()->calculateFaults(); - pInf.incrementProgress(); + RiaPreferences* prefs = RiaApplication::instance()->preferences(); + if (prefs->autocomputeGridFaults) + { + pInf.setProgressDescription("Calculating faults"); + rigEclipseCase->mainGrid()->calculateFaults(); + pInf.incrementProgress(); + } } } @@ -554,3 +541,40 @@ QString RimCase::relocateFile(const QString& orgFileName, const QString& orgNew return fileName; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimCase::openReserviorCase() +{ + // If read already, return + + if (this->reservoirData() != NULL) return true; + + if (!openEclipseGridFile()) + { + return false; + } + + { + RimReservoirCellResultsStorage* results = this->results(RifReaderInterface::MATRIX_RESULTS); + if (results->cellResults()) + { + results->cellResults()->createPlaceholderResultEntries(); + // After the placeholder result for combined transmissibility is created, + // make sure the nnc transmissibilities can be addressed by this scalarResultIndex as well + size_t combinedTransResIdx = results->cellResults()->findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::combinedTransmissibilityResultName()); + if (combinedTransResIdx != cvf::UNDEFINED_SIZE_T) + { + reservoirData()->mainGrid()->nncData()->setCombTransmisibilityScalarResultIndex(combinedTransResIdx); + } + } + + } + { + RimReservoirCellResultsStorage* results = this->results(RifReaderInterface::FRACTURE_RESULTS); + if (results->cellResults()) results->cellResults()->createPlaceholderResultEntries(); + } + + return true; +} diff --git a/ApplicationCode/ProjectDataModel/RimCase.h b/ApplicationCode/ProjectDataModel/RimCase.h index efb5801ba5..ccaee649f8 100644 --- a/ApplicationCode/ProjectDataModel/RimCase.h +++ b/ApplicationCode/ProjectDataModel/RimCase.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -57,7 +59,8 @@ class RimCase : public caf::PdmObject caf::PdmField > filesContainingFaults; - virtual bool openEclipseGridFile() { return false;}; // Should be pure virtual but PDM does not allow that. + bool openReserviorCase(); + virtual bool openEclipseGridFile() { return false; }; // Should be pure virtual but PDM does not allow that. RigCaseData* reservoirData(); const RigCaseData* reservoirData() const; diff --git a/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp b/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp index bf8064a8bb..2ab8bb64ad 100644 --- a/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,22 +19,10 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimCaseCollection.h" -#include "RimCase.h" -#include "RimReservoirView.h" +#include "RimCase.h" #include "RimIdenticalGridCaseGroup.h" -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" - -#include "RimReservoirCellResultsCacher.h" -#include "RimResultSlot.h" - -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimWellCollection.h" CAF_PDM_SOURCE_INIT(RimCaseCollection, "RimCaseCollection"); diff --git a/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp b/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp index 93383d0522..19926c6dee 100644 --- a/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,20 +19,15 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimCellEdgeResultSlot.h" -#include "RimReservoirCellResultsCacher.h" +#include "RigCaseCellResultsData.h" #include "RimLegendConfig.h" +#include "RimReservoirCellResultsStorage.h" #include "RimReservoirView.h" -#include "RigCaseCellResultsData.h" + #include "cafPdmUiListEditor.h" +#include "cvfMath.h" -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" -#include "RimResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimWellCollection.h" CAF_PDM_SOURCE_INIT(RimCellEdgeResultSlot, "CellEdgeResultSlot"); @@ -149,12 +146,12 @@ QList RimCellEdgeResultSlot::calculateValueOptions(const QList optionList; - std::map > varBaseNameToVarsMap; + std::map > varBaseNameToVarsMap; int i; for (i = 0; i < varList.size(); ++i) { - if (varList[i].compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) continue; + if (RimDefines::isPerCellFaceResult(varList[i])) continue; size_t cubeFaceIdx; for (cubeFaceIdx = 0; cubeFaceIdx < EdgeFaceEnum::size(); ++cubeFaceIdx) @@ -169,7 +166,7 @@ QList RimCellEdgeResultSlot::calculateValueOptions(const } } - std::map >::iterator it; + std::map >::iterator it; for (it = varBaseNameToVarsMap.begin(); it != varBaseNameToVarsMap.end(); ++it) { @@ -179,16 +176,16 @@ QList RimCellEdgeResultSlot::calculateValueOptions(const bool firstText = true; for (cubeFaceIdx = 0; cubeFaceIdx < 6; ++cubeFaceIdx) { - if (!it->second.v[cubeFaceIdx].isEmpty()) + if (!it->second[cubeFaceIdx].isEmpty()) { if (firstText) { - optionUiName += it->second.v[cubeFaceIdx]; + optionUiName += it->second[cubeFaceIdx]; firstText = false; } else { - optionUiName += QString(", ") + it->second.v[cubeFaceIdx]; + optionUiName += QString(", ") + it->second[cubeFaceIdx]; } } } @@ -225,9 +222,9 @@ QStringList RimCellEdgeResultSlot::findResultVariableNames() int i; for (i = 0; i < varList.size(); ++i) { - if (varList[i].compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) continue; + if (RimDefines::isPerCellFaceResult(varList[i])) continue; - if (varList[i].contains(resultVariable)) + if (varList[i].startsWith(resultVariable)) { varNames.append(varList[i]); } @@ -297,7 +294,7 @@ bool RimCellEdgeResultSlot::hasResult() const //-------------------------------------------------------------------------------------------------- void RimCellEdgeResultSlot::updateIgnoredScalarValue() { - if (resultVariable == "MULT") + if (resultVariable == "MULT" || resultVariable == "riMULT") { m_ignoredResultScalar = 1.0; } diff --git a/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h b/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h index 4bf0bd1ef1..8be396dad6 100644 --- a/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h +++ b/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,23 +24,12 @@ #include "cafPdmField.h" #include "cafAppEnum.h" #include "RimDefines.h" +#include "cafFixedArray.h" class RigCaseCellResultsData; class RimLegendConfig; class RimReservoirView; -namespace caf -{ -template -class fvector -{ -public: - T v[vectorSize]; - T& operator[] (size_t idx) { return v[idx]; } -const T& operator[] (size_t idx) const { return v[idx]; } - -}; -} //================================================================================================== /// @@ -86,7 +77,7 @@ class RimCellEdgeResultSlot : public caf::PdmObject void resetResultIndices(); void updateIgnoredScalarValue(); protected: - caf::fvector, 6 > m_resultNameToIndexPairs; + caf::FixedArray, 6 > m_resultNameToIndexPairs; caf::PdmPointer m_reservoirView; double m_ignoredResultScalar; }; diff --git a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp index abb2b6d3fc..e09bc9df37 100644 --- a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,13 +19,15 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimCellPropertyFilter.h" -#include "RimResultDefinition.h" -#include "cvfMath.h" -#include "RimCellPropertyFilterCollection.h" #include "RigCaseCellResultsData.h" +#include "RimCellPropertyFilterCollection.h" +#include "RimReservoirCellResultsStorage.h" +#include "RimResultDefinition.h" + #include "cafPdmUiDoubleSliderEditor.h" -#include "RimReservoirCellResultsCacher.h" +#include "cvfAssert.h" +#include "cvfMath.h" namespace caf @@ -126,21 +130,23 @@ QList RimCellPropertyFilter::calculateValueOptions(const { QList optionItems = resultDefinition->calculateValueOptions(fieldNeedingOptions, useOptionsOnly); - // Remove ternary from list, as it is not supported to perform filtering on a ternary result - int ternaryIndex = -1; + std::vector indicesToRemove; for (int i = 0; i < optionItems.size(); i++) { QString text = optionItems[i].optionUiText; - if (text.compare(RimDefines::ternarySaturationResultName(), Qt::CaseInsensitive) == 0) + if (RimDefines::isPerCellFaceResult(text)) { - ternaryIndex = i; + indicesToRemove.push_back(i); } } - if (ternaryIndex != -1) + std::sort(indicesToRemove.begin(), indicesToRemove.end()); + + std::vector::reverse_iterator rit; + for (rit = indicesToRemove.rbegin(); rit != indicesToRemove.rend(); ++rit) { - optionItems.takeAt(ternaryIndex); + optionItems.takeAt(*rit); } return optionItems; @@ -232,7 +238,7 @@ void RimCellPropertyFilter::computeResultValueRange() double min = 0.0; double max = 0.0; - size_t scalarIndex = resultDefinition->gridScalarIndex(); + size_t scalarIndex = resultDefinition->scalarResultIndex(); if (scalarIndex != cvf::UNDEFINED_SIZE_T) { RimReservoirCellResultsStorage* results = resultDefinition->currentGridCellResults(); diff --git a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h index 02c7677a60..7e92b29787 100644 --- a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h +++ b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,14 +20,7 @@ #pragma once -#include "cafPdmObject.h" -#include "cafPdmField.h" -#include "cafPdmDocument.h" -#include "cafAppEnum.h" - -#include "RimDefines.h" #include "RimCellFilter.h" -//#include "cvfStructGridGeometryGenerator.h" class RimReservoirView; class RimCellPropertyFilterCollection; @@ -34,10 +29,6 @@ class RimResultDefinition; class RigGridBase; class RigCaseCellResultsData; -namespace cvf -{ - //enum CellRangeFilter::CellStateType; -} //================================================================================================== /// @@ -81,5 +72,3 @@ class RimCellPropertyFilter : public RimCellFilter double m_minimumResultValue, m_maximumResultValue; }; - - diff --git a/ApplicationCode/ProjectDataModel/RimCellPropertyFilterCollection.cpp b/ApplicationCode/ProjectDataModel/RimCellPropertyFilterCollection.cpp index b12923b5c5..c4bac8aaac 100644 --- a/ApplicationCode/ProjectDataModel/RimCellPropertyFilterCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellPropertyFilterCollection.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,13 +24,6 @@ #include "RimResultDefinition.h" #include "RimResultSlot.h" -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" -#include "RimCellRangeFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimWellCollection.h" -#include "RimCellEdgeResultSlot.h" - CAF_PDM_SOURCE_INIT(RimCellPropertyFilterCollection, "CellPropertyFilters"); @@ -83,7 +78,7 @@ RimReservoirView* RimCellPropertyFilterCollection::reservoirView() //-------------------------------------------------------------------------------------------------- void RimCellPropertyFilterCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - this->updateUiIconFromState(active); + this->updateUiIconFromToggleField(); m_reservoirView->fieldChangedByUi(&(m_reservoirView->propertyFilterCollection), oldValue, newValue); } @@ -138,6 +133,8 @@ void RimCellPropertyFilterCollection::loadAndInitializePropertyFilters() void RimCellPropertyFilterCollection::initAfterRead() { loadAndInitializePropertyFilters(); + + this->updateUiIconFromToggleField(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp index 2bb0fc64cf..15fff47817 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,26 +18,19 @@ // ///////////////////////////////////////////////////////////////////////////////// -//#include "RiaStdInclude.h" #include "RimCellRangeFilter.h" -#include "RimCellRangeFilterCollection.h" -#include "RimReservoirView.h" + +#include "RigActiveCellInfo.h" #include "RigCaseData.h" +#include "RigGridBase.h" +#include "RigMainGrid.h" #include "RimCase.h" - -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" #include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirView.h" #include "cafPdmUiSliderEditor.h" - +#include "cvfAssert.h" CAF_PDM_SOURCE_INIT(RimCellRangeFilter, "CellRangeFilter"); diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.h b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.h index acb2372a87..78ee97f190 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.h +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,11 +20,11 @@ #pragma once -#include "cafPdmField.h" -#include "cafPdmObject.h" -#include "cafPdmPointer.h" #include "RimCellFilter.h" +class RigGridBase; +class RigMainGrid; +class RimCellRangeFilterCollection; class RimReservoirView; namespace cvf @@ -30,10 +32,6 @@ namespace cvf class CellRangeFilter; } -class RimCellRangeFilterCollection; -class RigMainGrid; -class RigGridBase; - //================================================================================================== /// /// diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp index eb9bc8bbba..ff430c838e 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,20 +18,12 @@ // ///////////////////////////////////////////////////////////////////////////////// -//#include "RiaStdInclude.h" - #include "RimCellRangeFilterCollection.h" + #include "RimCase.h" +#include "RigGridBase.h" #include "RimReservoirView.h" #include "RigCaseData.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimWellCollection.h" CAF_PDM_SOURCE_INIT(RimCellRangeFilterCollection, "CellRangeFilterCollection"); @@ -146,7 +140,7 @@ RigActiveCellInfo* RimCellRangeFilterCollection::activeCellInfo() const //-------------------------------------------------------------------------------------------------- void RimCellRangeFilterCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - updateUiIconFromState(isActive); + this->updateUiIconFromToggleField(); CVF_ASSERT(m_reservoirView); @@ -192,8 +186,9 @@ void RimCellRangeFilterCollection::initAfterRead() RimCellRangeFilter* rangeFilter = *it; rangeFilter->setParentContainer(this); rangeFilter->updateIconState(); - } + + this->updateUiIconFromToggleField(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimCommandObject.cpp b/ApplicationCode/ProjectDataModel/RimCommandObject.cpp index f24c7bd956..56b934001d 100644 --- a/ApplicationCode/ProjectDataModel/RimCommandObject.cpp +++ b/ApplicationCode/ProjectDataModel/RimCommandObject.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,34 +19,17 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimCommandObject.h" + #include "RiaApplication.h" #include "RimCalcScript.h" #include "RimProject.h" +#include "RimStatisticsCase.h" -#include "cafPdmUiTextEditor.h" -#include "cafPdmUiPushButtonEditor.h" #include "cafPdmDocument.h" +#include "cafPdmUiPushButtonEditor.h" +#include "cafPdmUiTextEditor.h" #include -#include "RimStatisticsCase.h" - -// Included due to template use in pdm fields -#include "RimReservoirView.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimOilField.h" -#include "RimScriptCollection.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimAnalysisModels.h" -#include "RimWellPathCollection.h" -#include "RimCaseCollection.h" - - CAF_PDM_SOURCE_INIT(RimCommandObject, "RimCommandObject"); @@ -106,13 +91,7 @@ void RimCommandExecuteScript::redo() QString octavePath = app->octavePath(); if (!octavePath.isEmpty()) { - // http://www.gnu.org/software/octave/doc/interpreter/Command-Line-Options.html#Command-Line-Options - - QStringList arguments; - arguments.append("--path"); - arguments << QApplication::applicationDirPath(); - - arguments.append("-q"); + QStringList arguments = app->octaveArguments(); arguments.append("--eval"); arguments << this->scriptText(); diff --git a/ApplicationCode/ProjectDataModel/RimCommandObject.h b/ApplicationCode/ProjectDataModel/RimCommandObject.h index 4123802cda..33c596565d 100644 --- a/ApplicationCode/ProjectDataModel/RimCommandObject.h +++ b/ApplicationCode/ProjectDataModel/RimCommandObject.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -24,7 +26,6 @@ #include "cafPdmObject.h" #include "cafPdmDocument.h" -#include //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/ProjectDataModel/RimDefines.cpp b/ApplicationCode/ProjectDataModel/RimDefines.cpp index 9fce926af4..ccc6eb4dab 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.cpp +++ b/ApplicationCode/ProjectDataModel/RimDefines.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -46,3 +48,36 @@ namespace caf } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimDefines::isPerCellFaceResult(const QString& resultName) +{ + if (resultName.compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) + { + return true; + } + else if (resultName.compare(RimDefines::combinedMultResultName(), Qt::CaseInsensitive) == 0) + { + return true; + } + else if (resultName.compare(RimDefines::ternarySaturationResultName(), Qt::CaseInsensitive) == 0) + { + return true; + } + else if (resultName.compare(RimDefines::combinedRiTranResultName(), Qt::CaseInsensitive) == 0) + { + return true; + } + else if (resultName.compare(RimDefines::combinedRiMultResultName(), Qt::CaseInsensitive) == 0) + { + return true; + } + else if (resultName.compare(RimDefines::combinedRiAreaNormTranResultName(), Qt::CaseInsensitive) == 0) + { + return true; + } + + return false; +} diff --git a/ApplicationCode/ProjectDataModel/RimDefines.h b/ApplicationCode/ProjectDataModel/RimDefines.h index c55a7b04e4..21c0addb60 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.h +++ b/ApplicationCode/ProjectDataModel/RimDefines.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -39,11 +41,28 @@ class RimDefines FRACTURE_MODEL }; - static QString undefinedResultName() { return "None"; } - static QString undefinedGridFaultName() { return "Undefined grid faults"; } - static QString combinedTransmissibilityResultName() { return "TRANSXYZ"; } + static bool isPerCellFaceResult(const QString& resultName); + + static QString undefinedResultName() { return "None"; } + static QString undefinedGridFaultName() { return "Undefined grid faults"; } + static QString combinedTransmissibilityResultName() { return "TRANXYZ"; } static QString ternarySaturationResultName() { return "TERNARY"; } + static QString combinedMultResultName() { return "MULTXYZ"; } + + static QString riTranXResultName() { return "riTRANX"; } + static QString riTranYResultName() { return "riTRANY"; } + static QString riTranZResultName() { return "riTRANZ"; } + static QString combinedRiTranResultName() { return "riTRANXYZ"; } + + static QString riMultXResultName() { return "riMULTX"; } + static QString riMultYResultName() { return "riMULTY"; } + static QString riMultZResultName() { return "riMULTZ"; } + static QString combinedRiMultResultName() { return "riMULTXYZ"; } + static QString riAreaNormTranXResultName() { return "riTRANXbyArea"; } + static QString riAreaNormTranYResultName() { return "riTRANYbyArea"; } + static QString riAreaNormTranZResultName() { return "riTRANZbyArea"; } + static QString combinedRiAreaNormTranResultName() { return "riTRANXYZbyArea"; } // Mock model text identifiers static QString mockModelBasic() { return "Result Mock Debug Model Simple"; } diff --git a/ApplicationCode/ProjectDataModel/RimFault.cpp b/ApplicationCode/ProjectDataModel/RimFault.cpp index 88a3686a19..ab499fea80 100644 --- a/ApplicationCode/ProjectDataModel/RimFault.cpp +++ b/ApplicationCode/ProjectDataModel/RimFault.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -21,12 +22,6 @@ #include "RigFault.h" #include "RimReservoirView.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimCellRangeFilterCollection.h" -#include "RimWellCollection.h" CAF_PDM_SOURCE_INIT(RimFault, "Fault"); @@ -69,20 +64,9 @@ caf::PdmFieldHandle* RimFault::userDescriptionField() //-------------------------------------------------------------------------------------------------- void RimFault::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - if (&showFault == changedField) - { - this->updateUiIconFromState(showFault); - - RimReservoirView* reservoirView = NULL; - this->firstAncestorOfType(reservoirView); - - if (reservoirView) - { - reservoirView->scheduleCreateDisplayModelAndRedraw(); - } - } + this->updateUiIconFromToggleField(); - if (&faultColor == changedField) + if (&faultColor == changedField || &showFault == changedField) { RimReservoirView* reservoirView = NULL; this->firstAncestorOfType(reservoirView); diff --git a/ApplicationCode/ProjectDataModel/RimFault.h b/ApplicationCode/ProjectDataModel/RimFault.h index b85c18d7da..b8aeaf91b4 100644 --- a/ApplicationCode/ProjectDataModel/RimFault.h +++ b/ApplicationCode/ProjectDataModel/RimFault.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -23,8 +24,9 @@ #include "cafPdmPointer.h" #include "cvfBase.h" -#include "cvfColor3.h" -#include "cafPdmFieldCvfColor.h" + +// Include to make Pdm work for cvf::Color +#include "cafPdmFieldCvfColor.h" class RigFault; diff --git a/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp b/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp index b6a201af09..e16532c68e 100644 --- a/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,27 +19,19 @@ #include "RimFaultCollection.h" -#include "cafAppEnum.h" -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" -#include "RimReservoirView.h" - -#include "RimResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" - -#include "Rim3dOverlayInfoConfig.h" -#include "RimCellEdgeResultSlot.h" #include "RiaApplication.h" #include "RiaPreferences.h" - -#include "RimCase.h" -#include "RimReservoirCellResultsCacher.h" #include "RigCaseData.h" -#include "RivColorTableArray.h" +#include "RimCase.h" +#include "RimNoCommonAreaNNC.h" +#include "RimNoCommonAreaNncCollection.h" +#include "RimReservoirView.h" #include "RiuMainWindow.h" +#include "RivColorTableArray.h" +#include "cafAppEnum.h" +#include "cafPdmFieldCvfColor.h" +#include "cafPdmFieldCvfMat4d.h" namespace caf { @@ -67,22 +60,23 @@ RimFaultCollection::RimFaultCollection() CAF_PDM_InitField(&showFaultCollection, "Active", true, "Active", "", "", ""); showFaultCollection.setUiHidden(true); - CAF_PDM_InitField(&showGeometryDetectedFaults, "ShowGeometryDetectedFaults", false, "Show geometry detected faults", "", "", ""); - showGeometryDetectedFaults.setUiHidden(true); - CAF_PDM_InitField(&showFaultFaces, "ShowFaultFaces", true, "Show defined faces", "", "", ""); CAF_PDM_InitField(&showOppositeFaultFaces, "ShowOppositeFaultFaces", true, "Show opposite faces", "", "", ""); - CAF_PDM_InitField(&showNNCs, "ShowNNCs", false, "Show NNCs", "", "", ""); - CAF_PDM_InitField(&showResultsOnFaults, "ShowResultsOnFaults", true, "Show results on faults", "", "", ""); - CAF_PDM_InitField(&showFaultsOutsideFilters,"ShowFaultsOutsideFilters", true, "Show faults outside filters", "", "", ""); + CAF_PDM_InitField(&m_showFaultsOutsideFilters,"ShowFaultsOutsideFilters", true, "Show faults outside filters", "", "", ""); CAF_PDM_InitField(&faultResult, "FaultFaceCulling", caf::AppEnum(RimFaultCollection::FAULT_BACK_FACE_CULLING), "Dynamic Face Selection", "", "", ""); CAF_PDM_InitField(&showFaultLabel, "ShowFaultLabel", false, "Show labels", "", "", ""); cvf::Color3f defWellLabelColor = RiaApplication::instance()->preferences()->defaultWellLabelColor(); CAF_PDM_InitField(&faultLabelColor, "FaultLabelColor", defWellLabelColor, "Label color", "", "", ""); + + CAF_PDM_InitField(&showNNCs, "ShowNNCs", true, "Show NNCs", "", "", ""); + CAF_PDM_InitField(&hideNncsWhenNoResultIsAvailable, "HideNncsWhenNoResultIsAvailable", true, "Hide NNC geometry if no NNC result is available", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&noCommonAreaNnncCollection, "NoCommonAreaNnncCollection", "NNCs With No Common Area", "", "", ""); + noCommonAreaNnncCollection = new RimNoCommonAreaNncCollection; - CAF_PDM_InitFieldNoDefault(&faults, "Faults", "Faults", "", "", ""); + CAF_PDM_InitFieldNoDefault(&faults, "Faults", "Faults", "", "", ""); m_reservoirView = NULL; } @@ -93,6 +87,8 @@ RimFaultCollection::RimFaultCollection() RimFaultCollection::~RimFaultCollection() { faults.deleteAllChildObjects(); + + delete noCommonAreaNnncCollection(); } @@ -101,26 +97,22 @@ RimFaultCollection::~RimFaultCollection() //-------------------------------------------------------------------------------------------------- void RimFaultCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - if (&showFaultCollection == changedField) - { - this->updateUiIconFromState(showFaultCollection); - } - + this->updateUiIconFromToggleField(); + if (&faultLabelColor == changedField) { m_reservoirView->scheduleReservoirGridGeometryRegen(); } - if (&showGeometryDetectedFaults == changedField || - &showFaultFaces == changedField || + if (&showFaultFaces == changedField || &showOppositeFaultFaces == changedField || - &showNNCs == changedField || &showFaultCollection == changedField || &showFaultLabel == changedField || - &showFaultsOutsideFilters == changedField || + &m_showFaultsOutsideFilters == changedField || &faultLabelColor == changedField || &faultResult == changedField || - &showResultsOnFaults == changedField + &showNNCs == changedField || + &hideNncsWhenNoResultIsAvailable == changedField ) { if (m_reservoirView) @@ -247,6 +239,73 @@ void RimFaultCollection::syncronizeFaults() QString toolTip = QString("Fault count (%1)").arg(newFaults.size()); setUiToolTip(toolTip); + + // NNCs + this->noCommonAreaNnncCollection()->noCommonAreaNncs().deleteAllChildObjects(); + + RigMainGrid* mainGrid = m_reservoirView->eclipseCase()->reservoirData()->mainGrid(); + std::vector& nncConnections = mainGrid->nncData()->connections(); + for (size_t i = 0; i < nncConnections.size(); i++) + { + if (!nncConnections[i].hasCommonArea()) + { + RimNoCommonAreaNNC* noCommonAreaNnc = new RimNoCommonAreaNNC(); + + QString firstConnectionText; + QString secondConnectionText; + + { + const RigCell& cell = mainGrid->cells()[nncConnections[i].m_c1GlobIdx]; + + RigGridBase* hostGrid = cell.hostGrid(); + size_t gridLocalCellIndex = cell.gridLocalCellIndex(); + + size_t i, j, k; + if (hostGrid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k)) + { + // Adjust to 1-based Eclipse indexing + i++; + j++; + k++; + + if (!hostGrid->isMainGrid()) + { + QString gridName = QString::fromStdString(hostGrid->gridName()); + firstConnectionText = gridName + " "; + } + firstConnectionText += QString("[%1 %2 %3] - ").arg(i).arg(j).arg(k); + } + } + + { + const RigCell& cell = mainGrid->cells()[nncConnections[i].m_c2GlobIdx]; + + RigGridBase* hostGrid = cell.hostGrid(); + size_t gridLocalCellIndex = cell.gridLocalCellIndex(); + + size_t i, j, k; + if (hostGrid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k)) + { + // Adjust to 1-based Eclipse indexing + i++; + j++; + k++; + + if (!hostGrid->isMainGrid()) + { + QString gridName = QString::fromStdString(hostGrid->gridName()); + secondConnectionText = gridName + " "; + } + secondConnectionText += QString("[%1 %2 %3]").arg(i).arg(j).arg(k); + } + } + + noCommonAreaNnc->name = firstConnectionText + secondConnectionText; + this->noCommonAreaNnncCollection()->noCommonAreaNncs().push_back(noCommonAreaNnc); + } + + this->noCommonAreaNnncCollection()->updateName(); + } } //-------------------------------------------------------------------------------------------------- @@ -275,13 +334,43 @@ void RimFaultCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrderi labs->add(&faultLabelColor); caf::PdmUiGroup* adv = uiOrdering.addNewGroup("Fault Options"); - adv->add(&showFaultsOutsideFilters); - adv->add(&showResultsOnFaults); - adv->add(&showNNCs); + adv->add(&m_showFaultsOutsideFilters); caf::PdmUiGroup* ffviz = uiOrdering.addNewGroup("Fault Face Visibility"); ffviz->add(&showFaultFaces); ffviz->add(&showOppositeFaultFaces); ffviz->add(&faultResult); + + caf::PdmUiGroup* nncViz = uiOrdering.addNewGroup("NNC Visibility"); + nncViz->add(&showNNCs); + nncViz->add(&hideNncsWhenNoResultIsAvailable); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFaultCollection::showFaultsOutsideFilters() const +{ + if (!showFaultCollection) return false; + + return m_showFaultsOutsideFilters; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFaultCollection::setShowFaultsOutsideFilters(bool enableState) +{ + m_showFaultsOutsideFilters = enableState; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFaultCollection::addMockData() +{ + if (!(m_reservoirView && m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData() && m_reservoirView->eclipseCase()->reservoirData()->mainGrid())) return; + } diff --git a/ApplicationCode/ProjectDataModel/RimFaultCollection.h b/ApplicationCode/ProjectDataModel/RimFaultCollection.h index 632c3bd7c8..54c93b908b 100644 --- a/ApplicationCode/ProjectDataModel/RimFaultCollection.h +++ b/ApplicationCode/ProjectDataModel/RimFaultCollection.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,19 +19,22 @@ #pragma once +#include "cafAppEnum.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" -#include "cafAppEnum.h" -#include - #include "cvfBase.h" -#include "cvfColor3.h" -#include "RimFault.h" +// Include to make Pdm work for cvf::Color +#include "cafPdmFieldCvfColor.h" -class RimReservoirView; +#include "RimReservoirCellResultsStorage.h" +#include + +class RimFault; +class RimReservoirView; +class RimNoCommonAreaNncCollection; //================================================================================================== /// @@ -54,15 +58,15 @@ class RimFaultCollection : public caf::PdmObject void setReservoirView(RimReservoirView* ownerReservoirView); void syncronizeFaults(); - bool isGridVisualizationMode() const; + void addMockData(); - caf::PdmField showGeometryDetectedFaults; // Obsolete, to be removed + bool isGridVisualizationMode() const; + + bool showFaultsOutsideFilters() const; + void setShowFaultsOutsideFilters(bool enableState); caf::PdmField showFaultFaces; caf::PdmField showOppositeFaultFaces; - caf::PdmField showFaultsOutsideFilters; - caf::PdmField showNNCs; - caf::PdmField showResultsOnFaults; caf::PdmField > faultResult; @@ -71,18 +75,22 @@ class RimFaultCollection : public caf::PdmObject caf::PdmField faultLabelColor; caf::PdmField showFaultCollection; + caf::PdmField showNNCs; + caf::PdmField hideNncsWhenNoResultIsAvailable; caf::PdmPointersField faults; + RimFault* findFaultByName(QString name); + + caf::PdmField noCommonAreaNnncCollection; virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); virtual caf::PdmFieldHandle* objectToggleField(); private: - RimFault* findFaultByName(QString name); - virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); private: - RimReservoirView* m_reservoirView; + caf::PdmField m_showFaultsOutsideFilters; + RimReservoirView* m_reservoirView; }; diff --git a/ApplicationCode/ProjectDataModel/RimFaultResultSlot.cpp b/ApplicationCode/ProjectDataModel/RimFaultResultSlot.cpp new file mode 100644 index 0000000000..f29f1408b4 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimFaultResultSlot.cpp @@ -0,0 +1,160 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RimFaultResultSlot.h" + +#include "RigCaseData.h" +#include "RigMainGrid.h" + +#include "RimCase.h" +#include "RimReservoirView.h" +#include "RimResultSlot.h" +#include "RimUiTreeModelPdm.h" +#include "RiuMainWindow.h" + + + +CAF_PDM_SOURCE_INIT(RimFaultResultSlot, "RimFaultResultSlot"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFaultResultSlot::RimFaultResultSlot() +{ + CAF_PDM_InitObject("Fault Result Slot", ":/draw_style_faults_24x24.png", "", ""); + + CAF_PDM_InitField(&showCustomFaultResult, "ShowCustomFaultResult", false, "Show Custom Fault Result", "", "", ""); + showCustomFaultResult.setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_customFaultResult, "CustomResultSlot", "Custom Fault Result", ":/CellResult.png", "", ""); + m_customFaultResult = new RimResultSlot(); + m_customFaultResult.setOwnerObject(this); + m_customFaultResult.setUiHidden(true); + + // Take ownership of the fields in RimResultDefinition to be able to trap fieldChangedByUi in this class + m_customFaultResult->m_resultTypeUiField.setOwnerObject(this); + m_customFaultResult->m_porosityModelUiField.setOwnerObject(this); + m_customFaultResult->m_resultVariableUiField.setOwnerObject(this); + + + updateFieldVisibility(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFaultResultSlot::~RimFaultResultSlot() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFaultResultSlot::setReservoirView(RimReservoirView* ownerReservoirView) +{ + m_reservoirView = ownerReservoirView; + m_customFaultResult->setReservoirView(ownerReservoirView); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFaultResultSlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + this->updateUiIconFromToggleField(); + + m_customFaultResult->fieldChangedByUi(changedField, oldValue, newValue); + + if (changedField == &m_customFaultResult->m_resultVariableUiField) + { + RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this); + } + + if (m_reservoirView) m_reservoirView->scheduleCreateDisplayModelAndRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFaultResultSlot::initAfterRead() +{ + m_customFaultResult->initAfterRead(); + updateFieldVisibility(); + + this->updateUiIconFromToggleField(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFaultResultSlot::updateFieldVisibility() +{ + m_customFaultResult->updateFieldVisibility(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimResultSlot* RimFaultResultSlot::customFaultResult() +{ + return this->m_customFaultResult(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimFaultResultSlot::objectToggleField() +{ + return &showCustomFaultResult; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFaultResultSlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiGroup* group1 = uiOrdering.addNewGroup("Result"); + group1->add(&(m_customFaultResult->m_resultTypeUiField)); + group1->add(&(m_customFaultResult->m_porosityModelUiField)); + group1->add(&(m_customFaultResult->m_resultVariableUiField)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimFaultResultSlot::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +{ + return m_customFaultResult->calculateValueOptionsForSpecifiedDerivedListPosition(true, fieldNeedingOptions, useOptionsOnly); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFaultResultSlot::hasValidCustomResult() +{ + if (this->showCustomFaultResult()) + { + if (m_customFaultResult->hasResult() || m_customFaultResult->isTernarySaturationSelected()) + { + return true; + } + } + + return false; +} diff --git a/ApplicationCode/ProjectDataModel/RimFaultResultSlot.h b/ApplicationCode/ProjectDataModel/RimFaultResultSlot.h new file mode 100644 index 0000000000..b123503faa --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimFaultResultSlot.h @@ -0,0 +1,62 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "cafAppEnum.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +class RimResultSlot; +class RimReservoirView; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimFaultResultSlot : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimFaultResultSlot(); + virtual ~RimFaultResultSlot(); + + void setReservoirView(RimReservoirView* ownerReservoirView); + + caf::PdmField showCustomFaultResult; + + bool hasValidCustomResult(); + RimResultSlot* customFaultResult(); + + void updateFieldVisibility(); + + virtual QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ); + +protected: + virtual void initAfterRead(); + virtual caf::PdmFieldHandle* objectToggleField(); + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) ; + +private: + caf::PdmField m_customFaultResult; + caf::PdmPointer m_reservoirView; +}; + diff --git a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp index 0b1708f315..68aae7017e 100644 --- a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp +++ b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp @@ -1,7 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,33 +19,21 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimIdenticalGridCaseGroup.h" -#include "RimCaseCollection.h" +#include "RigActiveCellInfo.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigGridManager.h" #include "RimCase.h" +#include "RimCaseCollection.h" +#include "RimCellEdgeResultSlot.h" +#include "RimReservoirCellResultsStorage.h" #include "RimReservoirView.h" -#include "RigCaseData.h" -#include "RigCaseCellResultsData.h" - +#include "RimResultCase.h" #include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" #include "RimStatisticsCase.h" -#include "RimResultCase.h" #include "cafProgressInfo.h" -#include "RigActiveCellInfo.h" -#include "RigActiveCellInfo.h" - -#include "RigGridManager.h" -#include "RimReservoirCellResultsCacher.h" - - -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimWellCollection.h" - CAF_PDM_SOURCE_INIT(RimIdenticalGridCaseGroup, "RimIdenticalGridCaseGroup"); @@ -235,7 +224,7 @@ void RimIdenticalGridCaseGroup::loadMainCaseAndActiveCellInfo() //-------------------------------------------------------------------------------------------------- void RimIdenticalGridCaseGroup::computeUnionOfActiveCells() { - if (m_unionOfMatrixActiveCells->globalActiveCellCount() > 0) + if (m_unionOfMatrixActiveCells->reservoirActiveCellCount() > 0) { return; } @@ -247,8 +236,8 @@ void RimIdenticalGridCaseGroup::computeUnionOfActiveCells() return; } - m_unionOfMatrixActiveCells->setGlobalCellCount(m_mainGrid->cells().size()); - m_unionOfFractureActiveCells->setGlobalCellCount(m_mainGrid->cells().size()); + m_unionOfMatrixActiveCells->setReservoirCellCount(m_mainGrid->cells().size()); + m_unionOfFractureActiveCells->setReservoirCellCount(m_mainGrid->cells().size()); m_unionOfMatrixActiveCells->setGridCount(m_mainGrid->gridCount()); m_unionOfFractureActiveCells->setGridCount(m_mainGrid->gridCount()); @@ -262,25 +251,25 @@ void RimIdenticalGridCaseGroup::computeUnionOfActiveCells() std::vector activeM(grid->cellCount(), 0); std::vector activeF(grid->cellCount(), 0); - for (size_t localGridCellIdx = 0; localGridCellIdx < grid->cellCount(); localGridCellIdx++) + for (size_t gridLocalCellIndex = 0; gridLocalCellIndex < grid->cellCount(); gridLocalCellIndex++) { for (size_t caseIdx = 0; caseIdx < caseCollection->reservoirs.size(); caseIdx++) { - size_t globalCellIdx = grid->globalGridCellIndex(localGridCellIdx); + size_t reservoirCellIndex = grid->reservoirCellIndex(gridLocalCellIndex); - if (activeM[localGridCellIdx] == 0) + if (activeM[gridLocalCellIndex] == 0) { - if (caseCollection->reservoirs[caseIdx]->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->isActive(globalCellIdx)) + if (caseCollection->reservoirs[caseIdx]->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->isActive(reservoirCellIndex)) { - activeM[localGridCellIdx] = 1; + activeM[gridLocalCellIndex] = 1; } } - if (activeF[localGridCellIdx] == 0) + if (activeF[gridLocalCellIndex] == 0) { - if (caseCollection->reservoirs[caseIdx]->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->isActive(globalCellIdx)) + if (caseCollection->reservoirs[caseIdx]->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->isActive(reservoirCellIndex)) { - activeF[localGridCellIdx] = 1; + activeF[gridLocalCellIndex] = 1; } } } @@ -289,19 +278,19 @@ void RimIdenticalGridCaseGroup::computeUnionOfActiveCells() size_t activeMatrixIndex = 0; size_t activeFractureIndex = 0; - for (size_t localGridCellIdx = 0; localGridCellIdx < grid->cellCount(); localGridCellIdx++) + for (size_t gridLocalCellIndex = 0; gridLocalCellIndex < grid->cellCount(); gridLocalCellIndex++) { - size_t globalCellIdx = grid->globalGridCellIndex(localGridCellIdx); + size_t reservoirCellIndex = grid->reservoirCellIndex(gridLocalCellIndex); - if (activeM[localGridCellIdx] != 0) + if (activeM[gridLocalCellIndex] != 0) { - m_unionOfMatrixActiveCells->setCellResultIndex(globalCellIdx, globalActiveMatrixIndex++); + m_unionOfMatrixActiveCells->setCellResultIndex(reservoirCellIndex, globalActiveMatrixIndex++); activeMatrixIndex++; } - if (activeF[localGridCellIdx] != 0) + if (activeF[gridLocalCellIndex] != 0) { - m_unionOfFractureActiveCells->setCellResultIndex(globalCellIdx, globalActiveFractureIndex++); + m_unionOfFractureActiveCells->setCellResultIndex(reservoirCellIndex, globalActiveFractureIndex++); activeFractureIndex++; } } diff --git a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h index e3da03cc8e..6a033e1ede 100644 --- a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h +++ b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -25,7 +27,6 @@ #include "RifReaderInterface.h" -//#include "RimStatisticsCaseCollection.h" class RimCaseCollection; class RimStatisticsCase; diff --git a/ApplicationCode/ProjectDataModel/RimInputCase.cpp b/ApplicationCode/ProjectDataModel/RimInputCase.cpp index e9ab1a607f..3c4b6847f2 100644 --- a/ApplicationCode/ProjectDataModel/RimInputCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimInputCase.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,34 +18,24 @@ // ///////////////////////////////////////////////////////////////////////////////// -//#include "RiaStdInclude.h" - #include "RimInputCase.h" -#include "RimInputPropertyCollection.h" -#include "RimReservoirCellResultsCacher.h" -#include -#include "RimReservoirView.h" +#include "RiaPreferences.h" +#include "RifEclipseInputFileTools.h" #include "RifReaderEclipseInput.h" -#include "RigCaseData.h" +#include "RifReaderInterface.h" +#include "RifReaderMockModel.h" +#include "RifReaderSettings.h" #include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RimDefines.h" +#include "RimInputProperty.h" +#include "RimInputPropertyCollection.h" +#include "RimReservoirCellResultsStorage.h" -#include "RifReaderMockModel.h" -#include "RifEclipseInputFileTools.h" #include "cafProgressInfo.h" -#include "RiaApplication.h" -#include "RiaPreferences.h" - -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" - -#include "RimCellEdgeResultSlot.h" -#include "RimResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimWellCollection.h" +#include CAF_PDM_SOURCE_INIT(RimInputCase, "RimInputReservoir"); //-------------------------------------------------------------------------------------------------- @@ -107,7 +99,7 @@ void RimInputCase::openDataFileSet(const QStringList& fileNames) for (int i = 0; i < fileNames.size(); i++) { - if (RifEclipseInputFileTools::openGridFile(fileNames[i], this->reservoirData(), prefs->readFaultData())) + if (RifEclipseInputFileTools::openGridFile(fileNames[i], this->reservoirData(), prefs->readerSettings->importFaults())) { m_gridFileName = fileNames[i]; @@ -192,7 +184,7 @@ bool RimInputCase::openEclipseGridFile() { RiaPreferences* prefs = RiaApplication::instance()->preferences(); readerInterface = new RifReaderEclipseInput; - readerInterface->readFaultData(prefs->readFaultData()); + readerInterface->setReaderSetting(prefs->readerSettings()); cvf::ref eclipseCase = new RigCaseData; if (!readerInterface->open(m_gridFileName, eclipseCase.p())) diff --git a/ApplicationCode/ProjectDataModel/RimInputProperty.cpp b/ApplicationCode/ProjectDataModel/RimInputProperty.cpp index 95936e5f54..acbd17a801 100644 --- a/ApplicationCode/ProjectDataModel/RimInputProperty.cpp +++ b/ApplicationCode/ProjectDataModel/RimInputProperty.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,13 +18,10 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimInputProperty.h" -#include "cvfAssert.h" - #include "cafPdmUiLineEditor.h" +#include "cvfAssert.h" #include diff --git a/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.cpp b/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.cpp index 5798253f13..0758a0576c 100644 --- a/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,10 +18,11 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimInputPropertyCollection.h" +#include "RimInputProperty.h" + +#include CAF_PDM_SOURCE_INIT(RimInputPropertyCollection, "RimInputPropertyCollection"); diff --git a/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.h b/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.h index 2e865fda76..81828209cb 100644 --- a/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.h +++ b/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -23,7 +25,7 @@ #include "cafPdmField.h" #include "cafPdmObject.h" -#include "RimInputProperty.h" +class RimInputProperty; //================================================================================================== diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp index 3cfd96ca48..72c1312e3f 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.h b/ApplicationCode/ProjectDataModel/RimLegendConfig.h index a8a697601d..6d8704d29a 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp b/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp index 1266629d4e..e7e6fce382 100644 --- a/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp +++ b/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/ProjectDataModel/RimMockModelSettings.h b/ApplicationCode/ProjectDataModel/RimMockModelSettings.h index 64d1beac66..b6bc055bea 100644 --- a/ApplicationCode/ProjectDataModel/RimMockModelSettings.h +++ b/ApplicationCode/ProjectDataModel/RimMockModelSettings.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.cpp b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.cpp new file mode 100644 index 0000000000..7c05ca685b --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.cpp @@ -0,0 +1,42 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RimNoCommonAreaNNC.h" + +CAF_PDM_SOURCE_INIT(RimNoCommonAreaNNC, "NoCommonAreaNNC"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimNoCommonAreaNNC::RimNoCommonAreaNNC() +{ + CAF_PDM_InitObject("RimNoCommonAreaNNC", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&name, "Name", "Name", "", "", ""); + name.setUiReadOnly(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimNoCommonAreaNNC::userDescriptionField() +{ + return &name; +} + diff --git a/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.h b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.h similarity index 55% rename from ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.h rename to ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.h index d098829f66..0707dd66e9 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.h +++ b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,22 +19,23 @@ #pragma once -#include "cvfStructGridScalarDataAccess.h" -#include "RifReaderInterface.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPointer.h" -class RigActiveCellInfo; -class RigGridBase; - -class RigGridScalarDataAccessFactory +//================================================================================================== +/// +/// +//================================================================================================== +class RimNoCommonAreaNNC : public caf::PdmObject { + CAF_PDM_HEADER_INIT; public: - static cvf::ref - createPerGridDataAccessObject(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - size_t scalarSetIndex); -}; + RimNoCommonAreaNNC(); + caf::PdmField name; + caf::PdmFieldHandle* userDescriptionField(); + +}; diff --git a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.cpp b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.cpp new file mode 100644 index 0000000000..2da7c58588 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.cpp @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RimNoCommonAreaNncCollection.h" + +CAF_PDM_SOURCE_INIT(RimNoCommonAreaNncCollection, "RimNoCommonAreaNncCollection"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimNoCommonAreaNncCollection::RimNoCommonAreaNncCollection() +{ + CAF_PDM_InitObject("RimNoCommonAreaNncCollection", "", "", ""); + + CAF_PDM_InitField(&name, "UserDescription", QString("No Common Area Nncs"), "Name", "", "", ""); + name.setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&noCommonAreaNncs, "NoCommonAreaNncs", "NoCommonAreaNncs", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimNoCommonAreaNncCollection::~RimNoCommonAreaNncCollection() +{ + noCommonAreaNncs.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimNoCommonAreaNncCollection::userDescriptionField() +{ + return &name; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimNoCommonAreaNncCollection::updateName() +{ + name = QString("NNCs With No Common Area (%1)").arg(noCommonAreaNncs().size()); +} + diff --git a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.h b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.h new file mode 100644 index 0000000000..deb48e53a4 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.h @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPointer.h" + +class RimNoCommonAreaNNC; + +//================================================================================================== +/// Placeholder class used to create a folder in the tree view. +/// TODO: Remove this class when new tree view is integrated +//================================================================================================== +class RimNoCommonAreaNncCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimNoCommonAreaNncCollection(); + virtual ~RimNoCommonAreaNncCollection(); + + void updateName(); + + virtual caf::PdmFieldHandle* userDescriptionField(); + + caf::PdmField name; + caf::PdmPointersField noCommonAreaNncs; +}; diff --git a/ApplicationCode/ProjectDataModel/RimOilField.cpp b/ApplicationCode/ProjectDataModel/RimOilField.cpp index 8f078071de..f56e5bc456 100644 --- a/ApplicationCode/ProjectDataModel/RimOilField.cpp +++ b/ApplicationCode/ProjectDataModel/RimOilField.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,33 +18,10 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimOilField.h" -#include "cafAppEnum.h" -#include "RimReservoirView.h" - -#include "RimIdenticalGridCaseGroup.h" - -#include "RiaApplication.h" -#include "RigGridManager.h" -#include "RigCaseData.h" -#include "RimResultCase.h" -#include "RimWellPathCollection.h" #include "RimAnalysisModels.h" - -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimWellCollection.h" -#include "RimCaseCollection.h" -#include "RimResultSlot.h" -#include "RimStatisticsCase.h" +#include "RimWellPathCollection.h" CAF_PDM_SOURCE_INIT(RimOilField, "ResInsightOilField"); //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimOilField.h b/ApplicationCode/ProjectDataModel/RimOilField.h index 9b296aad83..0a26e32d40 100644 --- a/ApplicationCode/ProjectDataModel/RimOilField.h +++ b/ApplicationCode/ProjectDataModel/RimOilField.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,13 +20,10 @@ #pragma once -#include "cafPdmDocument.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPointer.h" -class RimCase; -class RigGridManager; -class RimIdenticalGridCaseGroup; -class RigMainGrid; -class RigCaseData; class RimWellPathCollection; class RimAnalysisModels; @@ -40,7 +39,6 @@ class RimOilField : public caf::PdmObject RimOilField(void); virtual ~RimOilField(void); - caf::PdmField analysisModels; - caf::PdmField wellPathCollection; - + caf::PdmField analysisModels; + caf::PdmField wellPathCollection; }; diff --git a/ApplicationCode/ProjectDataModel/RimProject.cpp b/ApplicationCode/ProjectDataModel/RimProject.cpp index 357a18bfdc..3fea5fd02a 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationCode/ProjectDataModel/RimProject.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,38 +18,22 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimProject.h" -#include "cafAppEnum.h" - -#include "RimOilField.h" -#include "RimAnalysisModels.h" - -#include "RimReservoirView.h" -#include "RimScriptCollection.h" -#include "RimIdenticalGridCaseGroup.h" #include "RiaApplication.h" #include "RiaVersionInfo.h" - -#include "RigGridManager.h" #include "RigCaseData.h" -#include "RimResultCase.h" +#include "RimAnalysisModels.h" +#include "RimCase.h" +#include "RimCaseCollection.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RimOilField.h" +#include "RimReservoirView.h" +#include "RimScriptCollection.h" #include "RimWellPathCollection.h" +#include "RimWellPathImport.h" - -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimWellCollection.h" -#include "RimCaseCollection.h" -#include "RimResultSlot.h" -#include "RimStatisticsCase.h" +#include CAF_PDM_SOURCE_INIT(RimProject, "ResInsightProject"); //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimProject.h b/ApplicationCode/ProjectDataModel/RimProject.h index 28c6b5f9fa..214706e7a7 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.h +++ b/ApplicationCode/ProjectDataModel/RimProject.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -19,8 +21,6 @@ #pragma once #include "cafPdmDocument.h" -#include "RimWellPathImport.h" -#include "RimCommandObject.h" class RimOilField; class RimCase; @@ -29,6 +29,8 @@ class RimScriptCollection; class RimIdenticalGridCaseGroup; class RigMainGrid; class RigCaseData; +class RimWellPathImport; +class RimCommandObject; //================================================================================================== /// diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp deleted file mode 100644 index 9b3357a8e1..0000000000 --- a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp +++ /dev/null @@ -1,775 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS -// -// 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 "RiaStdInclude.h" -#include -#include -#include -#include -#include - -#include "RimReservoirCellResultsCacher.h" -#include "RigCaseCellResultsData.h" -#include "RiaApplication.h" -#include "RigMainGrid.h" -#include "RigCell.h" -#include "cafProgressInfo.h" -#include "RimProject.h" -#include "RimCase.h" -#include "RimCaseCollection.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimScriptCollection.h" -#include "RimReservoirView.h" - -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimWellPathCollection.h" -#include "RimOilField.h" -#include "RimAnalysisModels.h" -#include "RimTools.h" - -CAF_PDM_SOURCE_INIT(RimReservoirCellResultsStorage, "ReservoirCellResultStorage"); - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimReservoirCellResultsStorage::RimReservoirCellResultsStorage() - : m_cellResults(NULL), - m_ownerMainGrid(NULL) -{ - CAF_PDM_InitObject("Cacher", "", "", ""); - - CAF_PDM_InitField(&m_resultCacheFileName, "ResultCacheFileName", QString(), "UiDummyname", "", "" ,""); - m_resultCacheFileName.setUiHidden(true); - CAF_PDM_InitFieldNoDefault(&m_resultCacheMetaData, "ResultCacheEntries", "UiDummyname", "", "", ""); - m_resultCacheMetaData.setUiHidden(true); - -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimReservoirCellResultsStorage::~RimReservoirCellResultsStorage() -{ - m_resultCacheMetaData.deleteAllChildObjects(); -} - -//-------------------------------------------------------------------------------------------------- -/// This override populates the metainfo regarding the cell results data in the RigCaseCellResultsData -/// object. This metainfo will then be written to the project file when saving, and thus read on project file open. -/// This method then writes the actual double arrays to the data file in a simple format: -/// MagicNumber, Version, ResultVariables< Array < TimeStep< CellDataArraySize, CellData< Array > > > -/// -//-------------------------------------------------------------------------------------------------- -void RimReservoirCellResultsStorage::setupBeforeSave() -{ - m_resultCacheMetaData.deleteAllChildObjects(); - QString newValidCacheFileName = getValidCacheFileName(); - - // Delete the storage file - - QFileInfo storageFileInfo(newValidCacheFileName); - if (storageFileInfo.exists()) - { - QDir storageDir = storageFileInfo.dir(); - storageDir.remove(storageFileInfo.fileName()); - } - - if (!m_cellResults) return; - - const std::vector& resInfo = m_cellResults->infoForEachResultIndex(); - - bool hasResultsToStore = false; - for (size_t rIdx = 0; rIdx < resInfo.size(); ++rIdx) - { - if (resInfo[rIdx].m_needsToBeStored) - { - hasResultsToStore = true; - break; - } - } - - if(resInfo.size() && hasResultsToStore) - { - QDir::root().mkpath(getCacheDirectoryPath()); - - QFile cacheFile(newValidCacheFileName); - - if (!cacheFile.open(QIODevice::WriteOnly)) - { - qWarning() << "Saving project: Can't open the cache file : " + newValidCacheFileName; - return; - } - - m_resultCacheFileName = newValidCacheFileName; - - QDataStream stream(&cacheFile); - stream.setVersion(QDataStream::Qt_4_6); - stream << (quint32)0xCEECAC4E; // magic number - stream << (quint32)1; // Version number. Increment if needing to extend the format in ways that can not be handled generically by the reader - - caf::ProgressInfo progInfo(resInfo.size(), "Saving generated and imported properties"); - - for (size_t rIdx = 0; rIdx < resInfo.size(); ++rIdx) - { - // If there is no data, we do not store anything for the current result variable - // (Even not the metadata, of cause) - size_t timestepCount = m_cellResults->cellScalarResults(resInfo[rIdx].m_gridScalarResultIndex).size(); - - if (timestepCount && resInfo[rIdx].m_needsToBeStored) - { - progInfo.setProgressDescription(resInfo[rIdx].m_resultName); - - // Create and setup the cache information for this result - RimReservoirCellResultsStorageEntryInfo* cacheEntry = new RimReservoirCellResultsStorageEntryInfo; - m_resultCacheMetaData.push_back(cacheEntry); - - cacheEntry->m_resultType = resInfo[rIdx].m_resultType; - cacheEntry->m_resultName = resInfo[rIdx].m_resultName; - cacheEntry->m_timeStepDates = resInfo[rIdx].m_timeStepDates; - - // Take note of the file position for fast lookup later - cacheEntry->m_filePosition = cacheFile.pos(); - - // Write all the scalar values for each time step to the stream, - // starting with the number of values - for (size_t tsIdx = 0; tsIdx < resInfo[rIdx].m_timeStepDates.size() ; ++tsIdx) - { - const std::vector* data = NULL; - if (tsIdx < timestepCount) - { - data = &(m_cellResults->cellScalarResults(resInfo[rIdx].m_gridScalarResultIndex, tsIdx)); - } - - if (data && data->size()) - { - - stream << (quint64)(data->size()); - for (size_t cIdx = 0; cIdx < data->size(); ++cIdx) - { - stream << (*data)[cIdx]; - } - } - else - { - stream << (quint64)0; - } - } - } - - progInfo.incrementProgress(); - } - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimReservoirCellResultsStorage::getValidCacheFileName() -{ - QString cacheFileName; - if (m_resultCacheFileName().isEmpty()) - { - QString newCacheDirPath = getCacheDirectoryPath(); - QUuid guid = QUuid::createUuid(); - cacheFileName = newCacheDirPath + "/" + guid.toString(); - } - else - { - // Make the path correct related to the possibly new project filename - QString newCacheDirPath = getCacheDirectoryPath(); - QFileInfo oldCacheFile(m_resultCacheFileName()); - - cacheFileName = newCacheDirPath + "/" + oldCacheFile.fileName(); - } - return cacheFileName; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimReservoirCellResultsStorage::getCacheDirectoryPath() -{ - QString cacheDirPath = RimTools::getCacheRootDirectoryPathFromProject(); - cacheDirPath += "_cache"; - return cacheDirPath; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimReservoirCellResultsStorage::setReaderInterface(RifReaderInterface* readerInterface) -{ - m_readerInterface = readerInterface; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RifReaderInterface* RimReservoirCellResultsStorage::readerInterface() -{ - return m_readerInterface.p(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RimReservoirCellResultsStorage::findOrLoadScalarResultForTimeStep(RimDefines::ResultCatType type, const QString& resultName, size_t timeStepIndex) -{ - if (!m_cellResults) return cvf::UNDEFINED_SIZE_T; - - // Special handling for SOIL - if (type == RimDefines::DYNAMIC_NATIVE && resultName.toUpper() == "SOIL") - { - size_t soilScalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName); - - // If SOIL is not found, try to compute and return computed scalar index - // Will return cvf::UNDEFINED_SIZE_T if no SGAS/SWAT is found - if (soilScalarResultIndex == cvf::UNDEFINED_SIZE_T) - { - computeSOILForTimeStep(timeStepIndex); - - soilScalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName); - return soilScalarResultIndex; - } - - // If we have found SOIL and SOIL must be calculated, calculate and return - if (soilScalarResultIndex != cvf::UNDEFINED_SIZE_T && m_cellResults->mustBeCalculated(soilScalarResultIndex)) - { - computeSOILForTimeStep(timeStepIndex); - - return soilScalarResultIndex; - } - } - - size_t scalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName); - if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T; - - if (type == RimDefines::GENERATED) - { - return cvf::UNDEFINED_SIZE_T; - } - - if (m_readerInterface.notNull()) - { - size_t timeStepCount = m_cellResults->infoForEachResultIndex()[scalarResultIndex].m_timeStepDates.size(); - - bool resultLoadingSucess = true; - - if (type == RimDefines::DYNAMIC_NATIVE && timeStepCount > 0) - { - m_cellResults->cellScalarResults(scalarResultIndex).resize(timeStepCount); - - std::vector& values = m_cellResults->cellScalarResults(scalarResultIndex)[timeStepIndex]; - if (values.size() == 0) - { - if (!m_readerInterface->dynamicResult(resultName, RifReaderInterface::MATRIX_RESULTS, timeStepIndex, &values)) - { - resultLoadingSucess = false; - } - } - } - else if (type == RimDefines::STATIC_NATIVE) - { - m_cellResults->cellScalarResults(scalarResultIndex).resize(1); - - std::vector& values = m_cellResults->cellScalarResults(scalarResultIndex)[0]; - if (!m_readerInterface->staticResult(resultName, RifReaderInterface::MATRIX_RESULTS, &values)) - { - resultLoadingSucess = false; - } - } - - if (!resultLoadingSucess) - { - // Error logging - CVF_ASSERT(false); - } - } - - return scalarResultIndex; - -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName) -{ - if (!m_cellResults) return cvf::UNDEFINED_SIZE_T; - - size_t resultGridIndex = m_cellResults->findScalarResultIndex(type, resultName); - if (resultGridIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T; - - // If we have any results on any timestep, assume we have loaded results already - - for (size_t tsIdx = 0; tsIdx < m_cellResults->timeStepCount(resultGridIndex); ++tsIdx) - { - if (m_cellResults->cellScalarResults(resultGridIndex, tsIdx).size()) - { - return resultGridIndex; - } - } - - if (type == RimDefines::GENERATED) - { - return cvf::UNDEFINED_SIZE_T; - } - - if (m_readerInterface.notNull()) - { - // Add one more result to result container - size_t timeStepCount = m_cellResults->infoForEachResultIndex()[resultGridIndex].m_timeStepDates.size(); - - bool resultLoadingSucess = true; - - if (type == RimDefines::DYNAMIC_NATIVE && timeStepCount > 0) - { - m_cellResults->cellScalarResults(resultGridIndex).resize(timeStepCount); - - size_t i; - for (i = 0; i < timeStepCount; i++) - { - std::vector& values = m_cellResults->cellScalarResults(resultGridIndex)[i]; - if (!m_readerInterface->dynamicResult(resultName, RifReaderInterface::MATRIX_RESULTS, i, &values)) - { - resultLoadingSucess = false; - } - } - } - else if (type == RimDefines::STATIC_NATIVE) - { - m_cellResults->cellScalarResults(resultGridIndex).resize(1); - - std::vector& values = m_cellResults->cellScalarResults(resultGridIndex)[0]; - if (!m_readerInterface->staticResult(resultName, RifReaderInterface::MATRIX_RESULTS, &values)) - { - resultLoadingSucess = false; - } - } - - if (!resultLoadingSucess) - { - // Remove last scalar result because loading of result failed - m_cellResults->cellScalarResults(resultGridIndex).clear(); - } - } - - return resultGridIndex; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimReservoirCellResultsStorage::loadOrComputeSOIL() -{ - size_t scalarIndexSOIL = findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); - if (scalarIndexSOIL != cvf::UNDEFINED_SIZE_T) - { - return; - } - - for (size_t timeStepIdx = 0; timeStepIdx < m_cellResults->maxTimeStepCount(); timeStepIdx++) - { - computeSOILForTimeStep(timeStepIdx); - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimReservoirCellResultsStorage::computeSOILForTimeStep(size_t timeStepIndex) -{ - size_t scalarIndexSWAT = findOrLoadScalarResultForTimeStep(RimDefines::DYNAMIC_NATIVE, "SWAT", timeStepIndex); - size_t scalarIndexSGAS = findOrLoadScalarResultForTimeStep(RimDefines::DYNAMIC_NATIVE, "SGAS", timeStepIndex); - - // Early exit if none of SWAT or SGAS is present - if (scalarIndexSWAT == cvf::UNDEFINED_SIZE_T && scalarIndexSGAS == cvf::UNDEFINED_SIZE_T) - { - return; - } - - CVF_ASSERT(m_cellResults); - - size_t soilResultValueCount = 0; - size_t soilTimeStepCount = 0; - - if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T) - { - std::vector& swatForTimeStep = m_cellResults->cellScalarResults(scalarIndexSWAT, timeStepIndex); - if (swatForTimeStep.size() > 0) - { - soilResultValueCount = swatForTimeStep.size(); - soilTimeStepCount = m_cellResults->infoForEachResultIndex()[scalarIndexSWAT].m_timeStepDates.size(); - } - } - - if (scalarIndexSGAS != cvf::UNDEFINED_SIZE_T) - { - std::vector& sgasForTimeStep = m_cellResults->cellScalarResults(scalarIndexSGAS, timeStepIndex); - if (sgasForTimeStep.size() > 0) - { - soilResultValueCount = qMax(soilResultValueCount, sgasForTimeStep.size()); - - size_t sgasTimeStepCount = m_cellResults->infoForEachResultIndex()[scalarIndexSGAS].m_timeStepDates.size(); - soilTimeStepCount = qMax(soilTimeStepCount, sgasTimeStepCount); - } - } - - size_t soilResultGridIndex = findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); - if (soilResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - soilResultGridIndex = m_cellResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL", false); - CVF_ASSERT(soilResultGridIndex != cvf::UNDEFINED_SIZE_T); - - // Set this result to be calculated - m_cellResults->setMustBeCalculated(soilResultGridIndex); - - m_cellResults->cellScalarResults(soilResultGridIndex).resize(soilTimeStepCount); - - for (size_t timeStepIdx = 0; timeStepIdx < soilTimeStepCount; timeStepIdx++) - { - m_cellResults->cellScalarResults(soilResultGridIndex, timeStepIdx).resize(soilResultValueCount); - } - } - - - std::vector* swatForTimeStep = NULL; - std::vector* sgasForTimeStep = NULL; - - if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T) - { - swatForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSWAT, timeStepIndex)); - if (swatForTimeStep->size() == 0) - { - swatForTimeStep = NULL; - } - } - - if (scalarIndexSGAS != cvf::UNDEFINED_SIZE_T) - { - sgasForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSGAS, timeStepIndex)); - if (sgasForTimeStep->size() == 0) - { - sgasForTimeStep = NULL; - } - } - - std::vector& soilForTimeStep = m_cellResults->cellScalarResults(soilResultGridIndex, timeStepIndex); - -#pragma omp parallel for - for (int idx = 0; idx < static_cast(soilResultValueCount); idx++) - { - double soilValue = 1.0; - if (sgasForTimeStep) - { - soilValue -= sgasForTimeStep->at(idx); - } - - if (swatForTimeStep) - { - soilValue -= swatForTimeStep->at(idx); - } - - soilForTimeStep[idx] = soilValue; - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimReservoirCellResultsStorage::computeDepthRelatedResults() -{ - if (!m_cellResults) return; - - size_t depthResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DEPTH"); - size_t dxResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DX"); - size_t dyResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DY"); - size_t dzResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DZ"); - size_t topsResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "TOPS"); - size_t bottomResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "BOTTOM"); - - bool computeDepth = false; - bool computeDx = false; - bool computeDy = false; - bool computeDz = false; - bool computeTops = false; - bool computeBottom = false; - - size_t resultValueCount = m_ownerMainGrid->cells().size(); - - if (depthResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - depthResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DEPTH", false, resultValueCount); - computeDepth = true; - } - - if (dxResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - dxResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DX", false, resultValueCount); - computeDx = true; - } - - if (dyResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - dyResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DY", false, resultValueCount); - computeDy = true; - } - - if (dzResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - dzResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DZ", false, resultValueCount); - computeDz = true; - } - - if (topsResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - topsResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "TOPS", false, resultValueCount); - computeTops = true; - } - - if (bottomResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - bottomResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "BOTTOM", false, resultValueCount); - computeBottom = true; - } - - std::vector< std::vector >& depth = m_cellResults->cellScalarResults(depthResultGridIndex); - std::vector< std::vector >& dx = m_cellResults->cellScalarResults(dxResultGridIndex); - std::vector< std::vector >& dy = m_cellResults->cellScalarResults(dyResultGridIndex); - std::vector< std::vector >& dz = m_cellResults->cellScalarResults(dzResultGridIndex); - std::vector< std::vector >& tops = m_cellResults->cellScalarResults(topsResultGridIndex); - std::vector< std::vector >& bottom = m_cellResults->cellScalarResults(bottomResultGridIndex); - - size_t cellIdx = 0; - for (cellIdx = 0; cellIdx < m_ownerMainGrid->cells().size(); cellIdx++) - { - const RigCell& cell = m_ownerMainGrid->cells()[cellIdx]; - - if (computeDepth) - { - depth[0][cellIdx] = cvf::Math::abs(cell.center().z()); - } - - if (computeDx) - { - cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_I) - cell.faceCenter(cvf::StructGridInterface::POS_I); - dx[0][cellIdx] = cvf::Math::abs(cellWidth.x()); - } - - if (computeDy) - { - cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_J) - cell.faceCenter(cvf::StructGridInterface::POS_J); - dy[0][cellIdx] = cvf::Math::abs(cellWidth.y()); - } - - if (computeDz) - { - cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_K) - cell.faceCenter(cvf::StructGridInterface::POS_K); - dz[0][cellIdx] = cvf::Math::abs(cellWidth.z()); - } - - if (computeTops) - { - tops[0][cellIdx] = cvf::Math::abs(cell.faceCenter(cvf::StructGridInterface::NEG_K).z()); - } - - if (computeBottom) - { - bottom[0][cellIdx] = cvf::Math::abs(cell.faceCenter(cvf::StructGridInterface::POS_K).z()); - } - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(const QString& resultName) -{ - if (!m_cellResults) return cvf::UNDEFINED_SIZE_T; - - size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; - - scalarResultIndex = this->findOrLoadScalarResult(RimDefines::STATIC_NATIVE, resultName); - - if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) - { - scalarResultIndex = this->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, resultName); - } - - if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) - { - scalarResultIndex = m_cellResults->findScalarResultIndex(RimDefines::GENERATED, resultName); - } - - if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) - { - scalarResultIndex = m_cellResults->findScalarResultIndex(RimDefines::INPUT_PROPERTY, resultName); - } - - return scalarResultIndex; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimReservoirCellResultsStorage::setCellResults(RigCaseCellResultsData* cellResults) -{ - m_cellResults = cellResults; - - if (m_cellResults == NULL) - return; - - // Now that we have got the results container, we can finally - // Read data from the internal storage and populate it - - if (m_resultCacheFileName().isEmpty()) - return; - - // Get the name of the cache name relative to the current project file position - QString newValidCacheFileName = getValidCacheFileName(); - - QFile storageFile(newValidCacheFileName); - - // Warn if we thought we were to find some data on the storage file - - if (!storageFile.exists() && m_resultCacheMetaData.size()) - { - qWarning() << "Reading stored results: Missing the storage file : " + newValidCacheFileName; - return; - } - - if (!storageFile.open(QIODevice::ReadOnly)) - { - qWarning() << "Reading stored results: Can't open the file : " + newValidCacheFileName; - return; - } - - QDataStream stream(&storageFile); - stream.setVersion(QDataStream::Qt_4_6); - quint32 magicNumber = 0; - quint32 versionNumber = 0; - stream >> magicNumber; - - if (magicNumber != 0xCEECAC4E) - { - qWarning() << "Reading stored results: The storage file has wrong type "; - return; - } - - stream >> versionNumber; - if (versionNumber > 1 ) - { - qWarning() << "Reading stored results: The storage file has been written by a newer version of ResInsight"; - return; - } - - caf::ProgressInfo progress(m_resultCacheMetaData.size(), "Reading internally stored results"); - // Fill the object with data from the storage - - for (size_t rIdx = 0; rIdx < m_resultCacheMetaData.size(); ++rIdx) - { - RimReservoirCellResultsStorageEntryInfo* resInfo = m_resultCacheMetaData[rIdx]; - size_t resultIndex = m_cellResults->addEmptyScalarResult(resInfo->m_resultType(), resInfo->m_resultName(), true); - - m_cellResults->setTimeStepDates(resultIndex, resInfo->m_timeStepDates()); - - progress.setProgressDescription(resInfo->m_resultName); - - for (size_t tsIdx = 0; tsIdx < resInfo->m_timeStepDates().size(); ++tsIdx) - { - std::vector* data = NULL; - - data = &(m_cellResults->cellScalarResults(rIdx, tsIdx)); - - quint64 cellCount = 0; - stream >> cellCount; - data->resize(cellCount, HUGE_VAL); - - for (size_t cIdx = 0; cIdx < cellCount; ++cIdx) - { - stream >> (*data)[cIdx]; - } - } - - progress.incrementProgress(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimReservoirCellResultsStorage::setMainGrid(RigMainGrid* mainGrid) -{ - m_ownerMainGrid = mainGrid; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RimReservoirCellResultsStorage::storedResultsCount() -{ - return m_resultCacheMetaData.size(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimReservoirCellResultsStorage::createCombinedTransmissibilityResults() -{ - if (!m_cellResults) return; - - m_cellResults->createCombinedTransmissibilityResult(); -} - - -CAF_PDM_SOURCE_INIT(RimReservoirCellResultsStorageEntryInfo, "ResultStorageEntryInfo"); - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimReservoirCellResultsStorageEntryInfo::RimReservoirCellResultsStorageEntryInfo() -{ - CAF_PDM_InitObject("Cache Entry", "", "", ""); - - CAF_PDM_InitField(&m_resultType, "ResultType", caf::AppEnum(RimDefines::REMOVED), "ResultType", "", "" ,""); - CAF_PDM_InitField(&m_resultName, "ResultName", QString(), "ResultName", "", "" ,""); - CAF_PDM_InitFieldNoDefault(&m_timeStepDates, "TimeSteps", "TimeSteps", "", "" ,""); - CAF_PDM_InitField(&m_filePosition, "FilePositionDataStart", qint64(-1), "FilePositionDataStart", "", "" ,""); - -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimReservoirCellResultsStorageEntryInfo::~RimReservoirCellResultsStorageEntryInfo() -{ - -} \ No newline at end of file diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp new file mode 100644 index 0000000000..d533ccb702 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp @@ -0,0 +1,1545 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RimReservoirCellResultsStorage.h" + +#include "RigActiveCellInfo.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigCell.h" +#include "RigMainGrid.h" + +#include "RimCase.h" +#include "RimTools.h" + +#include "cafProgressInfo.h" + +#include "cvfGeometryTools.h" + +#include +#include +#include +#include +#include + +CAF_PDM_SOURCE_INIT(RimReservoirCellResultsStorage, "ReservoirCellResultStorage"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimReservoirCellResultsStorage::RimReservoirCellResultsStorage() + : m_cellResults(NULL), + m_ownerMainGrid(NULL) +{ + CAF_PDM_InitObject("Cacher", "", "", ""); + + CAF_PDM_InitField(&m_resultCacheFileName, "ResultCacheFileName", QString(), "UiDummyname", "", "" ,""); + m_resultCacheFileName.setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_resultCacheMetaData, "ResultCacheEntries", "UiDummyname", "", "", ""); + m_resultCacheMetaData.setUiHidden(true); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimReservoirCellResultsStorage::~RimReservoirCellResultsStorage() +{ + m_resultCacheMetaData.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// This override populates the metainfo regarding the cell results data in the RigCaseCellResultsData +/// object. This metainfo will then be written to the project file when saving, and thus read on project file open. +/// This method then writes the actual double arrays to the data file in a simple format: +/// MagicNumber, Version, ResultVariables< Array < TimeStep< CellDataArraySize, CellData< Array > > > +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::setupBeforeSave() +{ + m_resultCacheMetaData.deleteAllChildObjects(); + QString newValidCacheFileName = getValidCacheFileName(); + + // Delete the storage file + + QFileInfo storageFileInfo(newValidCacheFileName); + if (storageFileInfo.exists()) + { + QDir storageDir = storageFileInfo.dir(); + storageDir.remove(storageFileInfo.fileName()); + } + + if (!m_cellResults) return; + + const std::vector& resInfo = m_cellResults->infoForEachResultIndex(); + + bool hasResultsToStore = false; + for (size_t rIdx = 0; rIdx < resInfo.size(); ++rIdx) + { + if (resInfo[rIdx].m_needsToBeStored) + { + hasResultsToStore = true; + break; + } + } + + if(resInfo.size() && hasResultsToStore) + { + QDir::root().mkpath(getCacheDirectoryPath()); + + QFile cacheFile(newValidCacheFileName); + + if (!cacheFile.open(QIODevice::WriteOnly)) + { + qWarning() << "Saving project: Can't open the cache file : " + newValidCacheFileName; + return; + } + + m_resultCacheFileName = newValidCacheFileName; + + QDataStream stream(&cacheFile); + stream.setVersion(QDataStream::Qt_4_6); + stream << (quint32)0xCEECAC4E; // magic number + stream << (quint32)1; // Version number. Increment if needing to extend the format in ways that can not be handled generically by the reader + + caf::ProgressInfo progInfo(resInfo.size(), "Saving generated and imported properties"); + + for (size_t rIdx = 0; rIdx < resInfo.size(); ++rIdx) + { + // If there is no data, we do not store anything for the current result variable + // (Even not the metadata, of cause) + size_t timestepCount = m_cellResults->cellScalarResults(resInfo[rIdx].m_gridScalarResultIndex).size(); + + if (timestepCount && resInfo[rIdx].m_needsToBeStored) + { + progInfo.setProgressDescription(resInfo[rIdx].m_resultName); + + // Create and setup the cache information for this result + RimReservoirCellResultsStorageEntryInfo* cacheEntry = new RimReservoirCellResultsStorageEntryInfo; + m_resultCacheMetaData.push_back(cacheEntry); + + cacheEntry->m_resultType = resInfo[rIdx].m_resultType; + cacheEntry->m_resultName = resInfo[rIdx].m_resultName; + cacheEntry->m_timeStepDates = resInfo[rIdx].m_timeStepDates; + + // Take note of the file position for fast lookup later + cacheEntry->m_filePosition = cacheFile.pos(); + + // Write all the scalar values for each time step to the stream, + // starting with the number of values + for (size_t tsIdx = 0; tsIdx < resInfo[rIdx].m_timeStepDates.size() ; ++tsIdx) + { + const std::vector* data = NULL; + if (tsIdx < timestepCount) + { + data = &(m_cellResults->cellScalarResults(resInfo[rIdx].m_gridScalarResultIndex, tsIdx)); + } + + if (data && data->size()) + { + + stream << (quint64)(data->size()); + for (size_t cIdx = 0; cIdx < data->size(); ++cIdx) + { + stream << (*data)[cIdx]; + } + } + else + { + stream << (quint64)0; + } + } + } + + progInfo.incrementProgress(); + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimReservoirCellResultsStorage::getValidCacheFileName() +{ + QString cacheFileName; + if (m_resultCacheFileName().isEmpty()) + { + QString newCacheDirPath = getCacheDirectoryPath(); + QUuid guid = QUuid::createUuid(); + cacheFileName = newCacheDirPath + "/" + guid.toString(); + } + else + { + // Make the path correct related to the possibly new project filename + QString newCacheDirPath = getCacheDirectoryPath(); + QFileInfo oldCacheFile(m_resultCacheFileName()); + + cacheFileName = newCacheDirPath + "/" + oldCacheFile.fileName(); + } + return cacheFileName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimReservoirCellResultsStorage::getCacheDirectoryPath() +{ + QString cacheDirPath = RimTools::getCacheRootDirectoryPathFromProject(); + cacheDirPath += "_cache"; + return cacheDirPath; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::setReaderInterface(RifReaderInterface* readerInterface) +{ + m_readerInterface = readerInterface; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifReaderInterface* RimReservoirCellResultsStorage::readerInterface() +{ + return m_readerInterface.p(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(const QString& resultName) +{ + if (!m_cellResults) return cvf::UNDEFINED_SIZE_T; + + size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; + + scalarResultIndex = this->findOrLoadScalarResult(RimDefines::STATIC_NATIVE, resultName); + + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) + { + scalarResultIndex = this->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, resultName); + } + + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) + { + scalarResultIndex = m_cellResults->findScalarResultIndex(RimDefines::GENERATED, resultName); + } + + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) + { + scalarResultIndex = m_cellResults->findScalarResultIndex(RimDefines::INPUT_PROPERTY, resultName); + } + + return scalarResultIndex; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName) +{ + if (!m_cellResults) return cvf::UNDEFINED_SIZE_T; + + size_t scalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName); + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T; + + // Load dependency data sets + + if (type == RimDefines::STATIC_NATIVE) + { + if (resultName == RimDefines::combinedTransmissibilityResultName()) + { + this->findOrLoadScalarResult(type, "TRANX"); + this->findOrLoadScalarResult(type, "TRANY"); + this->findOrLoadScalarResult(type, "TRANZ"); + } + else if (resultName == RimDefines::combinedMultResultName()) + { + this->findOrLoadScalarResult(type, "MULTX"); + this->findOrLoadScalarResult(type, "MULTX-"); + this->findOrLoadScalarResult(type, "MULTY"); + this->findOrLoadScalarResult(type, "MULTY-"); + this->findOrLoadScalarResult(type, "MULTZ"); + this->findOrLoadScalarResult(type, "MULTZ-"); + } + else if (resultName == RimDefines::combinedRiTranResultName()) + { + computeRiTransComponent(RimDefines::riTranXResultName()); + computeRiTransComponent(RimDefines::riTranYResultName()); + computeRiTransComponent(RimDefines::riTranZResultName()); + computeNncCombRiTrans(); + } + else if (resultName == RimDefines::riTranXResultName() + || resultName == RimDefines::riTranYResultName() + || resultName == RimDefines::riTranZResultName()) + { + computeRiTransComponent(resultName); + } + else if (resultName == RimDefines::combinedRiMultResultName()) + { + computeRiMULTComponent(RimDefines::riMultXResultName()); + computeRiMULTComponent(RimDefines::riMultYResultName()); + computeRiMULTComponent(RimDefines::riMultZResultName()); + computeNncCombRiTrans(); + computeNncCombRiMULT(); + } + else if (resultName == RimDefines::riMultXResultName() + || resultName == RimDefines::riMultYResultName() + || resultName == RimDefines::riMultZResultName()) + { + computeRiMULTComponent(resultName); + } + else if (resultName == RimDefines::combinedRiAreaNormTranResultName()) + { + computeRiTRANSbyAreaComponent(RimDefines::riAreaNormTranXResultName()); + computeRiTRANSbyAreaComponent(RimDefines::riAreaNormTranYResultName()); + computeRiTRANSbyAreaComponent(RimDefines::riAreaNormTranZResultName()); + computeNncCombRiTRANSbyArea(); + } + else if (resultName == RimDefines::riAreaNormTranXResultName() + || resultName == RimDefines::riAreaNormTranYResultName() + || resultName == RimDefines::riAreaNormTranZResultName()) + { + computeRiTRANSbyAreaComponent(resultName); + } + } + + + if (isDataPresent(scalarResultIndex)) + { + return scalarResultIndex; + } + + if (resultName == "SOIL") + { + if (m_cellResults->mustBeCalculated(scalarResultIndex)) + { + // Trigger loading of SWAT, SGAS to establish time step count if no data has been loaded from file at this point + findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); + findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); + + m_cellResults->cellScalarResults(scalarResultIndex).resize(m_cellResults->maxTimeStepCount()); + for (size_t timeStepIdx = 0; timeStepIdx < m_cellResults->maxTimeStepCount(); timeStepIdx++) + { + std::vector& values = m_cellResults->cellScalarResults(scalarResultIndex)[timeStepIdx]; + if (values.size() == 0) + { + computeSOILForTimeStep(timeStepIdx); + } + } + + return scalarResultIndex; + } + } + + if (type == RimDefines::GENERATED) + { + return cvf::UNDEFINED_SIZE_T; + } + + if (m_readerInterface.notNull()) + { + // Add one more result to result container + size_t timeStepCount = m_cellResults->infoForEachResultIndex()[scalarResultIndex].m_timeStepDates.size(); + + bool resultLoadingSucess = true; + + if (type == RimDefines::DYNAMIC_NATIVE && timeStepCount > 0) + { + m_cellResults->cellScalarResults(scalarResultIndex).resize(timeStepCount); + + size_t i; + for (i = 0; i < timeStepCount; i++) + { + std::vector& values = m_cellResults->cellScalarResults(scalarResultIndex)[i]; + if (!m_readerInterface->dynamicResult(resultName, RifReaderInterface::MATRIX_RESULTS, i, &values)) + { + resultLoadingSucess = false; + } + } + } + else if (type == RimDefines::STATIC_NATIVE) + { + m_cellResults->cellScalarResults(scalarResultIndex).resize(1); + + std::vector& values = m_cellResults->cellScalarResults(scalarResultIndex)[0]; + if (!m_readerInterface->staticResult(resultName, RifReaderInterface::MATRIX_RESULTS, &values)) + { + resultLoadingSucess = false; + } + } + + if (!resultLoadingSucess) + { + // Remove last scalar result because loading of result failed + m_cellResults->cellScalarResults(scalarResultIndex).clear(); + } + } + + return scalarResultIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// This method is intended to be used for multicase cross statistical calculations, when +/// we need process one timestep at a time, freeing memory as we go. +//-------------------------------------------------------------------------------------------------- +size_t RimReservoirCellResultsStorage::findOrLoadScalarResultForTimeStep(RimDefines::ResultCatType type, const QString& resultName, size_t timeStepIndex) +{ + if (!m_cellResults) return cvf::UNDEFINED_SIZE_T; + + // Special handling for SOIL + if (type == RimDefines::DYNAMIC_NATIVE && resultName.toUpper() == "SOIL") + { + size_t soilScalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName); + + if (m_cellResults->mustBeCalculated(soilScalarResultIndex)) + { + std::vector& values = m_cellResults->cellScalarResults(soilScalarResultIndex)[timeStepIndex]; + if (values.size() == 0) + { + computeSOILForTimeStep(timeStepIndex); + } + + return soilScalarResultIndex; + } + } + + size_t scalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName); + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T; + + if (type == RimDefines::GENERATED) + { + return cvf::UNDEFINED_SIZE_T; + } + + if (m_readerInterface.notNull()) + { + size_t timeStepCount = m_cellResults->infoForEachResultIndex()[scalarResultIndex].m_timeStepDates.size(); + + bool resultLoadingSucess = true; + + if (type == RimDefines::DYNAMIC_NATIVE && timeStepCount > 0) + { + m_cellResults->cellScalarResults(scalarResultIndex).resize(timeStepCount); + + std::vector& values = m_cellResults->cellScalarResults(scalarResultIndex)[timeStepIndex]; + if (values.size() == 0) + { + if (!m_readerInterface->dynamicResult(resultName, RifReaderInterface::MATRIX_RESULTS, timeStepIndex, &values)) + { + resultLoadingSucess = false; + } + } + } + else if (type == RimDefines::STATIC_NATIVE) + { + m_cellResults->cellScalarResults(scalarResultIndex).resize(1); + + std::vector& values = m_cellResults->cellScalarResults(scalarResultIndex)[0]; + if (!m_readerInterface->staticResult(resultName, RifReaderInterface::MATRIX_RESULTS, &values)) + { + resultLoadingSucess = false; + } + } + + if (!resultLoadingSucess) + { + // Error logging + CVF_ASSERT(false); + } + } + + return scalarResultIndex; + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::computeSOILForTimeStep(size_t timeStepIndex) +{ + size_t scalarIndexSWAT = findOrLoadScalarResultForTimeStep(RimDefines::DYNAMIC_NATIVE, "SWAT", timeStepIndex); + size_t scalarIndexSGAS = findOrLoadScalarResultForTimeStep(RimDefines::DYNAMIC_NATIVE, "SGAS", timeStepIndex); + + // Early exit if none of SWAT or SGAS is present + if (scalarIndexSWAT == cvf::UNDEFINED_SIZE_T && scalarIndexSGAS == cvf::UNDEFINED_SIZE_T) + { + return; + } + + CVF_ASSERT(m_cellResults); + + size_t soilResultValueCount = 0; + size_t soilTimeStepCount = 0; + + if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T) + { + std::vector& swatForTimeStep = m_cellResults->cellScalarResults(scalarIndexSWAT, timeStepIndex); + if (swatForTimeStep.size() > 0) + { + soilResultValueCount = swatForTimeStep.size(); + soilTimeStepCount = m_cellResults->infoForEachResultIndex()[scalarIndexSWAT].m_timeStepDates.size(); + } + } + + if (scalarIndexSGAS != cvf::UNDEFINED_SIZE_T) + { + std::vector& sgasForTimeStep = m_cellResults->cellScalarResults(scalarIndexSGAS, timeStepIndex); + if (sgasForTimeStep.size() > 0) + { + soilResultValueCount = qMax(soilResultValueCount, sgasForTimeStep.size()); + + size_t sgasTimeStepCount = m_cellResults->infoForEachResultIndex()[scalarIndexSGAS].m_timeStepDates.size(); + soilTimeStepCount = qMax(soilTimeStepCount, sgasTimeStepCount); + } + } + + // Make sure memory is allocated for the new SOIL results + + size_t soilResultScalarIndex = m_cellResults->findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "SOIL"); + m_cellResults->cellScalarResults(soilResultScalarIndex).resize(soilTimeStepCount); + + if (m_cellResults->cellScalarResults(soilResultScalarIndex, timeStepIndex).size() > 0) + { + // Data is computed and allocated, nothing more to do + return; + } + + m_cellResults->cellScalarResults(soilResultScalarIndex, timeStepIndex).resize(soilResultValueCount); + + std::vector* swatForTimeStep = NULL; + std::vector* sgasForTimeStep = NULL; + + if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T) + { + swatForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSWAT, timeStepIndex)); + if (swatForTimeStep->size() == 0) + { + swatForTimeStep = NULL; + } + } + + if (scalarIndexSGAS != cvf::UNDEFINED_SIZE_T) + { + sgasForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSGAS, timeStepIndex)); + if (sgasForTimeStep->size() == 0) + { + sgasForTimeStep = NULL; + } + } + + std::vector& soilForTimeStep = m_cellResults->cellScalarResults(soilResultScalarIndex, timeStepIndex); + +#pragma omp parallel for + for (int idx = 0; idx < static_cast(soilResultValueCount); idx++) + { + double soilValue = 1.0; + if (sgasForTimeStep) + { + soilValue -= sgasForTimeStep->at(idx); + } + + if (swatForTimeStep) + { + soilValue -= swatForTimeStep->at(idx); + } + + soilForTimeStep[idx] = soilValue; + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::computeDepthRelatedResults() +{ + if (!m_cellResults) return; + + size_t depthResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DEPTH"); + size_t dxResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DX"); + size_t dyResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DY"); + size_t dzResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DZ"); + size_t topsResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "TOPS"); + size_t bottomResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "BOTTOM"); + + bool computeDepth = false; + bool computeDx = false; + bool computeDy = false; + bool computeDz = false; + bool computeTops = false; + bool computeBottom = false; + + size_t resultValueCount = m_ownerMainGrid->cells().size(); + + if (depthResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + depthResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DEPTH", false, resultValueCount); + computeDepth = true; + } + + if (dxResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + dxResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DX", false, resultValueCount); + computeDx = true; + } + + if (dyResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + dyResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DY", false, resultValueCount); + computeDy = true; + } + + if (dzResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + dzResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DZ", false, resultValueCount); + computeDz = true; + } + + if (topsResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + topsResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "TOPS", false, resultValueCount); + computeTops = true; + } + + if (bottomResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + bottomResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "BOTTOM", false, resultValueCount); + computeBottom = true; + } + + std::vector< std::vector >& depth = m_cellResults->cellScalarResults(depthResultGridIndex); + std::vector< std::vector >& dx = m_cellResults->cellScalarResults(dxResultGridIndex); + std::vector< std::vector >& dy = m_cellResults->cellScalarResults(dyResultGridIndex); + std::vector< std::vector >& dz = m_cellResults->cellScalarResults(dzResultGridIndex); + std::vector< std::vector >& tops = m_cellResults->cellScalarResults(topsResultGridIndex); + std::vector< std::vector >& bottom = m_cellResults->cellScalarResults(bottomResultGridIndex); + + size_t cellIdx = 0; + for (cellIdx = 0; cellIdx < m_ownerMainGrid->cells().size(); cellIdx++) + { + const RigCell& cell = m_ownerMainGrid->cells()[cellIdx]; + + if (computeDepth) + { + depth[0][cellIdx] = cvf::Math::abs(cell.center().z()); + } + + if (computeDx) + { + cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_I) - cell.faceCenter(cvf::StructGridInterface::POS_I); + dx[0][cellIdx] = cvf::Math::abs(cellWidth.x()); + } + + if (computeDy) + { + cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_J) - cell.faceCenter(cvf::StructGridInterface::POS_J); + dy[0][cellIdx] = cvf::Math::abs(cellWidth.y()); + } + + if (computeDz) + { + cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_K) - cell.faceCenter(cvf::StructGridInterface::POS_K); + dz[0][cellIdx] = cvf::Math::abs(cellWidth.z()); + } + + if (computeTops) + { + tops[0][cellIdx] = cvf::Math::abs(cell.faceCenter(cvf::StructGridInterface::NEG_K).z()); + } + + if (computeBottom) + { + bottom[0][cellIdx] = cvf::Math::abs(cell.faceCenter(cvf::StructGridInterface::POS_K).z()); + } + } +} + +namespace RigTransmissibilityCalcTools +{ + void calculateConnectionGeometry(const RigCell& c1, const RigCell& c2, const std::vector& nodes, + cvf::StructGridInterface::FaceType faceId, cvf::Vec3d* faceAreaVec) + { + CVF_TIGHT_ASSERT(faceAreaVec); + + *faceAreaVec = cvf::Vec3d::ZERO; + + std::vector polygon; + std::vector intersections; + caf::SizeTArray4 face1; + caf::SizeTArray4 face2; + c1.faceIndices(faceId, &face1); + c2.faceIndices(cvf::StructGridInterface::oppositeFace(faceId), &face2); + + bool foundOverlap = cvf::GeometryTools::calculateOverlapPolygonOfTwoQuads( + &polygon, + &intersections, + (cvf::EdgeIntersectStorage*)NULL, + cvf::wrapArrayConst(&nodes), + face1.data(), + face2.data(), + 1e-6); + + + if (foundOverlap) + { + std::vector realPolygon; + + for (size_t pIdx = 0; pIdx < polygon.size(); ++pIdx) + { + if (polygon[pIdx] < nodes.size()) + realPolygon.push_back(nodes[polygon[pIdx]]); + else + realPolygon.push_back(intersections[polygon[pIdx] - nodes.size()]); + } + + // Polygon area vector + + *faceAreaVec = cvf::GeometryTools::polygonAreaNormal3D(realPolygon); + + } + + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + double halfCellTransmissibility(double perm, double ntg, const cvf::Vec3d& centerToFace, const cvf::Vec3d& faceAreaVec) + { + return perm*ntg*(faceAreaVec*centerToFace) / (centerToFace*centerToFace); + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + double newtran(double cdarchy, double mult, double halfCellTrans, double neighborHalfCellTrans) + { + if (cvf::Math::abs(halfCellTrans) < 1e-15 || cvf::Math::abs(neighborHalfCellTrans) < 1e-15) + { + return 0.0; + } + + double result = cdarchy * mult / ((1 / halfCellTrans) + (1 / neighborHalfCellTrans)); + CVF_TIGHT_ASSERT(result == result); + return result; + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + typedef size_t(*ResultIndexFunction)(const RigActiveCellInfo* activeCellinfo, size_t reservoirCellIndex); + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + + size_t directReservoirCellIndex(const RigActiveCellInfo* activeCellinfo, size_t reservoirCellIndex) + { + return reservoirCellIndex; + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + + size_t reservoirActiveCellIndex(const RigActiveCellInfo* activeCellinfo, size_t reservoirCellIndex) + { + return activeCellinfo->cellResultIndex(reservoirCellIndex); + } +} + +using namespace RigTransmissibilityCalcTools; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::computeRiTransComponent(const QString& riTransComponentResultName) +{ + if (!m_cellResults) return; + + // Set up which component to compute + + cvf::StructGridInterface::FaceType faceId; + QString permCompName; + + if (riTransComponentResultName == RimDefines::riTranXResultName()) + { + permCompName = "PERMX"; + faceId = cvf::StructGridInterface::POS_I; + } + else if (riTransComponentResultName == RimDefines::riTranYResultName()) + { + permCompName = "PERMY"; + faceId = cvf::StructGridInterface::POS_J; + } + else if (riTransComponentResultName == RimDefines::riTranZResultName()) + { + permCompName = "PERMZ"; + faceId = cvf::StructGridInterface::POS_K; + } + else + { + CVF_ASSERT(false); + } + + double cdarchy = darchysValue(); + + // Get the needed result indices we depend on + + size_t permResultIdx = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, permCompName); + size_t ntgResultIdx = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "NTG"); + + // Get the result index of the output + + size_t riTransResultIdx = m_cellResults->findScalarResultIndex(RimDefines::STATIC_NATIVE, riTransComponentResultName); + CVF_ASSERT(riTransResultIdx != cvf::UNDEFINED_SIZE_T); + + // Get the result count, to handle that one of them might be globally defined + + size_t permxResultValueCount = m_cellResults->cellScalarResults(permResultIdx)[0].size(); + size_t ntgResultValueCount = m_cellResults->cellScalarResults(ntgResultIdx)[0].size(); + + size_t resultValueCount = CVF_MIN(permxResultValueCount, ntgResultValueCount); + + // Get all the actual result values + + std::vector & permResults = m_cellResults->cellScalarResults(permResultIdx)[0]; + std::vector & ntgResults = m_cellResults->cellScalarResults(ntgResultIdx)[0]; + std::vector & riTransResults = m_cellResults->cellScalarResults(riTransResultIdx)[0]; + + // Set up output container to correct number of results + + riTransResults.resize(resultValueCount); + + // Prepare how to index the result values: + + bool isPermUsingResIdx = m_cellResults->isUsingGlobalActiveIndex(permResultIdx); + bool isNtgUsingResIdx = m_cellResults->isUsingGlobalActiveIndex(ntgResultIdx); + bool isTransUsingResIdx = m_cellResults->isUsingGlobalActiveIndex(riTransResultIdx); + + // Set up result index function pointers + + ResultIndexFunction riTranIdxFunc = isTransUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; + ResultIndexFunction permIdxFunc = isPermUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; + ResultIndexFunction ntgIdxFunc = isNtgUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; + + + const RigActiveCellInfo* activeCellInfo = m_cellResults->activeCellInfo(); + const std::vector& nodes = m_ownerMainGrid->nodes(); + bool isFaceNormalsOutwards = m_ownerMainGrid->isFaceNormalsOutwards(); + + for (size_t nativeResvCellIndex = 0; nativeResvCellIndex < m_ownerMainGrid->cells().size(); nativeResvCellIndex++) + { + // Do nothing if we are only dealing with active cells, and this cell is not active: + size_t tranResIdx = (*riTranIdxFunc)(activeCellInfo, nativeResvCellIndex); + + if (tranResIdx == cvf::UNDEFINED_SIZE_T) continue; + + const RigCell& nativeCell = m_ownerMainGrid->cells()[nativeResvCellIndex]; + RigGridBase* grid = nativeCell.hostGrid(); + + size_t gridLocalNativeCellIndex = nativeCell.gridLocalCellIndex(); + + size_t i, j, k, gridLocalNeighborCellIdx; + + grid->ijkFromCellIndex(gridLocalNativeCellIndex, &i, &j, &k); + + if (grid->cellIJKNeighbor(i, j, k, faceId, &gridLocalNeighborCellIdx)) + { + size_t neighborResvCellIdx = grid->reservoirCellIndex(gridLocalNeighborCellIdx); + const RigCell& neighborCell = m_ownerMainGrid->cells()[neighborResvCellIdx]; + + // Do nothing if neighbor cell has no results + size_t neighborCellPermResIdx = (*permIdxFunc)(activeCellInfo, neighborResvCellIdx); + if (neighborCellPermResIdx == cvf::UNDEFINED_SIZE_T) continue; + + // Connection geometry + + const RigFault* fault = grid->mainGrid()->findFaultFromCellIndexAndCellFace(nativeResvCellIndex, faceId); + bool isOnFault = fault; + + + cvf::Vec3d faceAreaVec; + cvf::Vec3d faceCenter; + + if (isOnFault) + { + calculateConnectionGeometry(nativeCell, neighborCell, nodes, faceId, &faceAreaVec); + } + else + { + + faceAreaVec = nativeCell.faceNormalWithAreaLenght(faceId); + } + + if (!isFaceNormalsOutwards) faceAreaVec = -faceAreaVec; + + double halfCellTrans = 0; + double neighborHalfCellTrans = 0; + + // Native cell half cell transm + { + cvf::Vec3d centerToFace = nativeCell.faceCenter(faceId) - nativeCell.center(); + + size_t permResIdx = (*permIdxFunc)(activeCellInfo, nativeResvCellIndex); + double perm = permResults[permResIdx]; + + double ntg = 1.0; + if (faceId != cvf::StructGridInterface::POS_K) + { + size_t ntgResIdx = (*ntgIdxFunc)(activeCellInfo, nativeResvCellIndex); + ntg = ntgResults[ntgResIdx]; + } + + halfCellTrans = halfCellTransmissibility(perm, ntg, centerToFace, faceAreaVec); + } + + // Neighbor cell half cell transm + { + cvf::Vec3d centerToFace = neighborCell.faceCenter(cvf::StructGridInterface::oppositeFace(faceId)) - neighborCell.center(); + + double perm = permResults[neighborCellPermResIdx]; + + double ntg = 1.0; + if (faceId != cvf::StructGridInterface::POS_K) + { + size_t ntgResIdx = (*ntgIdxFunc)(activeCellInfo, neighborResvCellIdx); + ntg = ntgResults[ntgResIdx]; + } + + neighborHalfCellTrans = halfCellTransmissibility(perm, ntg, centerToFace, -faceAreaVec); + } + + riTransResults[tranResIdx] = newtran(cdarchy, 1.0, halfCellTrans, neighborHalfCellTrans); + } + + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::computeNncCombRiTrans() +{ + if (!m_cellResults) return; + + size_t riCombTransScalarResultIndex = m_cellResults->findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::combinedRiTranResultName()); + if (m_ownerMainGrid->nncData()->connectionScalarResult(riCombTransScalarResultIndex)) return; + + double cdarchy = darchysValue(); + + // Get the needed result indices we depend on + + size_t permXResultIdx = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "PERMX"); + size_t permYResultIdx = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "PERMY"); + size_t permZResultIdx = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "PERMZ"); + + size_t ntgResultIdx = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "NTG"); + + // Get the result count, to handle that one of them might be globally defined + + size_t permxResultValueCount = m_cellResults->cellScalarResults(permXResultIdx)[0].size(); + size_t ntgResultValueCount = m_cellResults->cellScalarResults(ntgResultIdx)[0].size(); + + size_t resultValueCount = CVF_MIN(permxResultValueCount, ntgResultValueCount); + + // Get all the actual result values + + std::vector & permXResults = m_cellResults->cellScalarResults(permXResultIdx)[0]; + std::vector & permYResults = m_cellResults->cellScalarResults(permYResultIdx)[0]; + std::vector & permZResults = m_cellResults->cellScalarResults(permZResultIdx)[0]; + std::vector & ntgResults = m_cellResults->cellScalarResults(ntgResultIdx)[0]; + std::vector & riCombTransResults = m_ownerMainGrid->nncData()->makeConnectionScalarResult(riCombTransScalarResultIndex); + + + // Prepare how to index the result values: + + bool isPermXUsingResIdx = m_cellResults->isUsingGlobalActiveIndex(permXResultIdx); + bool isPermYUsingResIdx = m_cellResults->isUsingGlobalActiveIndex(permYResultIdx); + bool isPermZUsingResIdx = m_cellResults->isUsingGlobalActiveIndex(permZResultIdx); + bool isNtgUsingResIdx = m_cellResults->isUsingGlobalActiveIndex(ntgResultIdx); + + + // Set up result index function pointers + + ResultIndexFunction permXIdxFunc = isPermXUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; + ResultIndexFunction permYIdxFunc = isPermYUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; + ResultIndexFunction permZIdxFunc = isPermZUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; + ResultIndexFunction ntgIdxFunc = isNtgUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; + + + const RigActiveCellInfo* activeCellInfo = m_cellResults->activeCellInfo(); + const std::vector& nodes = m_ownerMainGrid->nodes(); + bool isFaceNormalsOutwards = m_ownerMainGrid->isFaceNormalsOutwards(); + + // NNC calculation + std::vector& nncConnections = m_ownerMainGrid->nncData()->connections(); + for (size_t connIdx = 0; connIdx < nncConnections.size(); connIdx++) + { + size_t nativeResvCellIndex = nncConnections[connIdx].m_c1GlobIdx; + size_t neighborResvCellIdx = nncConnections[connIdx].m_c2GlobIdx; + cvf::StructGridInterface::FaceType faceId = nncConnections[connIdx].m_c1Face; + + ResultIndexFunction permIdxFunc = NULL; + std::vector * permResults; + + switch (faceId) + { + case cvf::StructGridInterface::POS_I: + case cvf::StructGridInterface::NEG_I: + permIdxFunc = permXIdxFunc; + permResults = &permXResults; + break; + case cvf::StructGridInterface::POS_J: + case cvf::StructGridInterface::NEG_J: + permIdxFunc = permYIdxFunc; + permResults = &permYResults; + break; + case cvf::StructGridInterface::POS_K: + case cvf::StructGridInterface::NEG_K: + permIdxFunc = permZIdxFunc; + permResults = &permZResults; + break; + } + + if (!permIdxFunc) continue; + + // Do nothing if we are only dealing with active cells, and this cell is not active: + size_t nativeCellPermResIdx = (*permIdxFunc)(activeCellInfo, nativeResvCellIndex); + if (nativeCellPermResIdx == cvf::UNDEFINED_SIZE_T) continue; + + // Do nothing if neighbor cell has no results + size_t neighborCellPermResIdx = (*permIdxFunc)(activeCellInfo, neighborResvCellIdx); + if (neighborCellPermResIdx == cvf::UNDEFINED_SIZE_T) continue; + + + const RigCell& nativeCell = m_ownerMainGrid->cells()[nativeResvCellIndex]; + const RigCell& neighborCell = m_ownerMainGrid->cells()[neighborResvCellIdx]; + + + // Connection geometry + + cvf::Vec3d faceAreaVec = cvf::Vec3d::ZERO;; + cvf::Vec3d faceCenter = cvf::Vec3d::ZERO;; + + // Polygon center + const std::vector& realPolygon = nncConnections[connIdx].m_polygon; + for (size_t pIdx = 0; pIdx < realPolygon.size(); ++pIdx) + { + faceCenter += realPolygon[pIdx]; + } + + faceCenter *= 1.0 / realPolygon.size(); + + // Polygon area vector + + faceAreaVec = cvf::GeometryTools::polygonAreaNormal3D(realPolygon); + + if (!isFaceNormalsOutwards) faceAreaVec = -faceAreaVec; + + double halfCellTrans = 0; + double neighborHalfCellTrans = 0; + + // Native cell half cell transm + { + cvf::Vec3d centerToFace = nativeCell.faceCenter(faceId) - nativeCell.center(); + + double perm = (*permResults)[nativeCellPermResIdx]; + + double ntg = 1.0; + if (faceId != cvf::StructGridInterface::POS_K) + { + size_t ntgResIdx = (*ntgIdxFunc)(activeCellInfo, nativeResvCellIndex); + ntg = ntgResults[ntgResIdx]; + } + + halfCellTrans = halfCellTransmissibility(perm, ntg, centerToFace, faceAreaVec); + } + + // Neighbor cell half cell transm + { + cvf::Vec3d centerToFace = neighborCell.faceCenter(cvf::StructGridInterface::oppositeFace(faceId)) - neighborCell.center(); + + double perm = (*permResults)[neighborCellPermResIdx]; + + double ntg = 1.0; + if (faceId != cvf::StructGridInterface::POS_K) + { + size_t ntgResIdx = (*ntgIdxFunc)(activeCellInfo, neighborResvCellIdx); + ntg = ntgResults[ntgResIdx]; + } + + neighborHalfCellTrans = halfCellTransmissibility(perm, ntg, centerToFace, -faceAreaVec); + } + + double newtranTemp = newtran(cdarchy, 1.0, halfCellTrans, neighborHalfCellTrans); + riCombTransResults[connIdx] = newtranTemp; + } + +} + + +double riMult(double transResults, double riTransResults) +{ + if (transResults == HUGE_VAL || riTransResults == HUGE_VAL) return HUGE_VAL; + + // To make 0.0 values give 1.0 in mult value + if (cvf::Math::abs (riTransResults) < 1e-12) + { + if (cvf::Math::abs (transResults) < 1e-12) + { + return 1.0; + } + + return HUGE_VAL; + } + + + double result = transResults / riTransResults; + + return result; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::computeRiMULTComponent(const QString& riMultCompName) +{ + if (!m_cellResults) return; + + // Set up which component to compute + + QString riTransCompName; + QString transCompName; + + if (riMultCompName == RimDefines::riMultXResultName()) + { + riTransCompName = RimDefines::riTranXResultName(); + transCompName = "TRANX"; + } + else if (riMultCompName == RimDefines::riMultYResultName()) + { + riTransCompName = RimDefines::riTranYResultName(); + transCompName = "TRANY"; + } + else if (riMultCompName == RimDefines::riMultZResultName()) + { + riTransCompName = RimDefines::riTranZResultName(); + transCompName = "TRANZ"; + } + else + { + CVF_ASSERT(false); + } + + // Get the needed result indices we depend on + + size_t transResultIdx = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, transCompName); + size_t riTransResultIdx = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, riTransCompName); + + // Get the result index of the output + + size_t riMultResultIdx = m_cellResults->findScalarResultIndex(RimDefines::STATIC_NATIVE, riMultCompName); + CVF_ASSERT(riMultResultIdx != cvf::UNDEFINED_SIZE_T); + + // Get the result count, to handle that one of them might be globally defined + + CVF_ASSERT(m_cellResults->cellScalarResults(riTransResultIdx)[0].size() == m_cellResults->cellScalarResults(transResultIdx)[0].size()); + + size_t resultValueCount = m_cellResults->cellScalarResults(transResultIdx)[0].size(); + + // Get all the actual result values + + std::vector & riTransResults = m_cellResults->cellScalarResults(riTransResultIdx)[0]; + std::vector & transResults = m_cellResults->cellScalarResults(transResultIdx)[0]; + + std::vector & riMultResults = m_cellResults->cellScalarResults(riMultResultIdx)[0]; + + // Set up output container to correct number of results + + riMultResults.resize(resultValueCount); + + const RigActiveCellInfo* activeCellInfo = m_cellResults->activeCellInfo(); + + for (size_t vIdx = 0; vIdx < transResults.size(); ++vIdx) + { + riMultResults[vIdx] = riMult(transResults[vIdx], riTransResults[vIdx]); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::computeNncCombRiMULT() +{ + if (!m_cellResults) return; + + size_t riCombMultScalarResultIndex = m_cellResults->findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::combinedRiMultResultName()); + size_t riCombTransScalarResultIndex = m_cellResults->findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::combinedRiTranResultName()); + size_t combTransScalarResultIndex = m_cellResults->findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::combinedTransmissibilityResultName()); + + if (m_ownerMainGrid->nncData()->connectionScalarResult(riCombMultScalarResultIndex)) return; + + std::vector & riMultResults = m_ownerMainGrid->nncData()->makeConnectionScalarResult(riCombMultScalarResultIndex); + const std::vector * riTransResults = m_ownerMainGrid->nncData()->connectionScalarResult(riCombTransScalarResultIndex); + const std::vector * transResults = m_ownerMainGrid->nncData()->connectionScalarResult(combTransScalarResultIndex); + + for (size_t nncConIdx = 0; nncConIdx < riMultResults.size(); ++nncConIdx) + { + riMultResults[nncConIdx] = riMult((*transResults)[nncConIdx], (*riTransResults)[nncConIdx]); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::computeRiTRANSbyAreaComponent(const QString& riTransByAreaCompResultName) +{ + if (!m_cellResults) return; + + // Set up which component to compute + + cvf::StructGridInterface::FaceType faceId; + QString transCompName; + + if (riTransByAreaCompResultName == RimDefines::riAreaNormTranXResultName()) + { + transCompName = "TRANX"; + faceId = cvf::StructGridInterface::POS_I; + } + else if (riTransByAreaCompResultName == RimDefines::riAreaNormTranYResultName()) + { + transCompName = "TRANY"; + faceId = cvf::StructGridInterface::POS_J; + } + else if (riTransByAreaCompResultName == RimDefines::riAreaNormTranZResultName()) + { + transCompName = "TRANZ"; + faceId = cvf::StructGridInterface::POS_K; + } + else + { + CVF_ASSERT(false); + } + + // Get the needed result indices we depend on + + size_t tranCompScResIdx = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, transCompName); + + // Get the result index of the output + + size_t riTranByAreaScResIdx = m_cellResults->findScalarResultIndex(RimDefines::STATIC_NATIVE, riTransByAreaCompResultName); + CVF_ASSERT(riTranByAreaScResIdx != cvf::UNDEFINED_SIZE_T); + + // Get the result count, to handle that one of them might be globally defined + + size_t resultValueCount = m_cellResults->cellScalarResults(tranCompScResIdx)[0].size(); + + // Get all the actual result values + + std::vector & transResults = m_cellResults->cellScalarResults(tranCompScResIdx)[0]; + std::vector & riTransByAreaResults = m_cellResults->cellScalarResults(riTranByAreaScResIdx)[0]; + + // Set up output container to correct number of results + + riTransByAreaResults.resize(resultValueCount); + + // Prepare how to index the result values: + + bool isUsingResIdx = m_cellResults->isUsingGlobalActiveIndex(tranCompScResIdx); + + // Set up result index function pointers + + ResultIndexFunction resValIdxFunc = isUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; + + const RigActiveCellInfo* activeCellInfo = m_cellResults->activeCellInfo(); + const std::vector& nodes = m_ownerMainGrid->nodes(); + bool isFaceNormalsOutwards = m_ownerMainGrid->isFaceNormalsOutwards(); + + for (size_t nativeResvCellIndex = 0; nativeResvCellIndex < m_ownerMainGrid->cells().size(); nativeResvCellIndex++) + { + // Do nothing if we are only dealing with active cells, and this cell is not active: + size_t nativeCellResValIdx = (*resValIdxFunc)(activeCellInfo, nativeResvCellIndex); + + if (nativeCellResValIdx == cvf::UNDEFINED_SIZE_T) continue; + + const RigCell& nativeCell = m_ownerMainGrid->cells()[nativeResvCellIndex]; + RigGridBase* grid = nativeCell.hostGrid(); + + size_t gridLocalNativeCellIndex = nativeCell.gridLocalCellIndex(); + + size_t i, j, k, gridLocalNeighborCellIdx; + + grid->ijkFromCellIndex(gridLocalNativeCellIndex, &i, &j, &k); + + if (grid->cellIJKNeighbor(i, j, k, faceId, &gridLocalNeighborCellIdx)) + { + size_t neighborResvCellIdx = grid->reservoirCellIndex(gridLocalNeighborCellIdx); + const RigCell& neighborCell = m_ownerMainGrid->cells()[neighborResvCellIdx]; + + // Connection geometry + + const RigFault* fault = grid->mainGrid()->findFaultFromCellIndexAndCellFace(nativeResvCellIndex, faceId); + bool isOnFault = fault; + + cvf::Vec3d faceAreaVec; + + if (isOnFault) + { + calculateConnectionGeometry(nativeCell, neighborCell, nodes, faceId, &faceAreaVec); + } + else + { + faceAreaVec = nativeCell.faceNormalWithAreaLenght(faceId); + } + + double areaOfOverlap = faceAreaVec.length(); + double transCompValue = transResults[nativeCellResValIdx]; + + riTransByAreaResults[nativeCellResValIdx] = transCompValue / areaOfOverlap; + } + + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::computeNncCombRiTRANSbyArea() +{ + if (!m_cellResults) return; + + size_t riCombTransByAreaScResIdx = m_cellResults->findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::combinedRiAreaNormTranResultName()); + size_t combTransScalarResultIndex = m_cellResults->findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::combinedTransmissibilityResultName()); + + if (m_ownerMainGrid->nncData()->connectionScalarResult(riCombTransByAreaScResIdx)) return; + + std::vector & riAreaNormTransResults = m_ownerMainGrid->nncData()->makeConnectionScalarResult(riCombTransByAreaScResIdx); + const std::vector * transResults = m_ownerMainGrid->nncData()->connectionScalarResult(combTransScalarResultIndex); + + const std::vector& connections = m_ownerMainGrid->nncData()->connections(); + + for (size_t nncConIdx = 0; nncConIdx < riAreaNormTransResults.size(); ++nncConIdx) + { + const std::vector& realPolygon = connections[nncConIdx].m_polygon; + cvf::Vec3d faceAreaVec = cvf::GeometryTools::polygonAreaNormal3D(realPolygon); + double areaOfOverlap = faceAreaVec.length(); + + riAreaNormTransResults[nncConIdx] = (*transResults)[nncConIdx] / areaOfOverlap; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::setCellResults(RigCaseCellResultsData* cellResults) +{ + m_cellResults = cellResults; + + if (m_cellResults == NULL) + return; + + // Now that we have got the results container, we can finally + // Read data from the internal storage and populate it + + if (m_resultCacheFileName().isEmpty()) + return; + + // Get the name of the cache name relative to the current project file position + QString newValidCacheFileName = getValidCacheFileName(); + + QFile storageFile(newValidCacheFileName); + + // Warn if we thought we were to find some data on the storage file + + if (!storageFile.exists() && m_resultCacheMetaData.size()) + { + qWarning() << "Reading stored results: Missing the storage file : " + newValidCacheFileName; + return; + } + + if (!storageFile.open(QIODevice::ReadOnly)) + { + qWarning() << "Reading stored results: Can't open the file : " + newValidCacheFileName; + return; + } + + QDataStream stream(&storageFile); + stream.setVersion(QDataStream::Qt_4_6); + quint32 magicNumber = 0; + quint32 versionNumber = 0; + stream >> magicNumber; + + if (magicNumber != 0xCEECAC4E) + { + qWarning() << "Reading stored results: The storage file has wrong type "; + return; + } + + stream >> versionNumber; + if (versionNumber > 1 ) + { + qWarning() << "Reading stored results: The storage file has been written by a newer version of ResInsight"; + return; + } + + caf::ProgressInfo progress(m_resultCacheMetaData.size(), "Reading internally stored results"); + // Fill the object with data from the storage + + for (size_t rIdx = 0; rIdx < m_resultCacheMetaData.size(); ++rIdx) + { + RimReservoirCellResultsStorageEntryInfo* resInfo = m_resultCacheMetaData[rIdx]; + size_t resultIndex = m_cellResults->addEmptyScalarResult(resInfo->m_resultType(), resInfo->m_resultName(), true); + + m_cellResults->setTimeStepDates(resultIndex, resInfo->m_timeStepDates()); + + progress.setProgressDescription(resInfo->m_resultName); + + for (size_t tsIdx = 0; tsIdx < resInfo->m_timeStepDates().size(); ++tsIdx) + { + std::vector* data = NULL; + + data = &(m_cellResults->cellScalarResults(rIdx, tsIdx)); + + quint64 cellCount = 0; + stream >> cellCount; + data->resize(cellCount, HUGE_VAL); + + for (size_t cIdx = 0; cIdx < cellCount; ++cIdx) + { + stream >> (*data)[cIdx]; + } + } + + progress.incrementProgress(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::setMainGrid(RigMainGrid* mainGrid) +{ + m_ownerMainGrid = mainGrid; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimReservoirCellResultsStorage::storedResultsCount() +{ + return m_resultCacheMetaData.size(); +} + +//-------------------------------------------------------------------------------------------------- +/// If we have any results on any time step, assume we have loaded results +//-------------------------------------------------------------------------------------------------- +bool RimReservoirCellResultsStorage::isDataPresent(size_t scalarResultIndex) const +{ + if (scalarResultIndex >= m_cellResults->resultCount()) + { + return false; + } + + const std::vector< std::vector > data = m_cellResults->cellScalarResults(scalarResultIndex); + + for (size_t tsIdx = 0; tsIdx < data.size(); ++tsIdx) + { + if (data[tsIdx].size()) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimReservoirCellResultsStorage::darchysValue() +{ + // See "Cartesian transmissibility calculations" in the "Eclipse Technical Description" + // CDARCY Darcys constant + // = 0.00852702 (E300); 0.008527 (ECLIPSE 100) (METRIC) + // = 0.00112712 (E300); 0.001127 (ECLIPSE 100) (FIELD) + // = 3.6 (LAB) + // = 0.00864 (PVT - M) + + double darchy = 0.008527; // (ECLIPSE 100) (METRIC) + + RimCase* rimCase = NULL; + this->firstAncestorOfType(rimCase); + + if (rimCase && rimCase->reservoirData()) + { + RigCaseData::UnitsType unitsType = rimCase->reservoirData()->unitsType(); + + if (unitsType == RigCaseData::UNITS_FIELD) + { + darchy = 0.001127; + } + else if (unitsType == RigCaseData::UNITS_METRIC) + { + darchy = 0.008527; + } + else if (unitsType == RigCaseData::UNITS_LAB) + { + darchy = 3.6; + } + else + { + darchy = 0.00864; // Assuming (PVT - M) + CVF_TIGHT_ASSERT(false); // The enum and doc does not state that the PVT-M actually exists, so to trap this in debug + } + } + + return darchy; +} + + + +CAF_PDM_SOURCE_INIT(RimReservoirCellResultsStorageEntryInfo, "ResultStorageEntryInfo"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimReservoirCellResultsStorageEntryInfo::RimReservoirCellResultsStorageEntryInfo() +{ + CAF_PDM_InitObject("Cache Entry", "", "", ""); + + CAF_PDM_InitField(&m_resultType, "ResultType", caf::AppEnum(RimDefines::REMOVED), "ResultType", "", "" ,""); + CAF_PDM_InitField(&m_resultName, "ResultName", QString(), "ResultName", "", "" ,""); + CAF_PDM_InitFieldNoDefault(&m_timeStepDates, "TimeSteps", "TimeSteps", "", "" ,""); + CAF_PDM_InitField(&m_filePosition, "FilePositionDataStart", qint64(-1), "FilePositionDataStart", "", "" ,""); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimReservoirCellResultsStorageEntryInfo::~RimReservoirCellResultsStorageEntryInfo() +{ + +} diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.h b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h similarity index 83% rename from ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.h rename to ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h index f6f7a567f3..4e9fbffe3e 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.h +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,15 +19,17 @@ #pragma once -#include -#include "cvfBase.h" -#include "cvfObject.h" +#include "cafAppEnum.h" #include "cafPdmField.h" #include "cafPdmObject.h" -#include "cafAppEnum.h" +#include "cvfBase.h" +#include "cvfObject.h" + #include "RimDefines.h" +#include + class RimReservoirCellResultsStorageEntryInfo; class RigCaseCellResultsData; class RifReaderInterface; @@ -50,9 +53,8 @@ class RimReservoirCellResultsStorage : public caf::PdmObject void setReaderInterface(RifReaderInterface* readerInterface); RifReaderInterface* readerInterface(); - void loadOrComputeSOIL(); - void createCombinedTransmissibilityResults(); void computeDepthRelatedResults(); + bool isDataPresent(size_t scalarResultIndex) const; size_t findOrLoadScalarResultForTimeStep(RimDefines::ResultCatType type, const QString& resultName, size_t timeStepIndex); size_t findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName); @@ -64,10 +66,18 @@ class RimReservoirCellResultsStorage : public caf::PdmObject private: void computeSOILForTimeStep(size_t timeStepIndex); + void computeRiTransComponent(const QString& riTransComponentResultName); + void computeNncCombRiTrans(); + + void computeRiMULTComponent(const QString& riMultCompName); + void computeNncCombRiMULT(); + void computeRiTRANSbyAreaComponent(const QString& riTransByAreaCompResultName); + void computeNncCombRiTRANSbyArea(); + + double darchysValue(); QString getValidCacheFileName(); QString getCacheDirectoryPath(); - // Fields caf::PdmField m_resultCacheFileName; caf::PdmPointersField diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index 3438706133..b592adfb51 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,66 +18,50 @@ // ///////////////////////////////////////////////////////////////////////////////// -//#include "RiaStdInclude.h" #include "RimReservoirView.h" -#include "RiuViewer.h" -#include "cvfViewport.h" -#include "cvfModelBasicList.h" -#include "cvfPart.h" -#include "cvfDrawable.h" -#include "cvfScene.h" - -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include - -#include "RimProject.h" +#include "RiaApplication.h" +#include "RiaPreferences.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigResultAccessor.h" +#include "RigResultAccessorFactory.h" +#include "Rim3dOverlayInfoConfig.h" #include "RimCase.h" -#include "RimResultSlot.h" #include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilter.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilter.h" #include "RimCellPropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimWellPathCollection.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimScriptCollection.h" -#include "RimCaseCollection.h" +#include "RimCellRangeFilterCollection.h" +#include "RimFaultCollection.h" +#include "RimFaultResultSlot.h" #include "RimOilField.h" -#include "RimAnalysisModels.h" +#include "RimProject.h" +#include "RimResultSlot.h" #include "RimTernaryLegendConfig.h" - +#include "RimWell.h" +#include "RimWellCollection.h" +#include "RimWellPathCollection.h" #include "RiuMainWindow.h" -#include "RigGridBase.h" -#include "RigCaseData.h" -#include "RiaApplication.h" -#include "RiaPreferences.h" +#include "RiuViewer.h" +#include "RivReservoirPipesPartMgr.h" +#include "RivTernarySaturationOverlayItem.h" +#include "RivWellPathCollectionPartMgr.h" -#include "cafEffectGenerator.h" +#include "cafCadNavigation.h" +#include "cafCeetronPlusNavigation.h" #include "cafFrameAnimationControl.h" -#include "cvfStructGridGeometryGenerator.h" -#include "RigCaseCellResultsData.h" -#include "RivCellEdgeEffectGenerator.h" +#include "cvfDrawable.h" +#include "cvfModelBasicList.h" +#include "cvfOverlayScalarMapperLegend.h" +#include "cvfPart.h" +#include "cvfScene.h" +#include "cvfViewport.h" #include "cvfqtUtils.h" -#include "RivReservoirViewPartMgr.h" -#include "RivReservoirPipesPartMgr.h" -#include "cafCadNavigation.h" -#include "cafCeetronNavigation.h" -#include "RimCase.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RigGridScalarDataAccess.h" -#include "RimReservoirCellResultsCacher.h" -#include "RivWellPathCollectionPartMgr.h" -#include "cvfOverlayScalarMapperLegend.h" +#include #include -#include "cafCeetronPlusNavigation.h" -#include "RimFaultCollection.h" -#include "RivTernarySaturationOverlayItem.h" + namespace caf { @@ -121,6 +107,9 @@ RimReservoirView::RimReservoirView() CAF_PDM_InitFieldNoDefault(&cellEdgeResult, "GridCellEdgeResult", "Cell Edge Result", ":/EdgeResult_1.png", "", ""); cellEdgeResult = new RimCellEdgeResultSlot(); + CAF_PDM_InitFieldNoDefault(&faultResultSettings, "FaultResultSettings", "Separate Fault Result", "", "", ""); + faultResultSettings = new RimFaultResultSlot(); + CAF_PDM_InitFieldNoDefault(&overlayInfoConfig, "OverlayInfoConfig", "Info Box", "", "", ""); overlayInfoConfig = new Rim3dOverlayInfoConfig(); overlayInfoConfig->setReservoirView(this); @@ -181,6 +170,8 @@ RimReservoirView::RimReservoirView() this->cellEdgeResult()->legendConfig()->setPosition(cvf::Vec2ui(10, 320)); this->cellEdgeResult()->legendConfig()->setColorRangeMode(RimLegendConfig::PINK_WHITE); + this->faultResultSettings()->setReservoirView(this); + m_reservoirGridPartManager = new RivReservoirViewPartMgr(this); m_pipesPartManager = new RivReservoirPipesPartMgr(this); @@ -194,6 +185,7 @@ RimReservoirView::RimReservoirView() //-------------------------------------------------------------------------------------------------- RimReservoirView::~RimReservoirView() { + delete this->faultResultSettings(); delete this->cellResult(); delete this->cellEdgeResult(); delete this->overlayInfoConfig(); @@ -235,8 +227,10 @@ void RimReservoirView::updateViewerWidget() this->cellResult()->legendConfig->recreateLegend(); this->cellResult()->ternaryLegendConfig->recreateLegend(); this->cellEdgeResult()->legendConfig->recreateLegend(); - m_viewer->setColorLegend1(this->cellResult()->legendConfig->legend()); - m_viewer->setColorLegend2(this->cellEdgeResult()->legendConfig->legend()); + + m_viewer->removeAllColorLegends(); + m_viewer->addColorLegendToBottomLeftCorner(this->cellResult()->legendConfig->legend()); + m_viewer->addColorLegendToBottomLeftCorner(this->cellEdgeResult()->legendConfig->legend()); if (RiaApplication::instance()->navigationPolicy() == RiaApplication::NAVIGATION_POLICY_CEETRON) { @@ -425,7 +419,7 @@ void RimReservoirView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, } } - this->updateUiIconFromState(showWindow); + this->updateUiIconFromToggleField(); } else if (changedField == &backgroundColor ) { @@ -530,10 +524,7 @@ void RimReservoirView::createDisplayModel() // Find the number of time frames the animation needs to show the requested data. - if (this->cellResult()->hasDynamicResult() - || this->propertyFilterCollection()->hasActiveDynamicFilters() - || this->wellCollection->hasVisibleWellPipes() - || this->cellResult()->isTernarySaturationSelected()) + if (isTimeStepDependentDataVisible()) { CVF_ASSERT(currentGridCellResults()); @@ -633,9 +624,11 @@ void RimReservoirView::createDisplayModel() m_visibleGridParts = geometryTypesToAdd; } - if (!this->propertyFilterCollection()->hasActiveFilters() || faultCollection()->showFaultsOutsideFilters) + if (!this->propertyFilterCollection()->hasActiveFilters() || faultCollection()->showFaultsOutsideFilters()) { - std::vector faultGeometryTypesToAppend = visibleFaultParts(); + updateFaultForcedVisibility(); + + std::vector faultGeometryTypesToAppend = visibleFaultGeometryTypes(); RivReservoirViewPartMgr::ReservoirGeometryCacheType faultLabelType = m_reservoirGridPartManager->geometryTypeForFaultLabels(faultGeometryTypesToAppend); @@ -649,8 +642,6 @@ void RimReservoirView::createDisplayModel() m_reservoirGridPartManager->appendFaultLabelsStaticGeometryPartsToModel(frameModels[frameIdx].p(), faultLabelType); } - updateFaultForcedVisibility(); - } // Compute triangle count, Debug only @@ -697,7 +688,7 @@ void RimReservoirView::createDisplayModel() // If the animation was active before recreating everything, make viewer view current frame - if (isAnimationActive) + if (isAnimationActive || cellResult->hasResult()) { m_viewer->slotSetCurrentFrame(m_currentTimeStep); } @@ -727,9 +718,9 @@ void RimReservoirView::updateCurrentTimeStep() geometriesToRecolor.push_back( RivReservoirViewPartMgr::PROPERTY_FILTERED_WELL_CELLS); m_reservoirGridPartManager->appendDynamicGeometryPartsToModel(frameParts.p(), RivReservoirViewPartMgr::PROPERTY_FILTERED_WELL_CELLS, m_currentTimeStep, gridIndices); - if (faultCollection()->showFaultsOutsideFilters) + if (faultCollection()->showFaultsOutsideFilters()) { - std::vector faultGeometryTypesToAppend = visibleFaultParts(); + std::vector faultGeometryTypesToAppend = visibleFaultGeometryTypes(); for (size_t i = 0; i < faultGeometryTypesToAppend.size(); i++) { @@ -761,7 +752,7 @@ void RimReservoirView::updateCurrentTimeStep() { m_reservoirGridPartManager->appendStaticGeometryPartsToModel(frameParts.p(), RivReservoirViewPartMgr::RANGE_FILTERED_INACTIVE, gridIndices); - if (!faultCollection()->showFaultsOutsideFilters) + if (!faultCollection()->showFaultsOutsideFilters()) { m_reservoirGridPartManager->appendFaultsStaticGeometryPartsToModel(frameParts.p(), RivReservoirViewPartMgr::RANGE_FILTERED_INACTIVE); } @@ -770,7 +761,7 @@ void RimReservoirView::updateCurrentTimeStep() { m_reservoirGridPartManager->appendStaticGeometryPartsToModel(frameParts.p(), RivReservoirViewPartMgr::INACTIVE, gridIndices); - if (!faultCollection()->showFaultsOutsideFilters) + if (!faultCollection()->showFaultsOutsideFilters()) { m_reservoirGridPartManager->appendFaultsStaticGeometryPartsToModel(frameParts.p(), RivReservoirViewPartMgr::INACTIVE); } @@ -817,7 +808,7 @@ void RimReservoirView::updateCurrentTimeStep() { if (this->animationMode() && this->cellEdgeResult()->hasResult()) { - m_reservoirGridPartManager->updateCellEdgeResultColor(geometriesToRecolor[i], m_currentTimeStep, this->cellResult(), this->cellEdgeResult()); + m_reservoirGridPartManager->updateCellEdgeResultColor(geometriesToRecolor[i], m_currentTimeStep, this->cellResult(), this->cellEdgeResult()); } else if ((this->animationMode() && this->cellResult()->hasResult()) || this->cellResult()->isTernarySaturationSelected()) { @@ -916,7 +907,7 @@ void RimReservoirView::loadDataAndUpdate() if (m_reservoir) { - if (!m_reservoir->openEclipseGridFile()) + if (!m_reservoir->openReserviorCase()) { QMessageBox::warning(RiuMainWindow::instance(), "Error when opening project file", @@ -924,36 +915,17 @@ void RimReservoirView::loadDataAndUpdate() m_reservoir = NULL; return; } - else - { - RiaApplication* app = RiaApplication::instance(); - if (app->preferences()->autocomputeSOIL) - { - { - RimReservoirCellResultsStorage* results = m_reservoir->results(RifReaderInterface::MATRIX_RESULTS); - results->loadOrComputeSOIL(); - results->createCombinedTransmissibilityResults(); - } - { - RimReservoirCellResultsStorage* results = m_reservoir->results(RifReaderInterface::FRACTURE_RESULTS); - results->loadOrComputeSOIL(); - results->createCombinedTransmissibilityResults(); - } - } - } } CVF_ASSERT(this->cellResult() != NULL); this->cellResult()->loadResult(); - if (m_reservoir->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->globalActiveCellCount() == 0) - { - this->cellResult->setPorosityModelUiFieldHidden(true); - } - CVF_ASSERT(this->cellEdgeResult() != NULL); this->cellEdgeResult()->loadResult(); + this->faultResultSettings()->customFaultResult()->loadResult(); + this->faultResultSettings()->updateFieldVisibility(); + updateViewerWidget(); this->propertyFilterCollection()->loadAndInitializePropertyFilters(); @@ -981,11 +953,13 @@ void RimReservoirView::loadDataAndUpdate() //-------------------------------------------------------------------------------------------------- void RimReservoirView::initAfterRead() { + this->faultResultSettings()->setReservoirView(this); this->cellResult()->setReservoirView(this); this->cellEdgeResult()->setReservoirView(this); this->rangeFilterCollection()->setReservoirView(this); this->propertyFilterCollection()->setReservoirView(this); + this->updateUiIconFromToggleField(); } //-------------------------------------------------------------------------------------------------- @@ -1059,180 +1033,6 @@ RiuViewer* RimReservoirView::viewer() return m_viewer; } - -//-------------------------------------------------------------------------------------------------- -/// Get pick info text for given part ID, face index, and intersection point -//-------------------------------------------------------------------------------------------------- -bool RimReservoirView::pickInfo(size_t gridIndex, size_t cellIndex, cvf::StructGridInterface::FaceType face, const cvf::Vec3d& point, QString* pickInfoText) const -{ - CVF_ASSERT(pickInfoText); - - if (m_reservoir) - { - const RigCaseData* eclipseCase = m_reservoir->reservoirData(); - if (eclipseCase) - { - size_t i = 0; - size_t j = 0; - size_t k = 0; - if (eclipseCase->grid(gridIndex)->ijkFromCellIndex(cellIndex, &i, &j, &k)) - { - // Adjust to 1-based Eclipse indexing - i++; - j++; - k++; - - cvf::Vec3d domainCoord = point + eclipseCase->grid(gridIndex)->displayModelOffset(); - - cvf::StructGridInterface::FaceEnum faceEnum(face); - - QString faceText = faceEnum.text(); - - *pickInfoText = QString("Hit grid %1, cell [%2, %3, %4] face %5, ").arg(gridIndex).arg(i).arg(j).arg(k).arg(faceText); - - QString formattedText; - formattedText.sprintf("intersection point: [E: %.2f, N: %.2f, Depth: %.2f]", domainCoord.x(), domainCoord.y(), -domainCoord.z()); - - *pickInfoText += formattedText; - return true; - } - } - } - - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// Append fault name and result value for the given cell to the string -//-------------------------------------------------------------------------------------------------- -void RimReservoirView::appendCellResultInfo(size_t gridIndex, size_t cellIndex, cvf::StructGridInterface::FaceType face, QString* resultInfoText) -{ - CVF_ASSERT(resultInfoText); - - if (m_reservoir && m_reservoir->reservoirData()) - { - RigCaseData* eclipseCase = m_reservoir->reservoirData(); - RigGridBase* grid = eclipseCase->grid(gridIndex); - - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); - cvf::ref dataAccessObject; - - if (this->cellResult()->isTernarySaturationSelected()) - { - RimReservoirCellResultsStorage* gridCellResults = this->cellResult()->currentGridCellResults(); - if (gridCellResults) - { - size_t soilScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); - size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); - size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); - - cvf::ref dataAccessObjectX = eclipseCase->dataAccessObject(grid, porosityModel, m_currentTimeStep, soilScalarSetIndex); - cvf::ref dataAccessObjectY = eclipseCase->dataAccessObject(grid, porosityModel, m_currentTimeStep, sgasScalarSetIndex); - cvf::ref dataAccessObjectZ = eclipseCase->dataAccessObject(grid, porosityModel, m_currentTimeStep, swatScalarSetIndex); - - double scalarValue = 0.0; - - if (dataAccessObjectX.notNull()) scalarValue = dataAccessObjectX->cellScalar(cellIndex); - else scalarValue = 0.0; - resultInfoText->append(QString("SOIL : %1\n").arg(scalarValue)); - - if (dataAccessObjectY.notNull()) scalarValue = dataAccessObjectY->cellScalar(cellIndex); - else scalarValue = 0.0; - resultInfoText->append(QString("SGAS : %1\n").arg(scalarValue)); - - if (dataAccessObjectZ.notNull()) scalarValue = dataAccessObjectZ->cellScalar(cellIndex); - else scalarValue = 0.0; - resultInfoText->append(QString("SWAT : %1\n").arg(scalarValue)); - } - } - else if (this->cellResult()->hasResult()) - { - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); - cvf::ref dataAccessObject; - - if (cellResult->hasStaticResult()) - { - if (this->cellResult()->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) - { - size_t tranX, tranY, tranZ; - if (eclipseCase->results(porosityModel)->findTransmissibilityResults(tranX, tranY, tranZ)) - { - cvf::ref dataAccessObjectX = eclipseCase->dataAccessObject(grid, porosityModel, 0, tranX); - cvf::ref dataAccessObjectY = eclipseCase->dataAccessObject(grid, porosityModel, 0, tranY); - cvf::ref dataAccessObjectZ = eclipseCase->dataAccessObject(grid, porosityModel, 0, tranZ); - - double scalarValue = dataAccessObjectX->cellScalar(cellIndex); - resultInfoText->append(QString("Tran X : %1\n").arg(scalarValue)); - - scalarValue = dataAccessObjectY->cellScalar(cellIndex); - resultInfoText->append(QString("Tran Y : %1\n").arg(scalarValue)); - - scalarValue = dataAccessObjectZ->cellScalar(cellIndex); - resultInfoText->append(QString("Tran Z : %1\n").arg(scalarValue)); - } - } - else - { - dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, 0, this->cellResult()->gridScalarIndex()); - } - } - else - { - dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, m_currentTimeStep, this->cellResult()->gridScalarIndex()); - } - - if (dataAccessObject.notNull()) - { - double scalarValue = dataAccessObject->cellScalar(cellIndex); - resultInfoText->append(QString("Cell result : %1\n").arg(scalarValue)); - } - } - - if (this->cellEdgeResult()->hasResult()) - { - size_t resultIndices[6]; - QStringList resultNames; - this->cellEdgeResult()->gridScalarIndices(resultIndices); - this->cellEdgeResult()->gridScalarResultNames(&resultNames); - - for (int idx = 0; idx < 6; idx++) - { - if (resultIndices[idx] == cvf::UNDEFINED_SIZE_T) continue; - - // Cell edge results are static, results are loaded for first time step only - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); - cvf::ref dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, 0, resultIndices[idx]); - if (dataAccessObject.notNull()) - { - double scalarValue = dataAccessObject->cellScalar(cellIndex); - resultInfoText->append(QString("%1 : %2\n").arg(resultNames[idx]).arg(scalarValue)); - } - } - } - - cvf::Collection wellResults = m_reservoir->reservoirData()->wellResults(); - for (size_t i = 0; i < wellResults.size(); i++) - { - RigSingleWellResultsData* singleWellResultData = wellResults.at(i); - - if (m_currentTimeStep < static_cast(singleWellResultData->firstResultTimeStep())) - { - continue; - } - - const RigWellResultFrame& wellResultFrame = singleWellResultData->wellResultFrame(m_currentTimeStep); - const RigWellResultPoint* wellResultCell = wellResultFrame.findResultCell(gridIndex, cellIndex); - if (wellResultCell) - { - resultInfoText->append(QString("Well-cell connection info: Well Name: %1 Branch Id: %2 Segment Id: %3\n").arg(singleWellResultData->m_wellName).arg(wellResultCell->m_ertBranchId).arg(wellResultCell->m_ertSegmentId)); - } - } - - appendFaultName(grid, cellIndex, face, resultInfoText); - } -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1384,6 +1184,11 @@ void RimReservoirView::indicesToVisibleGrids(std::vector* gridIndices) //-------------------------------------------------------------------------------------------------- void RimReservoirView::updateLegends() { + if (m_viewer) + { + m_viewer->removeAllColorLegends(); + } + if (!m_reservoir || !m_viewer || !m_reservoir->reservoirData() ) { return; @@ -1396,40 +1201,10 @@ void RimReservoirView::updateLegends() RigCaseCellResultsData* results = eclipseCase->results(porosityModel); CVF_ASSERT(results); - if (this->cellResult()->hasResult()) + updateMinMaxValuesAndAddLegendToView(QString("Cell Results: \n"), this->cellResult(), results); + if (this->faultResultSettings()->showCustomFaultResult() && this->faultResultSettings()->hasValidCustomResult()) { - double globalMin, globalMax; - double globalPosClosestToZero, globalNegClosestToZero; - results->minMaxCellScalarValues(this->cellResult()->gridScalarIndex(), globalMin, globalMax); - results->posNegClosestToZero(this->cellResult()->gridScalarIndex(), globalPosClosestToZero, globalNegClosestToZero); - - double localMin, localMax; - double localPosClosestToZero, localNegClosestToZero; - if (this->cellResult()->hasDynamicResult()) - { - results->minMaxCellScalarValues(this->cellResult()->gridScalarIndex(), m_currentTimeStep, localMin, localMax); - results->posNegClosestToZero(this->cellResult()->gridScalarIndex(), m_currentTimeStep, localPosClosestToZero, localNegClosestToZero); - } - else - { - localMin = globalMin; - localMax = globalMax; - - localPosClosestToZero = globalPosClosestToZero; - localNegClosestToZero = globalNegClosestToZero; - } - - this->cellResult()->legendConfig->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero); - this->cellResult()->legendConfig->setAutomaticRanges(globalMin, globalMax, localMin, localMax); - - m_viewer->setColorLegend1(this->cellResult()->legendConfig->legend()); - this->cellResult()->legendConfig->legend()->setTitle(cvfqt::Utils::toString(QString("Cell Results: \n") + this->cellResult()->resultVariable())); - } - else - { - this->cellResult()->legendConfig->setClosestToZeroValues(0, 0, 0, 0); - this->cellResult()->legendConfig->setAutomaticRanges(cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE); - m_viewer->setColorLegend1(NULL); + updateMinMaxValuesAndAddLegendToView(QString("Fault Results: \n"), this->currentFaultResultSlot(), results); } if (this->cellEdgeResult()->hasResult()) @@ -1442,24 +1217,60 @@ void RimReservoirView::updateLegends() this->cellEdgeResult()->legendConfig->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, globalPosClosestToZero, globalNegClosestToZero); this->cellEdgeResult()->legendConfig->setAutomaticRanges(globalMin, globalMax, globalMin, globalMax); - m_viewer->setColorLegend2(this->cellEdgeResult()->legendConfig->legend()); + m_viewer->addColorLegendToBottomLeftCorner(this->cellEdgeResult()->legendConfig->legend()); this->cellEdgeResult()->legendConfig->legend()->setTitle(cvfqt::Utils::toString(QString("Edge Results: \n") + this->cellEdgeResult()->resultVariable)); - } else { - m_viewer->setColorLegend2(NULL); this->cellEdgeResult()->legendConfig->setClosestToZeroValues(0, 0, 0, 0); this->cellEdgeResult()->legendConfig->setAutomaticRanges(cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE); } +} - - viewer()->removeOverlayItem(this->cellResult()->ternaryLegendConfig->legend()); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirView::updateMinMaxValuesAndAddLegendToView(QString legendLabel, RimResultSlot* resultSlot, RigCaseCellResultsData* cellResultsData) +{ + if (resultSlot->hasResult()) + { + double globalMin, globalMax; + double globalPosClosestToZero, globalNegClosestToZero; + cellResultsData->minMaxCellScalarValues(resultSlot->scalarResultIndex(), globalMin, globalMax); + cellResultsData->posNegClosestToZero(resultSlot->scalarResultIndex(), globalPosClosestToZero, globalNegClosestToZero); - size_t maxTimeStepCount = results->maxTimeStepCount(); - if (this->cellResult()->isTernarySaturationSelected() && maxTimeStepCount > 1) + double localMin, localMax; + double localPosClosestToZero, localNegClosestToZero; + if (resultSlot->hasDynamicResult()) + { + cellResultsData->minMaxCellScalarValues(resultSlot->scalarResultIndex(), m_currentTimeStep, localMin, localMax); + cellResultsData->posNegClosestToZero(resultSlot->scalarResultIndex(), m_currentTimeStep, localPosClosestToZero, localNegClosestToZero); + } + else + { + localMin = globalMin; + localMax = globalMax; + + localPosClosestToZero = globalPosClosestToZero; + localNegClosestToZero = globalNegClosestToZero; + } + + resultSlot->legendConfig->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero); + resultSlot->legendConfig->setAutomaticRanges(globalMin, globalMax, localMin, localMax); + + m_viewer->addColorLegendToBottomLeftCorner(resultSlot->legendConfig->legend()); + resultSlot->legendConfig->legend()->setTitle(cvfqt::Utils::toString(legendLabel + resultSlot->resultVariable())); + } + else { - RimReservoirCellResultsStorage* gridCellResults = this->cellResult()->currentGridCellResults(); + resultSlot->legendConfig->setClosestToZeroValues(0, 0, 0, 0); + resultSlot->legendConfig->setAutomaticRanges(cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE); + } + + size_t maxTimeStepCount = cellResultsData->maxTimeStepCount(); + if (resultSlot->isTernarySaturationSelected() && maxTimeStepCount > 1) + { + RimReservoirCellResultsStorage* gridCellResults = resultSlot->currentGridCellResults(); { double globalMin = 0.0; double globalMax = 1.0; @@ -1469,10 +1280,10 @@ void RimReservoirView::updateLegends() size_t scalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); if (scalarSetIndex != cvf::UNDEFINED_SIZE_T) { - results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); - results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); + cellResultsData->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); + cellResultsData->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); - this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SOIL_IDX, globalMin, globalMax, localMin, localMax); + resultSlot->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SOIL_IDX, globalMin, globalMax, localMin, localMax); } } @@ -1485,10 +1296,10 @@ void RimReservoirView::updateLegends() size_t scalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); if (scalarSetIndex != cvf::UNDEFINED_SIZE_T) { - results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); - results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); + cellResultsData->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); + cellResultsData->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); - this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SGAS_IDX, globalMin, globalMax, localMin, localMax); + resultSlot->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SGAS_IDX, globalMin, globalMax, localMin, localMax); } } @@ -1501,16 +1312,17 @@ void RimReservoirView::updateLegends() size_t scalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); if (scalarSetIndex != cvf::UNDEFINED_SIZE_T) { - results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); - results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); + cellResultsData->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax); + cellResultsData->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax); - this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SWAT_IDX, globalMin, globalMax, localMin, localMax); + resultSlot->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SWAT_IDX, globalMin, globalMax, localMin, localMax); } } - if (this->cellResult()->ternaryLegendConfig->legend()) + if (resultSlot->ternaryLegendConfig->legend()) { - viewer()->addOverlayItem(this->cellResult()->ternaryLegendConfig->legend()); + resultSlot->ternaryLegendConfig->legend()->setTitle(cvfqt::Utils::toString(legendLabel)); + m_viewer->addColorLegendToBottomLeftCorner(resultSlot->ternaryLegendConfig->legend()); } } } @@ -1639,9 +1451,9 @@ void RimReservoirView::calculateVisibleWellCellsIncFence(cvf::UByteArray* visibl if (wellResFrames[wfIdx].m_wellHead.m_gridIndex == grid->gridIndex()) { size_t gridCellIndex = wellResFrames[wfIdx].m_wellHead.m_gridCellIndex; - size_t globalGridCellIndex = grid->globalGridCellIndex(gridCellIndex); + size_t reservoirCellIndex = grid->reservoirCellIndex(gridCellIndex); - if (activeCellInfo->isActive(globalGridCellIndex)) + if (activeCellInfo->isActive(reservoirCellIndex)) { (*visibleCells)[gridCellIndex] = true; } @@ -1696,9 +1508,9 @@ void RimReservoirView::calculateVisibleWellCellsIncFence(cvf::UByteArray* visibl for ( fIdx = 0; fIdx < cellCountFenceDirection; ++fIdx) { size_t fenceCellIndex = grid->cellIndexFromIJK(*pI,*pJ,*pK); - size_t globalGridCellIndex = grid->globalGridCellIndex(fenceCellIndex); + size_t reservoirCellIndex = grid->reservoirCellIndex(fenceCellIndex); - if (activeCellInfo && activeCellInfo->isActive(globalGridCellIndex)) + if (activeCellInfo && activeCellInfo->isActive(reservoirCellIndex)) { (*visibleCells)[fenceCellIndex] = true; } @@ -1867,91 +1679,6 @@ void RimReservoirView::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering cellGroup->add(&showInvalidCells); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimReservoirView::appendNNCResultInfo(size_t nncIndex, QString* resultInfo) -{ - CVF_ASSERT(resultInfo); - - if (m_reservoir && m_reservoir->reservoirData()) - { - RigCaseData* eclipseCase = m_reservoir->reservoirData(); - - RigMainGrid* grid = eclipseCase->mainGrid(); - CVF_ASSERT(grid); - - RigNNCData* nncData = grid->nncData(); - CVF_ASSERT(nncData); - - if (nncData) - { - const RigConnection& conn = nncData->connections()[nncIndex]; - cvf::StructGridInterface::FaceEnum face(conn.m_c1Face); - - QString faultName; - - resultInfo->append(QString("NNC Transmissibility : %1\n").arg(conn.m_transmissibility)); - { - CVF_ASSERT(conn.m_c1GlobIdx < grid->cells().size()); - const RigCell& cell = grid->cells()[conn.m_c1GlobIdx]; - - RigGridBase* hostGrid = cell.hostGrid(); - size_t localCellIndex = cell.cellIndex(); - - size_t i, j, k; - if (hostGrid->ijkFromCellIndex(localCellIndex, &i, &j, &k)) - { - // Adjust to 1-based Eclipse indexing - i++; - j++; - k++; - - QString gridName = QString::fromStdString(hostGrid->gridName()); - resultInfo->append(QString("NNC 1 : cell [%1, %2, %3] face %4 (%5)\n").arg(i).arg(j).arg(k).arg(face.text()).arg(gridName)); - - appendFaultName(hostGrid, conn.m_c1GlobIdx, conn.m_c1Face, &faultName); - } - } - - { - CVF_ASSERT(conn.m_c2GlobIdx < grid->cells().size()); - const RigCell& cell = grid->cells()[conn.m_c2GlobIdx]; - - RigGridBase* hostGrid = cell.hostGrid(); - size_t localCellIndex = cell.cellIndex(); - - size_t i, j, k; - if (hostGrid->ijkFromCellIndex(localCellIndex, &i, &j, &k)) - { - // Adjust to 1-based Eclipse indexing - i++; - j++; - k++; - - QString gridName = QString::fromStdString(hostGrid->gridName()); - cvf::StructGridInterface::FaceEnum oppositeFaceEnum(cvf::StructGridInterface::oppositeFace(face)); - QString faceText = oppositeFaceEnum.text(); - - resultInfo->append(QString("NNC 2 : cell [%1, %2, %3] face %4 (%5)\n").arg(i).arg(j).arg(k).arg(faceText).arg(gridName)); - - if (faultName.isEmpty()) - { - appendFaultName(hostGrid, conn.m_c2GlobIdx, cvf::StructGridInterface::oppositeFace(conn.m_c1Face), &faultName); - } - } - } - - resultInfo->append(QString("Face: %2\n").arg(face.text())); - - if (!faultName.isEmpty()) - { - resultInfo->append(faultName); - } - } - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1961,35 +1688,24 @@ void RimReservoirView::updateFaultForcedVisibility() // As fault geometry is visible in grid visualization mode, fault geometry must be forced visible // even if the fault item is disabled in project tree view - caf::FixedArray forceOn; - - for (size_t i = 0; i < RivReservoirViewPartMgr::PROPERTY_FILTERED; i++) - { - forceOn[i] = false; - } - - std::vector faultParts = visibleFaultParts(); - for (size_t i = 0; i < faultParts.size(); i++) + if (!faultCollection->showFaultCollection) { - forceOn[faultParts[i]]; + m_reservoirGridPartManager->setFaultForceVisibilityForGeometryType(RivReservoirViewPartMgr::ALL_WELL_CELLS, true); } - for (size_t i = 0; i < RivReservoirViewPartMgr::PROPERTY_FILTERED; i++) - { - RivReservoirViewPartMgr::ReservoirGeometryCacheType cacheType = (RivReservoirViewPartMgr::ReservoirGeometryCacheType)i; - - m_reservoirGridPartManager->setFaultForceVisibilityForGeometryType(cacheType, forceOn[i]); - } + m_reservoirGridPartManager->setFaultForceVisibilityForGeometryType(RivReservoirViewPartMgr::RANGE_FILTERED, true); + m_reservoirGridPartManager->setFaultForceVisibilityForGeometryType(RivReservoirViewPartMgr::VISIBLE_WELL_FENCE_CELLS, true); + m_reservoirGridPartManager->setFaultForceVisibilityForGeometryType(RivReservoirViewPartMgr::VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER, true); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimReservoirView::visibleFaultParts() const +std::vector RimReservoirView::visibleFaultGeometryTypes() const { std::vector faultParts; - if (this->propertyFilterCollection()->hasActiveFilters() && !faultCollection()->showFaultsOutsideFilters) + if (this->propertyFilterCollection()->hasActiveFilters() && !faultCollection()->showFaultsOutsideFilters()) { faultParts.push_back(RivReservoirViewPartMgr::PROPERTY_FILTERED); faultParts.push_back(RivReservoirViewPartMgr::PROPERTY_FILTERED_WELL_CELLS); @@ -2063,50 +1779,60 @@ std::vector RimReservoirVie void RimReservoirView::updateFaultColors() { // Update all fault geometry - std::vector faultGeometriesToRecolor = visibleFaultParts(); + std::vector faultGeometriesToRecolor = visibleFaultGeometryTypes(); + + RimResultSlot* faultResultSlot = currentFaultResultSlot(); for (size_t i = 0; i < faultGeometriesToRecolor.size(); ++i) { - m_reservoirGridPartManager->updateFaultColors(faultGeometriesToRecolor[i], m_currentTimeStep, this->cellResult()); + if (this->animationMode() && this->cellEdgeResult()->hasResult()) + { + m_reservoirGridPartManager->updateFaultCellEdgeResultColor(faultGeometriesToRecolor[i], m_currentTimeStep, faultResultSlot, this->cellEdgeResult()); + } + else + { + m_reservoirGridPartManager->updateFaultColors(faultGeometriesToRecolor[i], m_currentTimeStep, faultResultSlot); + } } } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimReservoirView::appendFaultName(RigGridBase* grid, size_t cellIndex, cvf::StructGridInterface::FaceType face, QString* resultInfoText) +bool RimReservoirView::isTimeStepDependentDataVisible() const { - if (grid->isMainGrid()) + if (this->cellResult()->hasDynamicResult()) return true; + + if (this->propertyFilterCollection()->hasActiveDynamicFilters()) return true; + + if (this->wellCollection->hasVisibleWellPipes()) return true; + + if (this->cellResult()->isTernarySaturationSelected()) return true; + + if (this->faultResultSettings->showCustomFaultResult()) { - RigMainGrid* mainGrid = grid->mainGrid(); + if (this->faultResultSettings->customFaultResult()->hasDynamicResult()) return true; - for (size_t i = 0; i < mainGrid->faults().size(); i++) - { - const RigFault* rigFault = mainGrid->faults().at(i); - const std::vector& faultFaces = rigFault->faultFaces(); + if (this->faultResultSettings->customFaultResult()->isTernarySaturationSelected()) return true; + } - for (size_t fIdx = 0; fIdx < faultFaces.size(); fIdx++) - { - if (faultFaces[fIdx].m_nativeGlobalCellIndex == cellIndex) - { - if (face == faultFaces[fIdx].m_nativeFace ) - { - resultInfoText->append(QString("Fault Name: %1\n").arg(rigFault->name())); - } + return false; +} - return; - } - if (faultFaces[fIdx].m_oppositeGlobalCellIndex == cellIndex) - { - if (face == cvf::StructGridInterface::oppositeFace(faultFaces[fIdx].m_nativeFace)) - { - resultInfoText->append(QString("Fault Name: %1\n").arg(rigFault->name())); - } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimResultSlot* RimReservoirView::currentFaultResultSlot() +{ + RimResultSlot* faultResultSlot = this->cellResult(); - return; - } - } - } + if (this->faultResultSettings()->showCustomFaultResult()) + { + faultResultSlot = this->faultResultSettings()->customFaultResult(); } + + return faultResultSlot; } + diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.h b/ApplicationCode/ProjectDataModel/RimReservoirView.h index a45a6c2e1d..5a85363b71 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.h +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,40 +19,40 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once -#include "cafPdmObject.h" -#include "cafPdmField.h" + #include "cafAppEnum.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cvfArray.h" #include "cvfBase.h" #include "cvfObject.h" +// Includes to make Pdm work for cvf::Color and cvf:Mat +#include "cafPdmFieldCvfColor.h" #include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include -#include - -#include "RimFaultCollection.h" +#include "RivReservoirViewPartMgr.h" +class RigActiveCellInfo; +class RigCaseCellResultsData; +class RigGridBase; +class RigGridCellFaceVisibilityFilter; +class Rim3dOverlayInfoConfig; class RimCase; -class RimResultSlot; class RimCellEdgeResultSlot; -class RimCellRangeFilter; -class RimCellRangeFilterCollection; class RimCellPropertyFilter; class RimCellPropertyFilterCollection; -class Rim3dOverlayInfoConfig; +class RimCellRangeFilter; +class RimCellRangeFilterCollection; +class RimFaultCollection; +class RimFaultResultSlot; class RimReservoirCellResultsStorage; +class RimReservoirCellResultsStorage; +class RimResultSlot; class RimWellCollection; -class RigActiveCellInfo; - -#include "RivReservoirViewPartMgr.h" -class RivReservoirPipesPartMgr; - class RiuViewer; -class RigGridBase; -class RigGridCellFaceVisibilityFilter; -class RimReservoirCellResultsStorage; +class RivReservoirPipesPartMgr; namespace cvf { @@ -98,6 +100,7 @@ class RimReservoirView : public caf::PdmObject caf::PdmField cellResult; caf::PdmField cellEdgeResult; + caf::PdmField faultResultSettings; caf::PdmField rangeFilterCollection; caf::PdmField propertyFilterCollection; @@ -132,6 +135,8 @@ class RimReservoirView : public caf::PdmObject // Access internal objects RimReservoirCellResultsStorage* currentGridCellResults(); RigActiveCellInfo* currentActiveCellInfo(); + RimResultSlot* currentFaultResultSlot(); + void setEclipseCase(RimCase* reservoir); RimCase* eclipseCase(); @@ -156,12 +161,6 @@ class RimReservoirView : public caf::PdmObject void setShowFaultsOnly(bool showFaults); bool isGridVisualizationMode() const; - - // Picking info - bool pickInfo(size_t gridIndex, size_t cellIndex, cvf::StructGridInterface::FaceType face, const cvf::Vec3d& point, QString* pickInfoText) const; - void appendCellResultInfo(size_t gridIndex, size_t cellIndex, cvf::StructGridInterface::FaceType face, QString* resultInfoText) ; - void appendNNCResultInfo(size_t nncIndex, QString* resultInfo); - // Does this belong here, really ? void calculateVisibleWellCellsIncFence(cvf::UByteArray* visibleCells, RigGridBase * grid); @@ -170,6 +169,7 @@ class RimReservoirView : public caf::PdmObject void loadDataAndUpdate(); void createDisplayModelAndRedraw(); void scheduleCreateDisplayModelAndRedraw(); + bool isTimeStepDependentDataVisible() const; void scheduleGeometryRegen(unsigned short geometryType); void scheduleReservoirGridGeometryRegen(); @@ -182,8 +182,6 @@ class RimReservoirView : public caf::PdmObject // Display model generation private: - void appendFaultName(RigGridBase* grid, size_t cellIndex, cvf::StructGridInterface::FaceType face, QString* resultInfoText); - void createDisplayModel(); void updateDisplayModelVisibility(); void updateCurrentTimeStep(); @@ -192,12 +190,12 @@ class RimReservoirView : public caf::PdmObject void updateStaticCellColors(); void updateStaticCellColors(unsigned short geometryType); void updateLegends(); + void updateMinMaxValuesAndAddLegendToView(QString legendLabel, RimResultSlot* resultSlot, RigCaseCellResultsData* cellResultsData); - std::vector visibleFaultParts() const; + std::vector visibleFaultGeometryTypes() const; void updateFaultForcedVisibility(); void updateFaultColors(); - cvf::ref m_reservoirGridPartManager; cvf::ref m_pipesPartManager; diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.cpp b/ApplicationCode/ProjectDataModel/RimResultCase.cpp index d0d72587fa..c83df1600a 100644 --- a/ApplicationCode/ProjectDataModel/RimResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultCase.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,41 +18,26 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - -#include "cafProgressInfo.h" -#include "cafPdmSettings.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "cafPdmUiPropertyDialog.h" - #include "RimResultCase.h" -#include "RigCaseData.h" -#include "RifReaderEclipseOutput.h" -#include "RigCaseCellResultsData.h" -#include "RimReservoirView.h" -#include "RifReaderMockModel.h" -#include "RifReaderEclipseInput.h" -#include "RimProject.h" -#include "RifEclipseOutputFileTools.h" -#include "RiaApplication.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimScriptCollection.h" -#include "RimCaseCollection.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimWellPathCollection.h" - -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimOilField.h" -#include "RimAnalysisModels.h" #include "RiaPreferences.h" +#include "RifEclipseOutputFileTools.h" +#include "RifReaderEclipseOutput.h" +#include "RifReaderMockModel.h" +#include "RifReaderSettings.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" #include "RimMockModelSettings.h" +#include "RimProject.h" +#include "RimReservoirCellResultsStorage.h" + +#include "cafPdmSettings.h" +#include "cafPdmUiPropertyDialog.h" +#include "cafProgressInfo.h" + +#include +#include +#include CAF_PDM_SOURCE_INIT(RimResultCase, "EclipseCase"); //-------------------------------------------------------------------------------------------------- @@ -106,7 +93,7 @@ bool RimResultCase::openEclipseGridFile() RiaPreferences* prefs = RiaApplication::instance()->preferences(); readerInterface = new RifReaderEclipseOutput; - readerInterface->readFaultData(prefs->readFaultData()); + readerInterface->setReaderSetting(prefs->readerSettings()); readerInterface->setFilenamesWithFaults(this->filesContainingFaults()); cvf::ref eclipseCase = new RigCaseData; diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.h b/ApplicationCode/ProjectDataModel/RimResultCase.h index 0463cdf508..b373bb3ddb 100644 --- a/ApplicationCode/ProjectDataModel/RimResultCase.h +++ b/ApplicationCode/ProjectDataModel/RimResultCase.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,10 +20,6 @@ #pragma once -#include "cvfBase.h" -#include "cvfObject.h" -#include "cafPdmField.h" -#include "cafPdmObject.h" #include "RimCase.h" class RifReaderInterface; diff --git a/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp index 110036ffb8..245489343e 100644 --- a/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,27 +18,15 @@ // ///////////////////////////////////////////////////////////////////////////////// -//#include "RiaStdInclude.h" - #include "RimResultDefinition.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimReservoirView.h" -#include "RimCase.h" #include "RigCaseCellResultsData.h" #include "RigCaseData.h" -#include "RigMainGrid.h" -#include "cafPdmUiListEditor.h" - +#include "RimCase.h" +#include "RimReservoirCellResultsStorage.h" +#include "RimReservoirView.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" +#include "cafPdmUiListEditor.h" CAF_PDM_SOURCE_INIT(RimResultDefinition, "ResultDefinition"); @@ -50,7 +40,7 @@ RimResultDefinition::RimResultDefinition() CAF_PDM_InitFieldNoDefault(&m_resultType, "ResultType", "Type", "", "", ""); m_resultType.setUiHidden(true); - CAF_PDM_InitFieldNoDefault(&m_porosityModel, "PorosityModelType", "Type", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_porosityModel, "PorosityModelType", "Porosity", "", "", ""); m_porosityModel.setUiHidden(true); CAF_PDM_InitField(&m_resultVariable, "ResultVariable", RimDefines::undefinedResultName(), "Variable", "", "", "" ); m_resultVariable.setUiHidden(true); @@ -58,7 +48,7 @@ RimResultDefinition::RimResultDefinition() CAF_PDM_InitFieldNoDefault(&m_resultTypeUiField, "MResultType", "Type", "", "", ""); m_resultTypeUiField.setIOReadable(false); m_resultTypeUiField.setIOWritable(false); - CAF_PDM_InitFieldNoDefault(&m_porosityModelUiField, "MPorosityModelType", "Type", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_porosityModelUiField, "MPorosityModelType", "Porosity", "", "", ""); m_porosityModelUiField.setIOReadable(false); m_porosityModelUiField.setIOWritable(false); CAF_PDM_InitField(&m_resultVariableUiField, "MResultVariable", RimDefines::undefinedResultName(), "Result property", "", "", "" ); @@ -84,16 +74,7 @@ void RimResultDefinition::setReservoirView(RimReservoirView* ownerReservoirView) { m_reservoirView = ownerReservoirView; - // TODO: This code is executed before reservoir is read, and then porosity model is never set to zero - if (m_reservoirView->eclipseCase() && - m_reservoirView->eclipseCase()->reservoirData() && - m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS) ) - { - if (m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->globalActiveCellCount() == 0) - { - m_porosityModelUiField.setUiHidden(true); - } - } + updateFieldVisibility(); } QStringList RimResultDefinition::getResultVariableListForCurrentUIFieldSettings() @@ -151,7 +132,15 @@ void RimResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* changedFie //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QList RimResultDefinition::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +QList RimResultDefinition::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +{ + return calculateValueOptionsForSpecifiedDerivedListPosition(false, fieldNeedingOptions, useOptionsOnly); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimResultDefinition::calculateValueOptionsForSpecifiedDerivedListPosition(bool showDerivedResultsFirstInList, const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) { if (fieldNeedingOptions == &m_resultVariableUiField) { @@ -162,22 +151,20 @@ QList RimResultDefinition::calculateValueOptions(const c bool hasCombinedTransmissibility = false; QList optionList; + QList perCellFaceOptionList; for (int i = 0; i < varList.size(); ++i) { - if (varList[i].compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) + if (RimDefines::isPerCellFaceResult(varList[i])) { - hasCombinedTransmissibility = true; - continue; + // Move combined per cell face results to top of list + perCellFaceOptionList.push_back(caf::PdmOptionItemInfo(varList[i], varList[i])); + } + else + { + optionList.push_back(caf::PdmOptionItemInfo(varList[i], varList[i])); } - - optionList.push_back(caf::PdmOptionItemInfo(varList[i], varList[i])); - } - - if (hasCombinedTransmissibility) - { - optionList.push_front(caf::PdmOptionItemInfo(RimDefines::combinedTransmissibilityResultName(), RimDefines::combinedTransmissibilityResultName())); } - + bool hasAtLeastOneTernaryComponent = false; if (varList.contains("SOIL")) hasAtLeastOneTernaryComponent = true; else if (varList.contains("SGAS")) hasAtLeastOneTernaryComponent = true; @@ -188,7 +175,19 @@ QList RimResultDefinition::calculateValueOptions(const c optionList.push_front(caf::PdmOptionItemInfo(RimDefines::ternarySaturationResultName(), RimDefines::ternarySaturationResultName())); } - optionList.push_front(caf::PdmOptionItemInfo( RimDefines::undefinedResultName(), RimDefines::undefinedResultName() )); + for (int i = 0; i < perCellFaceOptionList.size(); i++) + { + if (showDerivedResultsFirstInList) + { + optionList.push_front(perCellFaceOptionList[i]); + } + else + { + optionList.push_back(perCellFaceOptionList[i]); + } + } + + optionList.push_front(caf::PdmOptionItemInfo(RimDefines::undefinedResultName(), RimDefines::undefinedResultName())); if (useOptionsOnly) *useOptionsOnly = true; @@ -202,7 +201,7 @@ QList RimResultDefinition::calculateValueOptions(const c //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RimResultDefinition::gridScalarIndex() const +size_t RimResultDefinition::scalarResultIndex() const { size_t gridScalarResultIndex = cvf::UNDEFINED_SIZE_T; @@ -220,18 +219,10 @@ void RimResultDefinition::loadResult() RimReservoirCellResultsStorage* gridCellResults = this->currentGridCellResults(); if (gridCellResults) { - if (m_resultType() == RimDefines::STATIC_NATIVE && - m_resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) - { - gridCellResults->findOrLoadScalarResult(m_resultType(), "TRANX"); - gridCellResults->findOrLoadScalarResult(m_resultType(), "TRANY"); - gridCellResults->findOrLoadScalarResult(m_resultType(), "TRANZ"); - } - else - { - gridCellResults->findOrLoadScalarResult(m_resultType(), m_resultVariable); - } + gridCellResults->findOrLoadScalarResult(m_resultType(), m_resultVariable); } + + updateFieldVisibility(); } @@ -242,7 +233,7 @@ void RimResultDefinition::loadResult() bool RimResultDefinition::hasStaticResult() const { const RimReservoirCellResultsStorage* gridCellResults = this->currentGridCellResults(); - size_t gridScalarResultIndex = this->gridScalarIndex(); + size_t gridScalarResultIndex = this->scalarResultIndex(); if (hasResult() && gridCellResults->cellResults()->timeStepCount(gridScalarResultIndex) == 1 ) { @@ -285,7 +276,7 @@ bool RimResultDefinition::hasDynamicResult() const if (this->currentGridCellResults() && this->currentGridCellResults()->cellResults()) { const RigCaseCellResultsData* gridCellResults = this->currentGridCellResults()->cellResults(); - size_t gridScalarResultIndex = this->gridScalarIndex(); + size_t gridScalarResultIndex = this->scalarResultIndex(); if (gridCellResults->timeStepCount(gridScalarResultIndex) > 1 ) { return true; @@ -312,6 +303,8 @@ void RimResultDefinition::initAfterRead() m_porosityModelUiField = m_porosityModel; m_resultTypeUiField = m_resultType; m_resultVariableUiField = m_resultVariable; + + this->updateUiIconFromToggleField(); } //-------------------------------------------------------------------------------------------------- @@ -344,18 +337,32 @@ void RimResultDefinition::setResultVariable(const QString& val) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimResultDefinition::setPorosityModelUiFieldHidden(bool hide) +bool RimResultDefinition::isTernarySaturationSelected() const { - m_porosityModelUiField.setUiHidden(true); + bool isTernary = (m_resultType() == RimDefines::DYNAMIC_NATIVE) && + (m_resultVariable().compare(RimDefines::ternarySaturationResultName(), Qt::CaseInsensitive) == 0); + + return isTernary; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimResultDefinition::isTernarySaturationSelected() const +void RimResultDefinition::updateFieldVisibility() { - bool isTernary = (m_resultType() == RimDefines::DYNAMIC_NATIVE) && - (m_resultVariable().compare(RimDefines::ternarySaturationResultName(), Qt::CaseInsensitive) == 0); - - return isTernary; + if (m_reservoirView && + m_reservoirView->eclipseCase() && + m_reservoirView->eclipseCase()->reservoirData() && + m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS) ) + { + if (m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->reservoirActiveCellCount() == 0) + { + m_porosityModelUiField.setUiHidden(true); + } + else + { + m_porosityModelUiField.setUiHidden(false); + } + } } + diff --git a/ApplicationCode/ProjectDataModel/RimResultDefinition.h b/ApplicationCode/ProjectDataModel/RimResultDefinition.h index 3e7e463f7d..e3a6d3754a 100644 --- a/ApplicationCode/ProjectDataModel/RimResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimResultDefinition.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,10 +20,11 @@ #pragma once -#include "cafPdmObject.h" +#include "RimDefines.h" + #include "cafAppEnum.h" #include "cafPdmField.h" -#include "RimDefines.h" +#include "cafPdmObject.h" #include "cafPdmPointer.h" @@ -48,10 +51,9 @@ class RimResultDefinition : public caf::PdmObject void setPorosityModel(RimDefines::PorosityModelType val); QString resultVariable() const { return m_resultVariable(); } virtual void setResultVariable(const QString& val); - void setPorosityModelUiFieldHidden(bool hide); void loadResult(); - size_t gridScalarIndex() const; + size_t scalarResultIndex() const; bool hasStaticResult() const; bool hasDynamicResult() const; bool hasResult() const; @@ -59,8 +61,7 @@ class RimResultDefinition : public caf::PdmObject RimReservoirCellResultsStorage* currentGridCellResults() const; - - virtual QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ); + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly); virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); virtual void initAfterRead(); @@ -70,15 +71,19 @@ class RimResultDefinition : public caf::PdmObject caf::PdmField m_resultVariable; friend class RimCellPropertyFilter; + friend class RimFaultResultSlot; + // User interface only fields, to support "filtering"-like behaviour etc. caf::PdmField< caf::AppEnum< RimDefines::ResultCatType > > m_resultTypeUiField; caf::PdmField< caf::AppEnum< RimDefines::PorosityModelType > > m_porosityModelUiField; caf::PdmField m_resultVariableUiField; + caf::PdmPointer m_reservoirView; - //mutable size_t m_gridScalarResultIndex; +protected: + void updateFieldVisibility(); - caf::PdmPointer m_reservoirView; + QList calculateValueOptionsForSpecifiedDerivedListPosition(bool showDerivedResultsFirstInList, const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly); private: QStringList getResultVariableListForCurrentUIFieldSettings(); diff --git a/ApplicationCode/ProjectDataModel/RimResultSlot.cpp b/ApplicationCode/ProjectDataModel/RimResultSlot.cpp index 38108eaf5f..01ea519c71 100644 --- a/ApplicationCode/ProjectDataModel/RimResultSlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultSlot.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,8 +18,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimResultSlot.h" #include "RimReservoirView.h" @@ -156,6 +156,8 @@ void RimResultSlot::initAfterRead() //-------------------------------------------------------------------------------------------------- void RimResultSlot::setReservoirView(RimReservoirView* ownerReservoirView) { + RimResultDefinition::setReservoirView(ownerReservoirView); + m_reservoirView = ownerReservoirView; this->legendConfig()->setReservoirView(ownerReservoirView); std::list >::iterator it; diff --git a/ApplicationCode/ProjectDataModel/RimResultSlot.h b/ApplicationCode/ProjectDataModel/RimResultSlot.h index afa92bb3a3..c08ebc69d4 100644 --- a/ApplicationCode/ProjectDataModel/RimResultSlot.h +++ b/ApplicationCode/ProjectDataModel/RimResultSlot.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,9 +20,6 @@ #pragma once -#include "cafAppEnum.h" -#include "cafPdmObject.h" - #include "RimDefines.h" #include "RimLegendConfig.h" #include "RimResultDefinition.h" @@ -47,6 +46,7 @@ class RimResultSlot : public RimResultDefinition virtual void setResultVariable(const QString& resultName); protected: + friend class RimFaultResultSlot; virtual void initAfterRead(); private: diff --git a/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp b/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp index 2e597e678e..eb26bf7a83 100644 --- a/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,15 +18,16 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - - #include "RimScriptCollection.h" -#include "cafPdmField.h" -#include "cafUtils.h" -#include "RiuMainWindow.h" + +#include "RimCalcScript.h" #include "RimUiTreeModelPdm.h" +#include "RiuMainWindow.h" + #include "cafPdmUiFilePathEditor.h" +#include "cafUtils.h" + +#include CAF_PDM_SOURCE_INIT(RimScriptCollection, "ScriptLocation"); diff --git a/ApplicationCode/ProjectDataModel/RimScriptCollection.h b/ApplicationCode/ProjectDataModel/RimScriptCollection.h index 0c030e9be6..2562a3c83c 100644 --- a/ApplicationCode/ProjectDataModel/RimScriptCollection.h +++ b/ApplicationCode/ProjectDataModel/RimScriptCollection.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,7 +22,8 @@ #include "cafPdmField.h" #include "cafPdmObject.h" -#include "RimCalcScript.h" + +class RimCalcScript; namespace caf { diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCase.cpp b/ApplicationCode/ProjectDataModel/RimStatisticsCase.cpp index e942b18b0d..b2a0c39f85 100644 --- a/ApplicationCode/ProjectDataModel/RimStatisticsCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCase.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,35 +18,23 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimStatisticsCase.h" -#include "RimReservoirView.h" -#include "cafPdmUiOrdering.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RigCaseData.h" + #include "RigCaseCellResultsData.h" -#include "RimStatisticsCaseEvaluator.h" -#include "RigMainGrid.h" -#include "cafPdmUiTextEditor.h" -#include "cafPdmUiLineEditor.h" -#include "cafPdmUiPushButtonEditor.h" -#include "RiuMainWindow.h" -#include "RimUiTreeModelPdm.h" -#include "cafProgressInfo.h" +#include "RigCaseData.h" #include "RimCaseCollection.h" - - -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RimReservoirCellResultsStorage.h" +#include "RimReservoirView.h" #include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" +#include "RimStatisticsCaseEvaluator.h" +#include "RimUiTreeModelPdm.h" #include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" +#include "RiuMainWindow.h" -#include "RimReservoirCellResultsCacher.h" +#include "cafPdmUiPushButtonEditor.h" +#include "cafPdmUiTextEditor.h" +#include "cafProgressInfo.h" namespace caf { template<> diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCase.h b/ApplicationCode/ProjectDataModel/RimStatisticsCase.h index f3124cf511..a225d50674 100644 --- a/ApplicationCode/ProjectDataModel/RimStatisticsCase.h +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCase.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.cpp b/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.cpp index 40daa70a63..c4563c6fdd 100644 --- a/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,23 +18,9 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - -#include "RimReservoirView.h" - #include "RimStatisticsCaseCollection.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimCaseCollection.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimIdenticalGridCaseGroup.h" CAF_PDM_SOURCE_INIT(RimStatisticsCaseCollection, "RimStatisticalCollection"); diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.h b/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.h index e7c0059363..71f5bf5228 100644 --- a/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.h +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -23,8 +25,8 @@ #include "cafPdmField.h" #include "cafPdmObject.h" -#include "RimStatisticsCase.h" - +class RimStatisticsCase; +class RimIdenticalGridCaseGroup; //================================================================================================== @@ -44,6 +46,4 @@ class RimStatisticsCaseCollection : public caf::PdmObject RimIdenticalGridCaseGroup* parentCaseGroup(); -private: - }; diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.cpp b/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.cpp index 4d8a499d8c..883d5c6d4e 100644 --- a/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.cpp +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -15,29 +17,21 @@ // for more details. // ///////////////////////////////////////////////////////////////////////////////// -//#include "RiaStdInclude.h" #include "RimStatisticsCaseEvaluator.h" + #include "RigCaseCellResultsData.h" -#include "RimReservoirView.h" -#include "RimCase.h" #include "RigCaseData.h" +#include "RigResultAccessorFactory.h" +#include "RigResultModifier.h" +#include "RigResultModifierFactory.h" #include "RigStatisticsMath.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" +#include "cafProgressInfo.h" -//#include "RigCaseData.h" #include -#include "cafProgressInfo.h" //-------------------------------------------------------------------------------------------------- /// @@ -112,7 +106,7 @@ void RimStatisticsCaseEvaluator::evaluateForResults(const QList& result RimDefines::ResultCatType resultType = resultSpecification[i].m_resType; QString resultName = resultSpecification[i].m_resVarName; - size_t activeCellCount = m_destinationCase->activeCellInfo(poroModel)->globalActiveCellCount(); + size_t activeCellCount = m_destinationCase->activeCellInfo(poroModel)->reservoirActiveCellCount(); RigCaseCellResultsData* destCellResultsData = m_destinationCase->results(poroModel); // Special handling if SOIL is asked for @@ -181,7 +175,7 @@ void RimStatisticsCaseEvaluator::evaluateForResults(const QList& result RimDefines::ResultCatType resultType = resultSpecification[resSpecIdx].m_resType; QString resultName = resultSpecification[resSpecIdx].m_resVarName; - size_t activeCellCount = m_destinationCase->activeCellInfo(poroModel)->globalActiveCellCount(); + size_t activeCellCount = m_destinationCase->activeCellInfo(poroModel)->reservoirActiveCellCount(); if (activeCellCount == 0) continue; @@ -199,24 +193,25 @@ void RimStatisticsCaseEvaluator::evaluateForResults(const QList& result // Build data access objects for source scalar results - cvf::Collection sourceDataAccessList; + cvf::Collection sourceDataAccessList; for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++) { RimCase* sourceCase = m_sourceCases.at(caseIdx); - size_t scalarResultIndex = sourceCase->results(poroModel)->findOrLoadScalarResultForTimeStep(resultType, resultName, dataAccessTimeStepIndex); + // Trigger loading of dataset + sourceCase->results(poroModel)->findOrLoadScalarResultForTimeStep(resultType, resultName, dataAccessTimeStepIndex); - cvf::ref dataAccessObject = sourceCase->reservoirData()->dataAccessObject(grid, poroModel, dataAccessTimeStepIndex, scalarResultIndex); - if (dataAccessObject.notNull()) + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(sourceCase->reservoirData(), gridIdx, poroModel, dataAccessTimeStepIndex, resultName, resultType); + if (resultAccessor.notNull()) { - sourceDataAccessList.push_back(dataAccessObject.p()); + sourceDataAccessList.push_back(resultAccessor.p()); } } // Build data access objects for destination scalar results - // Find the created result container, if any, and put its dataAccessObject into the enum indexed destination collection + // Find the created result container, if any, and put its resultAccessor into the enum indexed destination collection - cvf::Collection destinationDataAccessList; + cvf::Collection destinationDataAccessList; std::vector statisticalResultNames(STAT_PARAM_COUNT); statisticalResultNames[MIN] = createResultNameMin(resultName); @@ -231,14 +226,9 @@ void RimStatisticsCaseEvaluator::evaluateForResults(const QList& result for (size_t stIdx = 0; stIdx < statisticalResultNames.size(); ++stIdx) { size_t scalarResultIndex = destCellResultsData->findScalarResultIndex(resultType, statisticalResultNames[stIdx]); - if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) - { - destinationDataAccessList.push_back(m_destinationCase->dataAccessObject(grid, poroModel, dataAccessTimeStepIndex, scalarResultIndex).p()); - } - else - { - destinationDataAccessList.push_back(NULL); - } + + cvf::ref resultModifier = RigResultModifierFactory::createResultModifier(m_destinationCase, grid->gridIndex(), poroModel, dataAccessTimeStepIndex, scalarResultIndex); + destinationDataAccessList.push_back(resultModifier.p()); } std::vector statParams(STAT_PARAM_COUNT, HUGE_VAL); @@ -248,8 +238,8 @@ void RimStatisticsCaseEvaluator::evaluateForResults(const QList& result for (int cellIdx = 0; static_cast(cellIdx) < grid->cellCount(); cellIdx++) { - size_t globalGridCellIdx = grid->globalGridCellIndex(cellIdx); - if (m_destinationCase->activeCellInfo(poroModel)->isActive(globalGridCellIdx)) + size_t reservoirCellIndex = grid->reservoirCellIndex(cellIdx); + if (m_destinationCase->activeCellInfo(poroModel)->isActive(reservoirCellIndex)) { // Extract the cell values from each of the cases and assemble them into one vector @@ -352,25 +342,6 @@ void RimStatisticsCaseEvaluator::evaluateForResults(const QList& result } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimStatisticsCaseEvaluator::debugOutput(RimDefines::ResultCatType resultType, const QString& resultName, size_t timeStepIdx) -{ - CVF_ASSERT(m_destinationCase); - - qDebug() << resultName << "timeIdx : " << timeStepIdx; - - size_t scalarResultIndex = m_destinationCase->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(resultType, resultName); - - cvf::ref dataAccessObject = m_destinationCase->dataAccessObject(m_destinationCase->mainGrid(), RifReaderInterface::MATRIX_RESULTS, timeStepIdx, scalarResultIndex); - if (dataAccessObject.isNull()) return; - - for (size_t cellIdx = 0; cellIdx < m_globalCellCount; cellIdx++) - { - qDebug() << dataAccessObject->cellScalar(cellIdx); - } -} //-------------------------------------------------------------------------------------------------- /// @@ -379,12 +350,12 @@ RimStatisticsCaseEvaluator::RimStatisticsCaseEvaluator(const std::vector 0) { - m_globalCellCount = sourceCases[0]->reservoirData()->mainGrid()->cells().size(); + m_reservoirCellCount = sourceCases[0]->reservoirData()->mainGrid()->cells().size(); } CVF_ASSERT(m_destinationCase); diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.h b/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.h index 7c825c8b8d..7dfad6eb7b 100644 --- a/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.h +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,15 +20,12 @@ #pragma once -#include "cvfBase.h" -#include "cvfObject.h" -#include "cvfCollection.h" +#include "RimDefines.h" +#include "RimStatisticsCase.h" + #include #include -#include -#include "RimDefines.h" -#include "RimStatisticsCase.h" class RimCase; class RigCaseData; @@ -76,8 +75,6 @@ class RimStatisticsCaseEvaluator void evaluateForResults(const QList& resultSpecification); - void debugOutput(RimDefines::ResultCatType resultType, const QString& resultName, size_t timeStepIdx); - private: void addNamedResult(RigCaseCellResultsData* cellResults, RimDefines::ResultCatType resultType, const QString& resultName, size_t activeCellCount); void buildSourceMetaData(RifReaderInterface::PorosityModelResultType poroModel, RimDefines::ResultCatType resultType, const QString& resultName); @@ -88,7 +85,7 @@ class RimStatisticsCaseEvaluator std::vector m_sourceCases; std::vector m_timeStepIndices; - size_t m_globalCellCount; + size_t m_reservoirCellCount; RimStatisticsConfig m_statisticsConfig; RigCaseData* m_destinationCase; }; diff --git a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp index 4f5a9bcde6..12565042a8 100644 --- a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -25,10 +26,12 @@ #include "RimReservoirView.h" #include "RivTernarySaturationOverlayItem.h" +#include "RivTernaryScalarMapper.h" -#include #include "cvfqtUtils.h" +#include + CAF_PDM_SOURCE_INIT(RimTernaryLegendConfig, "RimTernaryLegendConfig"); @@ -93,6 +96,8 @@ RimTernaryLegendConfig::RimTernaryLegendConfig() m_localAutoMin.resize(3, 0.0); m_localAutoMax.resize(3, 1.0); + m_scalarMapper = new RivTernaryScalarMapper(cvf::Color3f::GRAY); + recreateLegend(); updateLegend(); } @@ -163,6 +168,7 @@ void RimTernaryLegendConfig::updateLegend() double swatUpper = 1.0; ternaryRanges(soilLower, soilUpper, sgasLower, sgasUpper, swatLower, swatUpper); + m_scalarMapper->setTernaryRanges(soilLower, soilUpper, sgasLower, sgasUpper); cvf::String soilRange; cvf::String sgasRange; @@ -264,12 +270,6 @@ void RimTernaryLegendConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOr if (rangeMode == USER_DEFINED) { caf::PdmUiOrdering* ternaryGroupContainer = uiOrdering.addNewGroup("Ternary "); - { - caf::PdmUiOrdering* ternaryGroup = ternaryGroupContainer->addNewGroup("SOIL"); - ternaryGroup->add(&userDefinedMinValueSoil); - ternaryGroup->add(&userDefinedMaxValueSoil); - } - { caf::PdmUiOrdering* ternaryGroup = ternaryGroupContainer->addNewGroup("SGAS"); ternaryGroup->add(&userDefinedMinValueSgas); @@ -282,6 +282,12 @@ void RimTernaryLegendConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOr ternaryGroup->add(&userDefinedMaxValueSwat); } + { + caf::PdmUiOrdering* ternaryGroup = ternaryGroupContainer->addNewGroup("SOIL"); + ternaryGroup->add(&userDefinedMinValueSoil); + ternaryGroup->add(&userDefinedMaxValueSoil); + } + ternaryGroupContainer->add(&applyLocalMinMax); ternaryGroupContainer->add(&applyGlobalMinMax); ternaryGroupContainer->add(&applyFullRangeMinMax); @@ -298,7 +304,7 @@ void RimTernaryLegendConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOr //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::OverlayItem* RimTernaryLegendConfig::legend() +RivTernarySaturationOverlayItem* RimTernaryLegendConfig::legend() { return m_legend.p(); } @@ -438,3 +444,11 @@ void RimTernaryLegendConfig::updateLabelText() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivTernaryScalarMapper* RimTernaryLegendConfig::scalarMapper() +{ + return m_scalarMapper.p(); +} + diff --git a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h index 6697441da9..12fe8f1e89 100644 --- a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -27,6 +28,7 @@ class RimReservoirView; class RivTernarySaturationOverlayItem; +class RivTernaryScalarMapper; namespace cvf { @@ -69,7 +71,9 @@ class RimTernaryLegendConfig : public caf::PdmObject void ternaryRanges(double& soilLower, double& soilUpper, double& sgasLower, double& sgasUpper, double& swatLower, double& swatUpper) const; void recreateLegend(); - cvf::OverlayItem* legend(); + + RivTernarySaturationOverlayItem* legend(); + RivTernaryScalarMapper* scalarMapper(); protected: virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); @@ -105,4 +109,5 @@ class RimTernaryLegendConfig : public caf::PdmObject caf::PdmPointer m_reservoirView; cvf::ref m_legend; + cvf::ref m_scalarMapper; }; diff --git a/ApplicationCode/ProjectDataModel/RimTools.cpp b/ApplicationCode/ProjectDataModel/RimTools.cpp index 3ab3439da0..f1fadca848 100644 --- a/ApplicationCode/ProjectDataModel/RimTools.cpp +++ b/ApplicationCode/ProjectDataModel/RimTools.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,30 +18,12 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimTools.h" -#include "RivWellPathCollectionPartMgr.h" -#include "RimProject.h" -#include "RimCase.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimScriptCollection.h" -#include "RimReservoirView.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimCaseCollection.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimWellPathCollection.h" -#include "RivWellPathPartMgr.h" -#include "RimWellPathCollection.h" -#include "RimCellRangeFilterCollection.h" -#include "RimOilField.h" -#include "RimAnalysisModels.h" #include "RiaApplication.h" +#include "RimProject.h" + +#include //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/ProjectDataModel/RimTools.h b/ApplicationCode/ProjectDataModel/RimTools.h index 0d301ff002..8dbcb7e535 100644 --- a/ApplicationCode/ProjectDataModel/RimTools.h +++ b/ApplicationCode/ProjectDataModel/RimTools.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,7 +20,7 @@ #pragma once -class RimProject; +#include class RimTools { diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp index 68ec961b7c..81a9750ead 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp +++ b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,47 +18,34 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimUiTreeModelPdm.h" -#include "RimCellRangeFilter.h" -#include "RimCellRangeFilterCollection.h" - -#include "cafPdmObject.h" -#include "RimCellPropertyFilter.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimReservoirView.h" -#include "RiuViewer.h" -#include "RimCalcScript.h" #include "RiaApplication.h" -#include "RiuMainWindow.h" -#include "RimInputProperty.h" -#include "RimInputPropertyCollection.h" -#include "cafPdmField.h" -#include "RimInputCase.h" -#include "RimStatisticsCase.h" -#include "RimResultCase.h" #include "RigGridManager.h" +#include "RimAnalysisModels.h" #include "RimCase.h" -#include "RigCaseData.h" -#include "RimMimeData.h" #include "RimCaseCollection.h" +#include "RimCellPropertyFilterCollection.h" +#include "RimCellRangeFilterCollection.h" #include "RimIdenticalGridCaseGroup.h" +#include "RimInputCase.h" +#include "RimInputProperty.h" +#include "RimInputPropertyCollection.h" +#include "RimMimeData.h" +#include "RimOilField.h" #include "RimProject.h" +#include "RimReservoirView.h" +#include "RimResultCase.h" #include "RimScriptCollection.h" +#include "RimStatisticsCase.h" +#include "RimUiTreeView.h" #include "RimWellCollection.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirCellResultsCacher.h" #include "RimWellPathCollection.h" -#include "RimOilField.h" -#include "RimAnalysisModels.h" -#include "RimUiTreeView.h" +#include "cvfAssert.h" + +#include +#include //-------------------------------------------------------------------------------------------------- @@ -623,7 +612,7 @@ RimIdenticalGridCaseGroup* RimUiTreeModelPdm::addCaseGroup(QModelIndex& inserted //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects) +void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, const caf::PdmObjectGroup& pdmObjects) { RimProject* proj = RiaApplication::instance()->project(); CVF_ASSERT(proj); @@ -651,6 +640,8 @@ void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectG mainResultCase->readGridDimensions(mainCaseGridDimensions); } + std::vector insertedCases; + // Add cases to case group for (size_t i = 0; i < typedObjects.size(); i++) { @@ -663,6 +654,22 @@ void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectG continue; } + insertedCases.push_back(rimResultReservoir); + } + + // Initialize the new objects + for (size_t i = 0; i < insertedCases.size(); i++) + { + RimResultCase* rimResultReservoir = insertedCases[i]; + caf::PdmDocument::initAfterReadTraversal(rimResultReservoir); + } + + // Load stuff + for (size_t i = 0; i < insertedCases.size(); i++) + { + RimResultCase* rimResultReservoir = insertedCases[i]; + + if (!mainResultCase) { rimResultReservoir->openEclipseGridFile(); @@ -691,7 +698,7 @@ void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectG RimAnalysisModels* analysisModels = (activeOilField) ? activeOilField->analysisModels() : NULL; if (analysisModels) analysisModels->insertCaseInCaseGroup(gridCaseGroup, rimResultReservoir); - caf::PdmObjectGroup::initAfterReadTraversal(rimResultReservoir); + caf::PdmDocument::updateUiIconStateRecursively(rimResultReservoir); { QModelIndex rootIndex = getModelIndexFromPdmObject(gridCaseGroup->caseCollection()); @@ -703,9 +710,9 @@ void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectG endInsertRows(); } - for (size_t i = 0; i < rimResultReservoir->reservoirViews.size(); i++) + for (size_t rvIdx = 0; rvIdx < rimResultReservoir->reservoirViews.size(); rvIdx++) { - RimReservoirView* riv = rimResultReservoir->reservoirViews()[i]; + RimReservoirView* riv = rimResultReservoir->reservoirViews()[rvIdx]; riv->loadDataAndUpdate(); } } @@ -730,16 +737,17 @@ void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectG RimReservoirView* rimReservoirView = typedObjects[i]; QString nameOfCopy = QString("Copy of ") + rimReservoirView->name; rimReservoirView->name = nameOfCopy; - - rimReservoirView->setEclipseCase(rimCase); - + rimCase->reservoirViews().push_back(rimReservoirView); + // Delete all wells to be able to copy/paste between cases, as the wells differ between cases rimReservoirView->wellCollection()->wells().deleteAllChildObjects(); - caf::PdmObjectGroup::initAfterReadTraversal(rimReservoirView); + caf::PdmDocument::initAfterReadTraversal(rimReservoirView); + rimReservoirView->setEclipseCase(rimCase); + + caf::PdmDocument::updateUiIconStateRecursively(rimReservoirView); rimReservoirView->loadDataAndUpdate(); - rimCase->reservoirViews().push_back(rimReservoirView); int position = static_cast(rimCase->reservoirViews().size()); beginInsertRows(collectionIndex, position, position); diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h index d3337d18fc..a5a1a07730 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h +++ b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -65,7 +67,7 @@ class RimUiTreeModelPdm : public caf::UiTreeModelPdm void addToParentAndBuildUiItems(caf::PdmUiTreeItem* parentTreeItem, int position, caf::PdmObject* pdmObject); void populateObjectGroupFromModelIndexList(const QModelIndexList& modelIndexList, caf::PdmObjectGroup* objectGroup); - void addObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects); + void addObjects(const QModelIndex& itemIndex, const caf::PdmObjectGroup& pdmObjects); void moveObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects); RimStatisticsCase* addStatisticalCalculation(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp index 690c0bdfa7..a8a4e1dd3f 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp +++ b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -59,11 +61,13 @@ #include "RimCellEdgeResultSlot.h" #include "RimWellCollection.h" #include "RimWellPathCollection.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "Rim3dOverlayInfoConfig.h" #include "RimProject.h" #include "RimOilField.h" #include "RimAnalysisModels.h" +#include "RimInputProperty.h" +#include "RigSingleWellResultsData.h" //-------------------------------------------------------------------------------------------------- @@ -538,29 +542,14 @@ void RimUiTreeView::slotExecuteScript() QString octavePath = app->octavePath(); if (!octavePath.isEmpty()) { - // http://www.gnu.org/software/octave/doc/interpreter/Command-Line-Options.html#Command-Line-Options - - // -p path - // Add path to the head of the search path for function files. The value of path specified on the command line - // will override any value of OCTAVE_PATH found in the environment, but not any commands in the system or - // user startup files that set the internal load path through one of the path functions. - - // -q - // Don't print the usual greeting and version message at startup. - - // TODO: Must rename RimCalcScript::absolutePath to absoluteFileName, as the code below is confusing // absolutePath() is a function in QFileInfo QFileInfo fi(calcScript->absolutePath()); QString octaveFunctionSearchPath = fi.absolutePath(); - QStringList arguments; + QStringList arguments = app->octaveArguments(); arguments.append("--path"); arguments << octaveFunctionSearchPath; - arguments.append("--path"); - arguments << QApplication::applicationDirPath(); - - arguments.append("-q"); arguments << calcScript->absolutePath(); RiaApplication::instance()->launchProcess(octavePath, arguments); @@ -593,29 +582,14 @@ void RimUiTreeView::slotExecuteScriptForSelectedCases() QString octavePath = app->octavePath(); if (!octavePath.isEmpty()) { - // http://www.gnu.org/software/octave/doc/interpreter/Command-Line-Options.html#Command-Line-Options - - // -p path - // Add path to the head of the search path for function files. The value of path specified on the command line - // will override any value of OCTAVE_PATH found in the environment, but not any commands in the system or - // user startup files that set the internal load path through one of the path functions. - - // -q - // Don't print the usual greeting and version message at startup. - - // TODO: Must rename RimCalcScript::absolutePath to absoluteFileName, as the code below is confusing // absolutePath() is a function in QFileInfo QFileInfo fi(calcScript->absolutePath()); QString octaveFunctionSearchPath = fi.absolutePath(); - QStringList arguments; + QStringList arguments = app->octaveArguments(); arguments.append("--path"); arguments << octaveFunctionSearchPath; - arguments.append("--path"); - arguments << QApplication::applicationDirPath(); - - arguments.append("-q"); arguments << calcScript->absolutePath(); // Get case ID from selected cases in selection model diff --git a/ApplicationCode/ProjectDataModel/RimWell.cpp b/ApplicationCode/ProjectDataModel/RimWell.cpp index 76f740cbe2..cd85659e14 100644 --- a/ApplicationCode/ProjectDataModel/RimWell.cpp +++ b/ApplicationCode/ProjectDataModel/RimWell.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,22 +18,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -//#include "RiaStdInclude.h" #include "RimWell.h" - -#include "cafAppEnum.h" -#include "cafPdmField.h" -#include "RivReservoirViewPartMgr.h" +#include "RigSingleWellResultsData.h" #include "RimReservoirView.h" #include "RimWellCollection.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmFieldCvfColor.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimCellRangeFilterCollection.h" + +#include "cvfMath.h" CAF_PDM_SOURCE_INIT(RimWell, "Well"); diff --git a/ApplicationCode/ProjectDataModel/RimWell.h b/ApplicationCode/ProjectDataModel/RimWell.h index 32e724e536..fae8c997c7 100644 --- a/ApplicationCode/ProjectDataModel/RimWell.h +++ b/ApplicationCode/ProjectDataModel/RimWell.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,11 +24,15 @@ #include "cafPdmObject.h" #include "cafPdmPointer.h" #include "cafAppEnum.h" -#include "cafPdmFieldCvfColor.h" -#include "RigSingleWellResultsData.h" +#include "cvfObject.h" +// Include to make Pdm work for cvf::Color +#include "cafPdmFieldCvfColor.h" + +class RigSingleWellResultsData; class RimReservoirView; + //================================================================================================== /// /// diff --git a/ApplicationCode/ProjectDataModel/RimWellCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellCollection.cpp index 0c9783a885..2888f6d3ea 100644 --- a/ApplicationCode/ProjectDataModel/RimWellCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellCollection.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,19 +20,13 @@ #include "RimWellCollection.h" -#include "cafAppEnum.h" -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" -#include "RimReservoirView.h" - -#include "RimResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" - -#include "Rim3dOverlayInfoConfig.h" -#include "RimCellEdgeResultSlot.h" #include "RiaApplication.h" #include "RiaPreferences.h" +#include "RigSingleWellResultsData.h" +#include "RimReservoirView.h" +#include "RimWell.h" +#include "RivReservoirViewPartMgr.h" + namespace caf { @@ -196,7 +192,7 @@ void RimWellCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField { if (&showWellLabel == changedField || &isActive == changedField) { - this->updateUiIconFromState(isActive); + this->updateUiIconFromToggleField(); if (m_reservoirView) { diff --git a/ApplicationCode/ProjectDataModel/RimWellCollection.h b/ApplicationCode/ProjectDataModel/RimWellCollection.h index 515574bf41..0bf9e7ad6e 100644 --- a/ApplicationCode/ProjectDataModel/RimWellCollection.h +++ b/ApplicationCode/ProjectDataModel/RimWellCollection.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,11 +24,14 @@ #include "cafPdmObject.h" #include "cafPdmPointer.h" #include "cafAppEnum.h" -#include -#include "RimWell.h" +// Include to make Pdm work for cvf::Color +#include "cafPdmFieldCvfColor.h" + +#include class RimReservoirView; +class RimWell; //================================================================================================== /// diff --git a/ApplicationCode/ProjectDataModel/RimWellPath.cpp b/ApplicationCode/ProjectDataModel/RimWellPath.cpp index 18e1b7bb2c..598da51516 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPath.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPath.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,37 +18,16 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - - -#include "cafAppEnum.h" -#include "cafPdmField.h" -#include "RiaApplication.h" - #include "RimWellPath.h" -#include "RimWellPathCollection.h" -#include "RimProject.h" -#include "RimCase.h" -#include "RivWellPathPartMgr.h" + #include "RifJsonEncodeDecode.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimScriptCollection.h" -#include "RimReservoirView.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimCaseCollection.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimOilField.h" -#include "RimAnalysisModels.h" - -#include -#include +#include "RimProject.h" #include "RimTools.h" +#include "RimWellPathCollection.h" +#include "RivWellPathPartMgr.h" +#include +#include CAF_PDM_SOURCE_INIT(RimWellPath, "WellPath"); diff --git a/ApplicationCode/ProjectDataModel/RimWellPath.h b/ApplicationCode/ProjectDataModel/RimWellPath.h index 4d25a145b9..928cd2fb17 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPath.h +++ b/ApplicationCode/ProjectDataModel/RimWellPath.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,7 +24,10 @@ #include "cafPdmObject.h" #include "cafPdmPointer.h" #include "cafAppEnum.h" -#include "cafPdmFieldCvfColor.h" + +// Include to make Pdm work for cvf::Color +#include "cafPdmFieldCvfColor.h" + #include "RigWellPath.h" class RimProject; diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp index 5483feee76..45fd93376c 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,34 +18,21 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - -#include "cafAppEnum.h" -#include "cafPdmFieldCvfColor.h" -#include "cafProgressInfo.h" - #include "RimWellPathCollection.h" -#include "RimWellPath.h" -#include "RivWellPathCollectionPartMgr.h" -#include "RimProject.h" -#include "RimCase.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimScriptCollection.h" -#include "RimReservoirView.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimCaseCollection.h" -#include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "RimOilField.h" -#include "RimAnalysisModels.h" -#include #include "RiaApplication.h" #include "RiaPreferences.h" +#include "RimProject.h" +#include "RimWellPath.h" +#include "RivWellPathCollectionPartMgr.h" + +#include "cafProgressInfo.h" + +#include +#include + +#include +#include namespace caf { diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.h b/ApplicationCode/ProjectDataModel/RimWellPathCollection.h index b734bd5f97..4b60c7e535 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.h +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,12 +24,20 @@ #include "cafPdmObject.h" #include "cafPdmPointer.h" #include "cafAppEnum.h" -#include -#include "RimWellPath.h" +// Include to make Pdm work for cvf::Color +#include "cafPdmFieldCvfColor.h" + +#include "cvfObject.h" + +#include class RivWellPathCollectionPartMgr; class RimWellPathAsciiFileReader; +class RimWellPath; +class RimProject; +class RigWellPath; + //================================================================================================== /// diff --git a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake index aace5df653..06835f0e32 100644 --- a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake @@ -10,7 +10,15 @@ ${CEE_CURRENT_LIST_DIR}RigCell.h ${CEE_CURRENT_LIST_DIR}RigCaseData.h ${CEE_CURRENT_LIST_DIR}RigGridBase.h ${CEE_CURRENT_LIST_DIR}RigGridManager.h -${CEE_CURRENT_LIST_DIR}RigGridScalarDataAccess.h +${CEE_CURRENT_LIST_DIR}RigResultAccessor.h +${CEE_CURRENT_LIST_DIR}RigResultAccessorFactory.h +${CEE_CURRENT_LIST_DIR}RigAllGridCellsResultAccessor.h +${CEE_CURRENT_LIST_DIR}RigActiveCellsResultAccessor.h +${CEE_CURRENT_LIST_DIR}RigCellEdgeResultAccessor.h +${CEE_CURRENT_LIST_DIR}RigCombTransResultAccessor.h +${CEE_CURRENT_LIST_DIR}RigCombMultResultAccessor.h +${CEE_CURRENT_LIST_DIR}RigResultModifier.h +${CEE_CURRENT_LIST_DIR}RigResultModifierFactory.h ${CEE_CURRENT_LIST_DIR}RigLocalGrid.h ${CEE_CURRENT_LIST_DIR}RigMainGrid.h ${CEE_CURRENT_LIST_DIR}RigReservoirBuilderMock.h @@ -22,6 +30,11 @@ ${CEE_CURRENT_LIST_DIR}RigFault.h ${CEE_CURRENT_LIST_DIR}RigNNCData.h ${CEE_CURRENT_LIST_DIR}cvfGeometryTools.h ${CEE_CURRENT_LIST_DIR}cvfGeometryTools.inl +${CEE_CURRENT_LIST_DIR}RigPipeInCellEvaluator.h +${CEE_CURRENT_LIST_DIR}RigResultAccessor2d.h +${CEE_CURRENT_LIST_DIR}RigTernaryResultAccessor2d.h +${CEE_CURRENT_LIST_DIR}RigStatisticsDataCache.h +${CEE_CURRENT_LIST_DIR}RigStatisticsCalculator.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -30,7 +43,14 @@ ${CEE_CURRENT_LIST_DIR}RigCell.cpp ${CEE_CURRENT_LIST_DIR}RigCaseData.cpp ${CEE_CURRENT_LIST_DIR}RigGridBase.cpp ${CEE_CURRENT_LIST_DIR}RigGridManager.cpp -${CEE_CURRENT_LIST_DIR}RigGridScalarDataAccess.cpp +${CEE_CURRENT_LIST_DIR}RigResultAccessor.cpp +${CEE_CURRENT_LIST_DIR}RigResultAccessorFactory.cpp +${CEE_CURRENT_LIST_DIR}RigAllGridCellsResultAccessor.cpp +${CEE_CURRENT_LIST_DIR}RigActiveCellsResultAccessor.cpp +${CEE_CURRENT_LIST_DIR}RigCellEdgeResultAccessor.cpp +${CEE_CURRENT_LIST_DIR}RigCombTransResultAccessor.cpp +${CEE_CURRENT_LIST_DIR}RigCombMultResultAccessor.cpp +${CEE_CURRENT_LIST_DIR}RigResultModifierFactory.cpp ${CEE_CURRENT_LIST_DIR}RigLocalGrid.cpp ${CEE_CURRENT_LIST_DIR}RigMainGrid.cpp ${CEE_CURRENT_LIST_DIR}RigReservoirBuilderMock.cpp @@ -41,6 +61,9 @@ ${CEE_CURRENT_LIST_DIR}RigWellPath.cpp ${CEE_CURRENT_LIST_DIR}RigFault.cpp ${CEE_CURRENT_LIST_DIR}RigNNCData.cpp ${CEE_CURRENT_LIST_DIR}cvfGeometryTools.cpp +${CEE_CURRENT_LIST_DIR}RigTernaryResultAccessor2d.cpp +${CEE_CURRENT_LIST_DIR}RigStatisticsDataCache.cpp +${CEE_CURRENT_LIST_DIR}RigStatisticsCalculator.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigActiveCellInfo-Test.cpp b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigActiveCellInfo-Test.cpp index 57e99d4ec0..526bb1f997 100644 --- a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigActiveCellInfo-Test.cpp +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigActiveCellInfo-Test.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -32,7 +34,7 @@ TEST(RigActiveCellInfo, BasicTest) RigActiveCellInfo rigActiveCellInfo; size_t globalActiveCellCount = 10; - rigActiveCellInfo.setGlobalCellCount(globalActiveCellCount); + rigActiveCellInfo.setReservoirCellCount(globalActiveCellCount); for (size_t i = 0; i < globalActiveCellCount; i++) { @@ -57,7 +59,7 @@ TEST(RigActiveCellInfo, GridCellCounts) rigActiveCellInfo.setGridActiveCellCounts(2, 2); rigActiveCellInfo.computeDerivedData(); - EXPECT_TRUE(rigActiveCellInfo.globalActiveCellCount() == 3); + EXPECT_TRUE(rigActiveCellInfo.reservoirActiveCellCount() == 3); } { @@ -68,6 +70,6 @@ TEST(RigActiveCellInfo, GridCellCounts) rigActiveCellInfo.setGridActiveCellCounts(2, 5 ); rigActiveCellInfo.computeDerivedData(); - EXPECT_TRUE(rigActiveCellInfo.globalActiveCellCount() == 12); + EXPECT_TRUE(rigActiveCellInfo.reservoirActiveCellCount() == 12); } } diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/cvfGeometryTools-Test.cpp b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/cvfGeometryTools-Test.cpp index eefc79effb..3d3eefd9be 100644 --- a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/cvfGeometryTools-Test.cpp +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/cvfGeometryTools-Test.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp index b58b17c5d4..1a27ad8c62 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -23,8 +25,8 @@ /// //-------------------------------------------------------------------------------------------------- RigActiveCellInfo::RigActiveCellInfo() - : m_globalActiveCellCount(0), - m_globalCellResultCount(0), + : m_reservoirActiveCellCount(0), + m_reservoirCellResultCount(0), m_activeCellPositionMin(cvf::Vec3d::ZERO), m_activeCellPositionMax(cvf::Vec3d::ZERO) { @@ -34,15 +36,15 @@ RigActiveCellInfo::RigActiveCellInfo() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigActiveCellInfo::setGlobalCellCount(size_t globalCellCount) +void RigActiveCellInfo::setReservoirCellCount(size_t reservoirCellCount) { - m_cellIndexToResultIndex.resize(globalCellCount, cvf::UNDEFINED_SIZE_T); + m_cellIndexToResultIndex.resize(reservoirCellCount, cvf::UNDEFINED_SIZE_T); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigActiveCellInfo::globalCellCount() const +size_t RigActiveCellInfo::reservoirCellCount() const { return m_cellIndexToResultIndex.size(); } @@ -50,53 +52,53 @@ size_t RigActiveCellInfo::globalCellCount() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigActiveCellInfo::globalCellResultCount() const +size_t RigActiveCellInfo::reservoirCellResultCount() const { - return m_globalCellResultCount; + return m_reservoirCellResultCount; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigActiveCellInfo::isActive(size_t globalCellIndex) const +bool RigActiveCellInfo::isActive(size_t reservoirCellIndex) const { if (m_cellIndexToResultIndex.size() == 0) { return true; } - CVF_TIGHT_ASSERT(globalCellIndex < m_cellIndexToResultIndex.size()); + CVF_TIGHT_ASSERT(reservoirCellIndex < m_cellIndexToResultIndex.size()); - return m_cellIndexToResultIndex[globalCellIndex] != cvf::UNDEFINED_SIZE_T; + return m_cellIndexToResultIndex[reservoirCellIndex] != cvf::UNDEFINED_SIZE_T; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigActiveCellInfo::cellResultIndex(size_t globalCellIndex) const +size_t RigActiveCellInfo::cellResultIndex(size_t reservoirCellIndex) const { if (m_cellIndexToResultIndex.size() == 0) { - return globalCellIndex; + return reservoirCellIndex; } - CVF_TIGHT_ASSERT(globalCellIndex < m_cellIndexToResultIndex.size()); + CVF_TIGHT_ASSERT(reservoirCellIndex < m_cellIndexToResultIndex.size()); - return m_cellIndexToResultIndex[globalCellIndex]; + return m_cellIndexToResultIndex[reservoirCellIndex]; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigActiveCellInfo::setCellResultIndex(size_t globalCellIndex, size_t globalCellResultIndex) +void RigActiveCellInfo::setCellResultIndex(size_t reservoirCellIndex, size_t reservoirCellResultIndex) { - CVF_TIGHT_ASSERT(globalCellResultIndex < m_cellIndexToResultIndex.size()); + CVF_TIGHT_ASSERT(reservoirCellResultIndex < m_cellIndexToResultIndex.size()); - m_cellIndexToResultIndex[globalCellIndex] = globalCellResultIndex; + m_cellIndexToResultIndex[reservoirCellIndex] = reservoirCellResultIndex; - if (globalCellResultIndex >= m_globalCellResultCount) + if (reservoirCellResultIndex >= m_reservoirCellResultCount) { - m_globalCellResultCount = globalCellResultIndex + 1; + m_reservoirCellResultCount = reservoirCellResultIndex + 1; } } @@ -123,20 +125,20 @@ void RigActiveCellInfo::setGridActiveCellCounts(size_t gridIndex, size_t activeC //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::computeDerivedData() { - m_globalActiveCellCount = 0; + m_reservoirActiveCellCount = 0; for (size_t i = 0; i < m_perGridActiveCellInfo.size(); i++) { - m_globalActiveCellCount += m_perGridActiveCellInfo[i].activeCellCount(); + m_reservoirActiveCellCount += m_perGridActiveCellInfo[i].activeCellCount(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigActiveCellInfo::globalActiveCellCount() const +size_t RigActiveCellInfo::reservoirActiveCellCount() const { - return m_globalActiveCellCount; + return m_reservoirActiveCellCount; } //-------------------------------------------------------------------------------------------------- @@ -187,7 +189,7 @@ void RigActiveCellInfo::clear() { m_perGridActiveCellInfo.clear(); m_cellIndexToResultIndex.clear(); - m_globalActiveCellCount = 0; + m_reservoirActiveCellCount = 0; m_activeCellPositionMin = cvf::Vec3st(0,0,0); m_activeCellPositionMax = cvf::Vec3st(0,0,0); m_activeCellsBoundingBox.reset(); @@ -198,7 +200,7 @@ void RigActiveCellInfo::clear() //-------------------------------------------------------------------------------------------------- bool RigActiveCellInfo::isCoarseningActive() const { - return m_globalCellResultCount != m_globalActiveCellCount; + return m_reservoirCellResultCount != m_reservoirActiveCellCount; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h index cbe11c9b8c..93c23ba12a 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -32,15 +34,15 @@ class RigActiveCellInfo : public cvf::Object public: RigActiveCellInfo(); - void setGlobalCellCount(size_t globalCellCount); - size_t globalCellCount() const; - size_t globalActiveCellCount() const; - size_t globalCellResultCount() const; + void setReservoirCellCount(size_t reservoirCellCount); + size_t reservoirCellCount() const; + size_t reservoirActiveCellCount() const; + size_t reservoirCellResultCount() const; bool isCoarseningActive() const; - bool isActive(size_t globalCellIndex) const; - size_t cellResultIndex(size_t globalCellIndex) const; - void setCellResultIndex(size_t globalCellIndex, size_t globalResultCellIndex); + bool isActive(size_t reservoirCellIndex) const; + size_t cellResultIndex(size_t reservoirCellIndex) const; + void setCellResultIndex(size_t reservoirCellIndex, size_t globalResultCellIndex); void setGridCount(size_t gridCount); void setGridActiveCellCounts(size_t gridIndex, size_t activeCellCount); @@ -72,8 +74,8 @@ class RigActiveCellInfo : public cvf::Object std::vector m_cellIndexToResultIndex; - size_t m_globalActiveCellCount; - size_t m_globalCellResultCount; + size_t m_reservoirActiveCellCount; + size_t m_reservoirCellResultCount; cvf::Vec3st m_activeCellPositionMin; cvf::Vec3st m_activeCellPositionMax; diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.cpp new file mode 100644 index 0000000000..a2267e84aa --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.cpp @@ -0,0 +1,59 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigActiveCellsResultAccessor.h" + +#include "RigGridBase.h" +#include "RigActiveCellInfo.h" + +#include + + +RigActiveCellsResultAccessor::RigActiveCellsResultAccessor(const RigGridBase* grid, std::vector* reservoirResultValues, const RigActiveCellInfo* activeCellInfo) + : m_grid(grid), + m_reservoirResultValues(reservoirResultValues), + m_activeCellInfo(activeCellInfo) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigActiveCellsResultAccessor::cellScalar(size_t gridLocalCellIndex) const +{ + if (m_reservoirResultValues == NULL || m_reservoirResultValues->size() == 0 ) return HUGE_VAL; + + size_t reservoirCellIndex = m_grid->reservoirCellIndex(gridLocalCellIndex); + size_t resultValueIndex = m_activeCellInfo->cellResultIndex(reservoirCellIndex); + if (resultValueIndex == cvf::UNDEFINED_SIZE_T) return HUGE_VAL; + + CVF_TIGHT_ASSERT(resultValueIndex < m_reservoirResultValues->size()); + + return m_reservoirResultValues->at(resultValueIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigActiveCellsResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + return cellScalar(gridLocalCellIndex); +} + diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h new file mode 100644 index 0000000000..e9fa9b1c0c --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigResultAccessor.h" + +class RigGridBase; +class RigActiveCellInfo; + + +//================================================================================================== +/// +//================================================================================================== +class RigActiveCellsResultAccessor : public RigResultAccessor +{ +public: + RigActiveCellsResultAccessor(const RigGridBase* grid, std::vector* reservoirResultValues, const RigActiveCellInfo* activeCellInfo); + + virtual double cellScalar(size_t gridLocalCellIndex) const; + virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + +private: + const RigActiveCellInfo* m_activeCellInfo; + const RigGridBase* m_grid; + std::vector* m_reservoirResultValues; +}; + diff --git a/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.cpp new file mode 100644 index 0000000000..71e360ceb4 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.cpp @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigAllGridCellsResultAccessor.h" + +#include "RigGridBase.h" + +#include + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigAllGridCellsResultAccessor::RigAllGridCellsResultAccessor(const RigGridBase* grid, std::vector* reservoirResultValues) + : m_grid(grid), + m_reservoirResultValues(reservoirResultValues) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigAllGridCellsResultAccessor::cellScalar(size_t gridLocalCellIndex) const +{ + if (m_reservoirResultValues->size() == 0 ) return HUGE_VAL; + + size_t reservoirCellIndex = m_grid->reservoirCellIndex(gridLocalCellIndex); + CVF_TIGHT_ASSERT(reservoirCellIndex < m_reservoirResultValues->size()); + + return m_reservoirResultValues->at(reservoirCellIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigAllGridCellsResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + return cellScalar(gridLocalCellIndex); +} + diff --git a/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.h new file mode 100644 index 0000000000..4c347a555b --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigActiveCellsResultAccessor.h" + +class RigGridBase; + + +//================================================================================================== +/// +//================================================================================================== +class RigAllGridCellsResultAccessor : public RigResultAccessor +{ +public: + RigAllGridCellsResultAccessor(const RigGridBase* grid, std::vector* reservoirResultValues); + + virtual double cellScalar(size_t gridLocalCellIndex) const; + virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + +private: + const RigGridBase* m_grid; + std::vector* m_reservoirResultValues; +}; + + diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp index ea168688b6..cbe1826d8b 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,10 +19,11 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RigCaseCellResultsData.h" -#include "RifReaderInterface.h" -#include "RigMainGrid.h" +#include "RigMainGrid.h" +#include "RigStatisticsDataCache.h" #include "RigStatisticsMath.h" +#include "RigStatisticsCalculator.h" #include #include @@ -33,11 +36,8 @@ RigCaseCellResultsData::RigCaseCellResultsData(RigMainGrid* ownerGrid) { CVF_ASSERT(ownerGrid != NULL); m_ownerMainGrid = ownerGrid; - - m_combinedTransmissibilityResultIndex = cvf::UNDEFINED_SIZE_T; } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -49,39 +49,9 @@ void RigCaseCellResultsData::setMainGrid(RigMainGrid* ownerGrid) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigCaseCellResultsData::minMaxCellScalarValues( size_t scalarResultIndex, double& min, double& max ) +void RigCaseCellResultsData::minMaxCellScalarValues(size_t scalarResultIndex, double& min, double& max) { - min = HUGE_VAL; - max = -HUGE_VAL; - - CVF_ASSERT(scalarResultIndex < resultCount()); - - // Extend array and cache vars - - if (scalarResultIndex >= m_maxMinValues.size() ) - { - m_maxMinValues.resize(scalarResultIndex+1, std::make_pair(HUGE_VAL, -HUGE_VAL)); - } - - if (m_maxMinValues[scalarResultIndex].first != HUGE_VAL) - { - min = m_maxMinValues[scalarResultIndex].first; - max = m_maxMinValues[scalarResultIndex].second; - - return; - } - - size_t i; - for (i = 0; i < timeStepCount(scalarResultIndex); i++) - { - double tsmin, tsmax; - minMaxCellScalarValues(scalarResultIndex, i, tsmin, tsmax); - if (tsmin < min) min = tsmin; - if (tsmax > max) max = tsmax; - } - - m_maxMinValues[scalarResultIndex].first = min; - m_maxMinValues[scalarResultIndex].second= max; + m_statisticsDataCache[scalarResultIndex]->minMaxCellScalarValues(min, max); } //-------------------------------------------------------------------------------------------------- @@ -89,80 +59,23 @@ void RigCaseCellResultsData::minMaxCellScalarValues( size_t scalarResultIndex, d //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max) { - min = HUGE_VAL; - max = -HUGE_VAL; - - CVF_ASSERT(scalarResultIndex < resultCount()); - - if (timeStepIndex >= m_cellScalarResults[scalarResultIndex].size()) - { - return; - } - - if (scalarResultIndex >= m_maxMinValuesPrTs.size()) - { - m_maxMinValuesPrTs.resize(scalarResultIndex+1); - } - - if (timeStepIndex >= m_maxMinValuesPrTs[scalarResultIndex].size()) - { - m_maxMinValuesPrTs[scalarResultIndex].resize(timeStepIndex+1, std::make_pair(HUGE_VAL, -HUGE_VAL)); - } - - if (m_maxMinValuesPrTs[scalarResultIndex][timeStepIndex].first != HUGE_VAL) - { - min = m_maxMinValuesPrTs[scalarResultIndex][timeStepIndex].first; - max = m_maxMinValuesPrTs[scalarResultIndex][timeStepIndex].second; - - return; - } - - if (scalarResultIndex == m_combinedTransmissibilityResultIndex) - { - size_t tranX, tranY, tranZ; - if (!findTransmissibilityResults(tranX, tranY, tranZ)) return; - - double tranMin; - double tranMax; - - minMaxCellScalarValues(tranX, timeStepIndex, tranMin, tranMax); - min = CVF_MIN(tranMin, min); - max = CVF_MAX(tranMax, max); - - minMaxCellScalarValues(tranY, timeStepIndex, tranMin, tranMax); - min = CVF_MIN(tranMin, min); - max = CVF_MAX(tranMax, max); - - minMaxCellScalarValues(tranZ, timeStepIndex, tranMin, tranMax); - min = CVF_MIN(tranMin, min); - max = CVF_MAX(tranMax, max); - - return; - } - - std::vector& values = m_cellScalarResults[scalarResultIndex][timeStepIndex]; - - size_t i; - for (i = 0; i < values.size(); i++) - { - if (values[i] == HUGE_VAL) - { - continue; - } - - if (values[i] < min) - { - min = values[i]; - } + m_statisticsDataCache[scalarResultIndex]->minMaxCellScalarValues(timeStepIndex, min, max); +} - if (values[i] > max) - { - max = values[i]; - } - } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, double& pos, double& neg) +{ + m_statisticsDataCache[scalarResultIndex]->posNegClosestToZero(pos, neg); +} - m_maxMinValuesPrTs[scalarResultIndex][timeStepIndex].first = min; - m_maxMinValuesPrTs[scalarResultIndex][timeStepIndex].second= max; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, size_t timeStepIndex, double& pos, double& neg) +{ + m_statisticsDataCache[scalarResultIndex]->posNegClosestToZero(timeStepIndex, pos, neg); } //-------------------------------------------------------------------------------------------------- @@ -170,68 +83,15 @@ void RigCaseCellResultsData::minMaxCellScalarValues(size_t scalarResultIndex, si //-------------------------------------------------------------------------------------------------- const std::vector& RigCaseCellResultsData::cellScalarValuesHistogram(size_t scalarResultIndex) { - CVF_ASSERT(scalarResultIndex < resultCount()); - - // Extend array and cache vars - - if (scalarResultIndex >= m_histograms.size() ) - { - m_histograms.resize(resultCount()); - m_p10p90.resize(resultCount(), std::make_pair(HUGE_VAL, HUGE_VAL)); - } - - if (m_histograms[scalarResultIndex].size()) - { - return m_histograms[scalarResultIndex]; - - } - - double min; - double max; - size_t nBins = 100; - this->minMaxCellScalarValues( scalarResultIndex, min, max ); - RigHistogramCalculator histCalc(min, max, nBins, &m_histograms[scalarResultIndex]); - - if (scalarResultIndex == m_combinedTransmissibilityResultIndex) - { - size_t tranX, tranY, tranZ; - if (findTransmissibilityResults(tranX, tranY, tranZ)) - { - for (size_t tsIdx = 0; tsIdx < this->timeStepCount(scalarResultIndex); tsIdx++) - { - histCalc.addData(m_cellScalarResults[tranX][tsIdx]); - histCalc.addData(m_cellScalarResults[tranY][tsIdx]); - histCalc.addData(m_cellScalarResults[tranZ][tsIdx]); - } - } - } - else - { - for (size_t tsIdx = 0; tsIdx < this->timeStepCount(scalarResultIndex); tsIdx++) - { - std::vector& values = m_cellScalarResults[scalarResultIndex][tsIdx]; - - histCalc.addData(values); - } - } - - m_p10p90[scalarResultIndex].first = histCalc.calculatePercentil(0.1); - m_p10p90[scalarResultIndex].second = histCalc.calculatePercentil(0.9); - - return m_histograms[scalarResultIndex]; + return m_statisticsDataCache[scalarResultIndex]->cellScalarValuesHistogram(); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90) { - // First make sure they are calculated - const std::vector& histogr = cellScalarValuesHistogram( scalarResultIndex); - // Then return them - p10 = m_p10p90[scalarResultIndex].first; - p90 = m_p10p90[scalarResultIndex].second; + m_statisticsDataCache[scalarResultIndex]->p10p90CellScalarValues(p10, p90); } //-------------------------------------------------------------------------------------------------- @@ -239,73 +99,7 @@ void RigCaseCellResultsData::p10p90CellScalarValues(size_t scalarResultIndex, do //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::meanCellScalarValues(size_t scalarResultIndex, double& meanValue) { - CVF_ASSERT(scalarResultIndex < resultCount()); - - // Extend array and cache vars - - if (scalarResultIndex >= m_meanValues.size() ) - { - m_meanValues.resize(scalarResultIndex+1, HUGE_VAL); - } - - if (m_meanValues[scalarResultIndex] != HUGE_VAL) - { - meanValue = m_meanValues[scalarResultIndex]; - return; - } - - double valueSum = 0.0; - size_t count = 0; - - if (scalarResultIndex == m_combinedTransmissibilityResultIndex) - { - size_t tranX, tranY, tranZ; - if (findTransmissibilityResults(tranX, tranY, tranZ)) - { - for (size_t tIdx = 0; tIdx < timeStepCount(tranX); tIdx++) - { - { - std::vector& values = m_cellScalarResults[tranX][tIdx]; - for (size_t cIdx = 0; cIdx < values.size(); ++cIdx) - { - valueSum += values[cIdx]; - } - count += values.size(); - } - { - std::vector& values = m_cellScalarResults[tranY][tIdx]; - for (size_t cIdx = 0; cIdx < values.size(); ++cIdx) - { - valueSum += values[cIdx]; - } - count += values.size(); - } - { - std::vector& values = m_cellScalarResults[tranZ][tIdx]; - for (size_t cIdx = 0; cIdx < values.size(); ++cIdx) - { - valueSum += values[cIdx]; - } - count += values.size(); - } - } - } - } - else - { - for (size_t tIdx = 0; tIdx < timeStepCount(scalarResultIndex); tIdx++) - { - std::vector& values = m_cellScalarResults[scalarResultIndex][tIdx]; - for (size_t cIdx = 0; cIdx < values.size(); ++cIdx) - { - valueSum += values[cIdx]; - } - count += values.size(); - } - } - - m_meanValues[scalarResultIndex] = valueSum/count; - meanValue = m_meanValues[scalarResultIndex]; + m_statisticsDataCache[scalarResultIndex]->meanCellScalarValues(meanValue); } //-------------------------------------------------------------------------------------------------- @@ -422,21 +216,87 @@ size_t RigCaseCellResultsData::findScalarResultIndex(const QString& resultName) //-------------------------------------------------------------------------------------------------- /// Adds an empty scalar set, and returns the scalarResultIndex to it. -/// if resultName already exists, it returns the scalarResultIndex to the existing result. +/// if resultName already exists, it just returns the scalarResultIndex to the existing result. //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::addEmptyScalarResult(RimDefines::ResultCatType type, const QString& resultName, bool needsToBeStored) { - size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; + size_t scalarResultIndex = this->findScalarResultIndex(type, resultName); - scalarResultIndex = this->findScalarResultIndex(type, resultName); - if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) + // If the result exists, do nothing + + if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) + { + return scalarResultIndex; + } + + // Create the new empty result with metadata + + scalarResultIndex = this->resultCount(); + m_cellScalarResults.push_back(std::vector >()); + ResultInfo resInfo(type, needsToBeStored, false, resultName, scalarResultIndex); + m_resultInfos.push_back(resInfo); + + // Create statistics calculator and add statistics cache object + // Todo: Move to a "factory" method + + cvf::ref statisticsCalculator; + + if (resultName == RimDefines::combinedTransmissibilityResultName()) + { + cvf::ref calc = new RigMultipleDatasetStatCalc(); + + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANX")); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANY")); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANZ")); + + statisticsCalculator = calc; + } + else if (resultName == RimDefines::combinedMultResultName()) + { + cvf::ref calc = new RigMultipleDatasetStatCalc(); + + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "MULTX")); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "MULTX-")); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "MULTY")); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "MULTY-")); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "MULTZ")); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, "MULTZ-")); + + statisticsCalculator = calc; + } + else if (resultName == RimDefines::combinedRiTranResultName()) + { + cvf::ref calc = new RigMultipleDatasetStatCalc(); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riTranXResultName())); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riTranYResultName())); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riTranZResultName())); + statisticsCalculator = calc; + } + else if (resultName == RimDefines::combinedRiMultResultName()) + { + cvf::ref calc = new RigMultipleDatasetStatCalc(); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riMultXResultName())); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riMultYResultName())); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riMultZResultName())); + statisticsCalculator = calc; + } + else if (resultName == RimDefines::combinedRiAreaNormTranResultName()) + { + cvf::ref calc = new RigMultipleDatasetStatCalc(); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riAreaNormTranXResultName())); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riAreaNormTranYResultName())); + calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riAreaNormTranZResultName())); + statisticsCalculator = calc; + } + else { - scalarResultIndex = this->resultCount(); - m_cellScalarResults.push_back(std::vector >()); - ResultInfo resInfo(type, needsToBeStored, false, resultName, scalarResultIndex); - m_resultInfos.push_back(resInfo); + statisticsCalculator = new RigNativeStatCalc(this, scalarResultIndex); } + cvf::ref dataCache = new RigStatisticsDataCache(statisticsCalculator.p()); + m_statisticsDataCache.push_back(dataCache.p()); + + return scalarResultIndex; } @@ -460,20 +320,9 @@ QStringList RigCaseCellResultsData::resultNames(RimDefines::ResultCatType resTyp //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigCaseCellResultsData::recalculateMinMax(size_t scalarResultIndex) +void RigCaseCellResultsData::recalculateStatistics(size_t scalarResultIndex) { - // Make sure cached max min values are recalculated next time asked for, since - // the data could be changed. - - if (scalarResultIndex < m_maxMinValues.size()) - { - m_maxMinValues[scalarResultIndex] = std::make_pair(HUGE_VAL, -HUGE_VAL); - } - - if (scalarResultIndex < m_maxMinValuesPrTs.size()) - { - m_maxMinValuesPrTs[scalarResultIndex].clear(); - } + m_statisticsDataCache[scalarResultIndex]->clearAllStatistics(); } //-------------------------------------------------------------------------------------------------- @@ -592,15 +441,9 @@ void RigCaseCellResultsData::removeResult(const QString& resultName) void RigCaseCellResultsData::clearAllResults() { m_cellScalarResults.clear(); - m_maxMinValues.clear(); - m_histograms.clear(); - m_p10p90.clear(); - m_meanValues.clear(); - m_maxMinValuesPrTs.clear(); m_resultInfos.clear(); } - //-------------------------------------------------------------------------------------------------- /// Removes all the actual numbers put into this object, and frees up the memory. /// Does not touch the metadata in any way @@ -619,13 +462,14 @@ void RigCaseCellResultsData::freeAllocatedResultsData() } //-------------------------------------------------------------------------------------------------- -/// Add a result with given type and name, and allocate one result vector for the static result values +/// Make sure we have a result with given type and name, and make sure one "timestep" result vector +// for the static result values are allocated //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::addStaticScalarResult(RimDefines::ResultCatType type, const QString& resultName, bool needsToBeStored, size_t resultValueCount) { size_t resultIdx = addEmptyScalarResult(type, resultName, needsToBeStored); - m_cellScalarResults[resultIdx].push_back(std::vector()); + m_cellScalarResults[resultIdx].resize(1, std::vector()); m_cellScalarResults[resultIdx][0].resize(resultValueCount, HUGE_VAL); return resultIdx; @@ -676,132 +520,90 @@ void RigCaseCellResultsData::setMustBeCalculated(size_t scalarResultIndex) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, double& pos, double& neg) +void RigCaseCellResultsData::createPlaceholderResultEntries() { - pos = HUGE_VAL; - neg = -HUGE_VAL; - - CVF_ASSERT(scalarResultIndex < resultCount()); - - // Extend array and cache vars - - if (scalarResultIndex >= m_posNegClosestToZero.size() ) - { - m_posNegClosestToZero.resize(scalarResultIndex+1, std::make_pair(HUGE_VAL, -HUGE_VAL)); - } - - if (m_posNegClosestToZero[scalarResultIndex].first != HUGE_VAL) + // SOIL { - pos = m_posNegClosestToZero[scalarResultIndex].first; - neg = m_posNegClosestToZero[scalarResultIndex].second; - - return; - } - - size_t i; - for (i = 0; i < timeStepCount(scalarResultIndex); i++) - { - double tsNeg, tsPos; - posNegClosestToZero(scalarResultIndex, i, tsPos, tsNeg); - if (tsNeg > neg && tsNeg < 0) neg = tsNeg; - if (tsPos < pos && tsPos > 0) pos = tsPos; - } - - m_posNegClosestToZero[scalarResultIndex].first = pos; - m_posNegClosestToZero[scalarResultIndex].second= neg; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, size_t timeStepIndex, double& pos, double& neg) -{ - pos = HUGE_VAL; - neg = -HUGE_VAL; - - CVF_ASSERT(scalarResultIndex < resultCount()); + size_t soilIndex = findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "SOIL"); + if (soilIndex == cvf::UNDEFINED_SIZE_T) + { + size_t swatIndex = findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "SWAT"); + size_t sgasIndex = findScalarResultIndex(RimDefines::DYNAMIC_NATIVE, "SGAS"); - if (timeStepIndex >= m_cellScalarResults[scalarResultIndex].size()) - { - return; + if (swatIndex != cvf::UNDEFINED_SIZE_T || sgasIndex != cvf::UNDEFINED_SIZE_T) + { + soilIndex = addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL", false); + this->setMustBeCalculated(soilIndex); + } + } } - if (scalarResultIndex >= m_posNegClosestToZeroPrTs.size()) + // TRANSXYZ { - m_posNegClosestToZeroPrTs.resize(scalarResultIndex+1); + size_t tranX, tranY, tranZ; + if (findTransmissibilityResults(tranX, tranY, tranZ)) + { + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::combinedTransmissibilityResultName(), false, 0); + } } - - if (timeStepIndex >= m_posNegClosestToZeroPrTs[scalarResultIndex].size()) + // MULTXYZ { - m_posNegClosestToZeroPrTs[scalarResultIndex].resize(timeStepIndex+1, std::make_pair(HUGE_VAL, -HUGE_VAL)); + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::combinedMultResultName(), false, 0); } - if (m_posNegClosestToZeroPrTs[scalarResultIndex][timeStepIndex].first != HUGE_VAL) + // riTRANSXYZ and X,Y,Z { - pos = m_posNegClosestToZeroPrTs[scalarResultIndex][timeStepIndex].first; - neg = m_posNegClosestToZeroPrTs[scalarResultIndex][timeStepIndex].second; - - return; + size_t ntgResIdx = findScalarResultIndex(RimDefines::STATIC_NATIVE, "NTG"); + if ( findScalarResultIndex(RimDefines::STATIC_NATIVE, "NTG") != cvf::UNDEFINED_SIZE_T + && findScalarResultIndex(RimDefines::STATIC_NATIVE, "PERMX") != cvf::UNDEFINED_SIZE_T + && findScalarResultIndex(RimDefines::STATIC_NATIVE, "PERMY") != cvf::UNDEFINED_SIZE_T + && findScalarResultIndex(RimDefines::STATIC_NATIVE, "PERMZ") != cvf::UNDEFINED_SIZE_T) + { + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riTranXResultName(), false, 0); + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riTranYResultName(), false, 0); + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riTranZResultName(), false, 0); + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::combinedRiTranResultName(), false, 0); + } } - if (scalarResultIndex == m_combinedTransmissibilityResultIndex) + // riMULTXYZ and X, Y, Z { size_t tranX, tranY, tranZ; - if (findTransmissibilityResults(tranX, tranY, tranZ)) + if (findTransmissibilityResults(tranX, tranY, tranZ) + && findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riTranXResultName()) != cvf::UNDEFINED_SIZE_T + && findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riTranYResultName()) != cvf::UNDEFINED_SIZE_T + && findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::riTranZResultName()) != cvf::UNDEFINED_SIZE_T) { - double traPos, traNeg; - posNegClosestToZero(tranX, timeStepIndex, traPos, traNeg); - if ( 0 < traPos && traPos < pos ) pos = traPos; - if ( neg < traNeg && traNeg < 0 ) neg = traNeg; - posNegClosestToZero(tranY, timeStepIndex, traPos, traNeg); - if ( 0 < traPos && traPos < pos ) pos = traPos; - if ( neg < traNeg && traNeg < 0 ) neg = traNeg; - posNegClosestToZero(tranZ, timeStepIndex, traPos, traNeg); - if ( 0 < traPos && traPos < pos ) pos = traPos; - if ( neg < traNeg && traNeg < 0 ) neg = traNeg; + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riMultXResultName(), false, 0); + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riMultYResultName(), false, 0); + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riMultZResultName(), false, 0); + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::combinedRiMultResultName(), false, 0); } - - return; } - std::vector& values = m_cellScalarResults[scalarResultIndex][timeStepIndex]; - - size_t i; - for (i = 0; i < values.size(); i++) + // riTRANSXYZbyArea and X, Y, Z { - if (values[i] == HUGE_VAL) + if (findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANX") != cvf::UNDEFINED_SIZE_T) { - continue; + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riAreaNormTranXResultName(), false, 0); } - if (values[i] < pos && values[i] > 0) + if (findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANY") != cvf::UNDEFINED_SIZE_T) { - pos = values[i]; + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riAreaNormTranYResultName(), false, 0); } - if (values[i] > neg && values[i] < 0) + if (findScalarResultIndex(RimDefines::STATIC_NATIVE, "TRANZ") != cvf::UNDEFINED_SIZE_T) { - neg = values[i]; + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::riAreaNormTranZResultName(), false, 0); } - } - - m_posNegClosestToZeroPrTs[scalarResultIndex][timeStepIndex].first = pos; - m_posNegClosestToZeroPrTs[scalarResultIndex][timeStepIndex].second= neg; -} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigCaseCellResultsData::createCombinedTransmissibilityResult() -{ - size_t combinedTransmissibilityIndex = findScalarResultIndex(RimDefines::STATIC_NATIVE, RimDefines::combinedTransmissibilityResultName()); - if (combinedTransmissibilityIndex != cvf::UNDEFINED_SIZE_T) return; - - size_t tranX, tranY, tranZ; - if (!findTransmissibilityResults(tranX, tranY, tranZ)) return; - - - m_combinedTransmissibilityResultIndex = addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::combinedTransmissibilityResultName(), false, 0); + size_t tranX, tranY, tranZ; + if (findTransmissibilityResults(tranX, tranY, tranZ)) + { + addStaticScalarResult(RimDefines::STATIC_NATIVE, RimDefines::combinedRiAreaNormTranResultName(), false, 0); + } + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h index ec88739efa..dc5ddf4182 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,14 +20,19 @@ #pragma once +#include "RifReaderInterface.h" + #include "RimDefines.h" + #include + #include #include -#include "RifReaderInterface.h" class RifReaderInterface; class RigMainGrid; +class RigStatisticsDataCache; +class RigActiveCellInfo; //================================================================================================== /// Class containing the results for the complete number of active cells. Both main grid and LGR's @@ -36,9 +43,12 @@ class RigCaseCellResultsData : public cvf::Object RigCaseCellResultsData(RigMainGrid* ownerGrid); void setMainGrid(RigMainGrid* ownerGrid); + void setActiveCellInfo(RigActiveCellInfo* activeCellInfo) { m_activeCellInfo = activeCellInfo;} + RigActiveCellInfo* activeCellInfo() { return m_activeCellInfo;} + const RigActiveCellInfo* activeCellInfo() const { return m_activeCellInfo;} // Max and min values of the results - void recalculateMinMax(size_t scalarResultIndex); + void recalculateStatistics(size_t scalarResultIndex); void minMaxCellScalarValues(size_t scalarResultIndex, double& min, double& max); void minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max); void posNegClosestToZero(size_t scalarResultIndex, double& pos, double& neg); @@ -66,7 +76,7 @@ class RigCaseCellResultsData : public cvf::Object size_t addEmptyScalarResult(RimDefines::ResultCatType type, const QString& resultName, bool needsToBeStored); QString makeResultNameUnique(const QString& resultNameProposal) const; - void createCombinedTransmissibilityResult(); + void createPlaceholderResultEntries(); void removeResult(const QString& resultName); void clearAllResults(); @@ -113,20 +123,12 @@ class RigCaseCellResultsData : public cvf::Object private: std::vector< std::vector< std::vector > > m_cellScalarResults; ///< Scalar results on the complete reservoir for each Result index (ResultVariable) and timestep - std::vector< std::pair > m_maxMinValues; ///< Max min values for each Result index - std::vector< std::pair > m_posNegClosestToZero; - std::vector< std::vector > m_histograms; ///< Histogram for each Result Index - std::vector< std::pair > m_p10p90; ///< P10 and p90 values for each Result Index - std::vector< double > m_meanValues; ///< Mean value for each Result Index - - std::vector< std::vector< std::pair > > m_maxMinValuesPrTs; ///< Max min values for each Result index and timestep - std::vector< std::vector< std::pair > > m_posNegClosestToZeroPrTs; - - size_t m_combinedTransmissibilityResultIndex; + cvf::Collection m_statisticsDataCache; private: std::vector m_resultInfos; RigMainGrid* m_ownerMainGrid; + RigActiveCellInfo* m_activeCellInfo; }; diff --git a/ApplicationCode/ReservoirDataModel/RigCaseData.cpp b/ApplicationCode/ReservoirDataModel/RigCaseData.cpp index c9483020e0..3b40771fc9 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseData.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -19,7 +21,7 @@ #include "RigCaseData.h" #include "RigMainGrid.h" #include "RigCaseCellResultsData.h" -#include "RigGridScalarDataAccess.h" +#include "RigResultAccessorFactory.h" //-------------------------------------------------------------------------------------------------- /// @@ -33,6 +35,11 @@ RigCaseData::RigCaseData() m_activeCellInfo = new RigActiveCellInfo; m_fractureActiveCellInfo = new RigActiveCellInfo; + + m_matrixModelResults->setActiveCellInfo(m_activeCellInfo.p()); + m_fractureModelResults->setActiveCellInfo(m_fractureActiveCellInfo.p()); + + m_unitsType = UNITS_METRIC; } //-------------------------------------------------------------------------------------------------- @@ -166,9 +173,9 @@ void RigCaseData::computeWellCellsPrGrid() if (gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size()) { - size_t globalGridCellIndex = grids[gridIndex]->globalGridCellIndex(gridCellIndex); - if (m_activeCellInfo->isActive(globalGridCellIndex) - || m_fractureActiveCellInfo->isActive(globalGridCellIndex)) + size_t reservoirCellIndex = grids[gridIndex]->reservoirCellIndex(gridCellIndex); + if (m_activeCellInfo->isActive(reservoirCellIndex) + || m_fractureActiveCellInfo->isActive(reservoirCellIndex)) { m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true); m_gridCellToWellIndex[gridIndex]->set(gridCellIndex, static_cast(wIdx)); @@ -397,10 +404,12 @@ void RigCaseData::setActiveCellInfo(RifReaderInterface::PorosityModelResultType if (porosityModel == RifReaderInterface::MATRIX_RESULTS) { m_activeCellInfo = activeCellInfo; + m_matrixModelResults->setActiveCellInfo(m_activeCellInfo.p()); } else { m_fractureActiveCellInfo = activeCellInfo; + m_fractureModelResults->setActiveCellInfo(m_fractureActiveCellInfo.p()); } } @@ -485,26 +494,6 @@ const RigCaseCellResultsData* RigCaseData::results(RifReaderInterface::PorosityM return m_fractureModelResults.p(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref RigCaseData::dataAccessObject(const RigGridBase* grid, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - size_t scalarSetIndex) -{ - if (timeStepIndex != cvf::UNDEFINED_SIZE_T && - scalarSetIndex != cvf::UNDEFINED_SIZE_T) - { - cvf::ref dataAccess = RigGridScalarDataAccessFactory::createPerGridDataAccessObject( this, grid->gridIndex(), porosityModel, timeStepIndex, scalarSetIndex); - return dataAccess; - } - - return NULL; - -} - - /* //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/ReservoirDataModel/RigCaseData.h b/ApplicationCode/ReservoirDataModel/RigCaseData.h index 2ab3432815..8b49fb29ad 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseData.h +++ b/ApplicationCode/ReservoirDataModel/RigCaseData.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -30,8 +32,16 @@ class RigCaseCellResultsData; -class RigCaseData: public cvf::Object +class RigCaseData : public cvf::Object { +public: + enum UnitsType + { + UNITS_METRIC, + UNITS_FIELD, + UNITS_LAB + }; + public: RigCaseData(); ~RigCaseData(); @@ -53,12 +63,6 @@ class RigCaseData: public cvf::Object const RigActiveCellInfo* activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel) const; void setActiveCellInfo(RifReaderInterface::PorosityModelResultType porosityModel, RigActiveCellInfo* activeCellInfo); - - cvf::ref dataAccessObject(const RigGridBase* grid, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - size_t scalarSetIndex); - void setWellResults(const cvf::Collection& data); const cvf::Collection& wellResults() { return m_wellResults; } @@ -70,6 +74,9 @@ class RigCaseData: public cvf::Object void computeActiveCellBoundingBoxes(); + UnitsType unitsType() const { return m_unitsType; } + void setUnitsType(UnitsType unitsType) { m_unitsType = unitsType; } + private: void computeActiveCellIJKBBox(); void computeWellCellsPrGrid(); @@ -86,4 +93,6 @@ class RigCaseData: public cvf::Object cvf::Collection m_wellResults; //< A WellResults object for each well in the reservoir cvf::Collection m_wellCellsInGrid; //< A bool array pr grid with one bool pr cell telling wether the cell is a well cell or not cvf::Collection m_gridCellToWellIndex; //< Array pr grid with index to well pr cell telling which well a cell is in + + UnitsType m_unitsType; }; diff --git a/ApplicationCode/ReservoirDataModel/RigCell.cpp b/ApplicationCode/ReservoirDataModel/RigCell.cpp index 5385d7150a..a4af1b32a8 100644 --- a/ApplicationCode/ReservoirDataModel/RigCell.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCell.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -41,7 +43,7 @@ RigCell::RigCell() : m_subGrid(NULL), m_hostGrid(NULL), m_isInvalid(false), - m_cellIndex(cvf::UNDEFINED_SIZE_T), + m_gridLocalCellIndex(cvf::UNDEFINED_SIZE_T), m_coarseningBoxIndex(cvf::UNDEFINED_SIZE_T) { memcpy(m_cornerIndices.data(), undefinedCornersArray, 8*sizeof(size_t)); @@ -243,16 +245,20 @@ cvf::Vec3d RigCell::faceCenter(cvf::StructGridInterface::FaceType face) const } //-------------------------------------------------------------------------------------------------- -/// +/// Returns an area vector for the cell face. The direction is the face normal, and the length is +/// equal to the face area (projected to the plane represented by the diagonal in case of warp) +/// The components of this area vector are equal to the area of the face projection onto +/// the corresponding plane. +/// See http://geomalgorithms.com/a01-_area.html //-------------------------------------------------------------------------------------------------- -cvf::Vec3d RigCell::faceNormal(cvf::StructGridInterface::FaceType face) const +cvf::Vec3d RigCell::faceNormalWithAreaLenght(cvf::StructGridInterface::FaceType face) const { cvf::ubyte faceVertexIndices[4]; cvf::StructGridInterface::cellFaceVertexIndices(face, faceVertexIndices); const std::vector& nodeCoords = m_hostGrid->mainGrid()->nodes(); - return ( nodeCoords[m_cornerIndices[faceVertexIndices[2]]] - nodeCoords[m_cornerIndices[faceVertexIndices[0]]]) ^ - ( nodeCoords[m_cornerIndices[faceVertexIndices[3]]] - nodeCoords[m_cornerIndices[faceVertexIndices[1]]]); + return 0.5*( nodeCoords[m_cornerIndices[faceVertexIndices[2]]] - nodeCoords[m_cornerIndices[faceVertexIndices[0]]]) ^ + ( nodeCoords[m_cornerIndices[faceVertexIndices[3]]] - nodeCoords[m_cornerIndices[faceVertexIndices[1]]]); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigCell.h b/ApplicationCode/ReservoirDataModel/RigCell.h index 0f5761c3ad..1cda50a286 100644 --- a/ApplicationCode/ReservoirDataModel/RigCell.h +++ b/ApplicationCode/ReservoirDataModel/RigCell.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -41,8 +43,8 @@ class RigCell bool isInvalid() const { return m_isInvalid; } void setInvalid( bool val ) { m_isInvalid = val; } - size_t cellIndex() const { return m_cellIndex; } - void setCellIndex(size_t val) { m_cellIndex = val; } + size_t gridLocalCellIndex() const { return m_gridLocalCellIndex; } + void setGridLocalCellIndex(size_t val) { m_gridLocalCellIndex = val; } RigLocalGrid* subGrid() const { return m_subGrid; } void setSubGrid(RigLocalGrid* subGrid) { m_subGrid = subGrid; } @@ -63,14 +65,14 @@ class RigCell cvf::Vec3d center() const; cvf::Vec3d faceCenter(cvf::StructGridInterface::FaceType face) const; - cvf::Vec3d faceNormal(cvf::StructGridInterface::FaceType face) const; + cvf::Vec3d faceNormalWithAreaLenght(cvf::StructGridInterface::FaceType face) const; int firstIntersectionPoint(const cvf::Ray& ray, cvf::Vec3d* intersectionPoint) const; bool isLongPyramidCell(double maxHeightFactor = 5, double nodeNearTolerance = 1e-3 ) const; private: caf::SizeTArray8 m_cornerIndices; - size_t m_cellIndex; ///< This cells index in the grid it belongs to. + size_t m_gridLocalCellIndex; ///< This cells index in the grid it belongs to. RigGridBase* m_hostGrid; RigLocalGrid* m_subGrid; diff --git a/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.cpp new file mode 100644 index 0000000000..6ed6218bb4 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.cpp @@ -0,0 +1,66 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigCellEdgeResultAccessor.h" + +#include + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCellEdgeResultAccessor::RigCellEdgeResultAccessor() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCellEdgeResultAccessor::setDataAccessObjectForFace(cvf::StructGridInterface::FaceType faceId, RigResultAccessor* resultAccessObject) +{ + m_resultAccessObjects[faceId] = resultAccessObject; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCellEdgeResultAccessor::cellScalar(size_t gridLocalCellIndex) const +{ + + // TODO: How to handle when we get here? + CVF_ASSERT(false); + + return cvf::UNDEFINED_DOUBLE; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCellEdgeResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + const RigResultAccessor* resultAccessObj = m_resultAccessObjects[faceId].p(); + if (resultAccessObj != NULL) + { + return resultAccessObj->cellFaceScalar(gridLocalCellIndex, faceId); + } + + return HUGE_VAL; +} + diff --git a/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.h new file mode 100644 index 0000000000..3ba5e22898 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.h @@ -0,0 +1,42 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigResultAccessor.h" + +#include "cafFixedArray.h" + + +//================================================================================================== +/// +//================================================================================================== +class RigCellEdgeResultAccessor : public RigResultAccessor +{ +public: + RigCellEdgeResultAccessor(); + + void setDataAccessObjectForFace(cvf::StructGridInterface::FaceType faceId, RigResultAccessor* resultAccessObject); + + virtual double cellScalar(size_t gridLocalCellIndex) const; + virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + +private: + caf::FixedArray, 6> m_resultAccessObjects; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.cpp new file mode 100644 index 0000000000..a06104fbf0 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.cpp @@ -0,0 +1,149 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigCombMultResultAccessor.h" + +#include "RigGridBase.h" + +#include + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCombMultResultAccessor::RigCombMultResultAccessor(const RigGridBase* grid) + : m_grid(grid) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCombMultResultAccessor::setMultResultAccessors( + RigResultAccessor* multXPosAccessor, RigResultAccessor* multXNegAccessor, + RigResultAccessor* multYPosAccessor, RigResultAccessor* multYNegAccessor, + RigResultAccessor* multZPosAccessor, RigResultAccessor* multZNegAccessor) +{ + m_multXPosAccessor = multXPosAccessor; + m_multXNegAccessor = multXNegAccessor; + m_multYPosAccessor = multYPosAccessor; + m_multYNegAccessor = multYNegAccessor; + m_multZPosAccessor = multZPosAccessor; + m_multZNegAccessor = multZNegAccessor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCombMultResultAccessor::cellScalar(size_t gridLocalCellIndex) const +{ + CVF_TIGHT_ASSERT(false); + + return HUGE_VAL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCombMultResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + size_t i, j, k, neighborGridCellIdx; + m_grid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k); + + double faceScalarThisCell = nativeMultScalar(gridLocalCellIndex, faceId); + + double faceScalarNeighborCell = 1.0; + if (m_grid->cellIJKNeighbor(i, j, k, faceId, &neighborGridCellIdx)) + { + faceScalarNeighborCell = nativeMultScalar(neighborGridCellIdx, cvf::StructGridInterface::oppositeFace(faceId)); + } + + return faceScalarThisCell * faceScalarNeighborCell; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCombMultResultAccessor::nativeMultScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + double faceScalar = 1.0; + + switch (faceId) + { + case cvf::StructGridInterface::POS_I: + { + if (m_multXPosAccessor.notNull()) + { + faceScalar = m_multXPosAccessor->cellScalar(gridLocalCellIndex); + } + break; + } + case cvf::StructGridInterface::NEG_I: + { + if (m_multXNegAccessor.notNull()) + { + faceScalar = m_multXNegAccessor->cellScalar(gridLocalCellIndex); + } + break; + } + + case cvf::StructGridInterface::POS_J: + { + if (m_multYPosAccessor.notNull()) + { + faceScalar = m_multYPosAccessor->cellScalar(gridLocalCellIndex); + } + break; + } + case cvf::StructGridInterface::NEG_J: + { + if (m_multYNegAccessor.notNull()) + { + faceScalar = m_multYNegAccessor->cellScalar(gridLocalCellIndex); + } + break; + } + + case cvf::StructGridInterface::POS_K: + { + if (m_multZPosAccessor.notNull()) + { + faceScalar = m_multZPosAccessor->cellScalar(gridLocalCellIndex); + } + break; + } + case cvf::StructGridInterface::NEG_K: + { + if (m_multZNegAccessor.notNull()) + { + faceScalar = m_multZNegAccessor->cellScalar(gridLocalCellIndex); + } + break; + } + } + + // FaceScalar with value HUGE_VAL means value outside valid IJK-range. Clamp to 1.0 as this means no change in MULT factor. + if (faceScalar == HUGE_VAL) + { + faceScalar = 1.0; + } + + return faceScalar; +} + diff --git a/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.h new file mode 100644 index 0000000000..74aa312a9c --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.h @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigResultAccessor.h" + +#include "cvfCollection.h" + +class RigGridBase; + + +//================================================================================================== +/// +//================================================================================================== +class RigCombMultResultAccessor : public RigResultAccessor +{ +public: + RigCombMultResultAccessor(const RigGridBase* grid); + + void setMultResultAccessors( + RigResultAccessor* multXPosAccessor, + RigResultAccessor* multXNegAccessor, + RigResultAccessor* multYPosAccessor, + RigResultAccessor* multYNegAccessor, + RigResultAccessor* multZPosAccessor, + RigResultAccessor* multZNegAccessor); + + virtual double cellScalar(size_t gridLocalCellIndex) const; + virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + +private: + double nativeMultScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + +private: + cvf::ref m_multXPosAccessor; + cvf::ref m_multXNegAccessor; + cvf::ref m_multYPosAccessor; + cvf::ref m_multYNegAccessor; + cvf::ref m_multZPosAccessor; + cvf::ref m_multZNegAccessor; + + const RigGridBase* m_grid; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.cpp new file mode 100644 index 0000000000..8d011f3757 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.cpp @@ -0,0 +1,139 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigCombTransResultAccessor.h" + +#include "RigGridBase.h" + +#include + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCombTransResultAccessor::RigCombTransResultAccessor(const RigGridBase* grid) + : m_grid(grid) +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// Only sensible to provide the positive values, as the negative ones will never be used. +/// The negative faces gets their value from the neighbor cell in that direction +//-------------------------------------------------------------------------------------------------- +void RigCombTransResultAccessor::setTransResultAccessors(RigResultAccessor* xTransAccessor, + RigResultAccessor* yTransAccessor, + RigResultAccessor* zTransAccessor) + +{ + m_xTransAccessor = xTransAccessor; + m_yTransAccessor = yTransAccessor; + m_zTransAccessor = zTransAccessor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCombTransResultAccessor::cellScalar(size_t gridLocalCellIndex) const +{ + CVF_TIGHT_ASSERT(false); + + return HUGE_VAL; +} +//-------------------------------------------------------------------------------------------------- +/// Get tran value from neighbor cell. Return 0.0 on active/inactive cell borders and end of grid +//-------------------------------------------------------------------------------------------------- +double RigCombTransResultAccessor::neighborCellTran(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId, const RigResultAccessor* transAccessor) const +{ + if (transAccessor != NULL) + { + size_t i, j, k, neighborGridCellIdx; + m_grid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k); + + if (m_grid->cellIJKNeighbor(i, j, k, faceId, &neighborGridCellIdx)) + { + double neighborCellValue = transAccessor->cellScalar(neighborGridCellIdx); + if (neighborCellValue == HUGE_VAL && transAccessor->cellScalar(gridLocalCellIndex) != HUGE_VAL) + { + return 0.0; + } + else + { + return neighborCellValue; + } + } + else + { + return 0.0; + } + } + return HUGE_VAL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCombTransResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + switch (faceId) + { + case cvf::StructGridInterface::POS_I: + { + if (m_xTransAccessor.notNull()) + { + return m_xTransAccessor->cellScalar(gridLocalCellIndex); + } + } + break; + case cvf::StructGridInterface::NEG_I: + { + return this->neighborCellTran(gridLocalCellIndex, cvf::StructGridInterface::NEG_I, m_xTransAccessor.p()); + } + break; + case cvf::StructGridInterface::POS_J: + { + if (m_yTransAccessor.notNull()) + { + return m_yTransAccessor->cellScalar(gridLocalCellIndex); + } + } + break; + case cvf::StructGridInterface::NEG_J: + { + return this->neighborCellTran(gridLocalCellIndex, cvf::StructGridInterface::NEG_J, m_yTransAccessor.p()); + } + break; + case cvf::StructGridInterface::POS_K: + { + if (m_zTransAccessor.notNull()) + { + return m_zTransAccessor->cellScalar(gridLocalCellIndex); + } + } + break; + case cvf::StructGridInterface::NEG_K: + { + return this->neighborCellTran(gridLocalCellIndex, cvf::StructGridInterface::NEG_K, m_zTransAccessor.p()); + } + break; + } + + return HUGE_VAL; +} + diff --git a/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.h new file mode 100644 index 0000000000..c250f0791a --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.h @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigResultAccessor.h" + +#include "cvfCollection.h" + +class RigGridBase; + + +//================================================================================================== +/// +//================================================================================================== +class RigCombTransResultAccessor : public RigResultAccessor +{ +public: + RigCombTransResultAccessor(const RigGridBase* grid); + + void setTransResultAccessors(RigResultAccessor* xTransAccessor, + RigResultAccessor* yTransAccessor, + RigResultAccessor* zTransAccessor); + + virtual double cellScalar(size_t gridLocalCellIndex) const; + virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; +private: + double neighborCellTran(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId, const RigResultAccessor* transAccessor) const; + + cvf::ref m_xTransAccessor; + cvf::ref m_yTransAccessor; + cvf::ref m_zTransAccessor; + + const RigGridBase* m_grid; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigFault.cpp b/ApplicationCode/ReservoirDataModel/RigFault.cpp index 6bfaba0dca..2b86d45bd8 100644 --- a/ApplicationCode/ReservoirDataModel/RigFault.cpp +++ b/ApplicationCode/ReservoirDataModel/RigFault.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -115,16 +116,16 @@ void RigFault::computeFaultFacesFromCellRanges(const RigMainGrid* mainGrid) } // Do not need to compute global grid cell index as for a maingrid localIndex == globalIndex - //size_t globalCellIndex = grid->globalGridCellIndex(localCellIndex); + //size_t reservoirCellIndex = grid->reservoirCellIndex(gridLocalCellIndex); size_t ni, nj, nk; mainGrid->neighborIJKAtCellFace(i, j, k, faceEnum, &ni, &nj, &nk); if (ni < mainGrid->cellCountI() && nj < mainGrid->cellCountJ() && nk < mainGrid->cellCountK()) { - size_t localCellIndex = mainGrid->cellIndexFromIJK(i, j, k); + size_t gridLocalCellIndex = mainGrid->cellIndexFromIJK(i, j, k); size_t oppositeCellIndex = mainGrid->cellIndexFromIJK(ni, nj, nk); - m_faultFaces.push_back(FaultFace(localCellIndex, faceEnum, oppositeCellIndex)); + m_faultFaces.push_back(FaultFace(gridLocalCellIndex, faceEnum, oppositeCellIndex)); } else { @@ -145,10 +146,10 @@ void RigFault::accumulateFaultsPrCell(RigFaultsPrCellAccumulator* faultsPrCellA { const FaultFace& ff = m_faultFaces[ffIdx]; - // Could detect overlapping faults here .... if (faultsPrCellAcc->faultIdx(ff.m_nativeGlobalCellIndex, ff.m_nativeFace) >= 0) + // Could detect overlapping faults here .... if (faultsPrCellAcc->faultIdx(ff.m_nativeReservoirCellIndex, ff.m_nativeFace) >= 0) - faultsPrCellAcc->setFaultIdx(ff.m_nativeGlobalCellIndex, ff.m_nativeFace, faultIdx); - faultsPrCellAcc->setFaultIdx(ff.m_oppositeGlobalCellIndex, cvf::StructGridInterface::oppositeFace(ff.m_nativeFace), faultIdx); + faultsPrCellAcc->setFaultIdx(ff.m_nativeReservoirCellIndex, ff.m_nativeFace, faultIdx); + faultsPrCellAcc->setFaultIdx(ff.m_oppositeReservoirCellIndex, cvf::StructGridInterface::oppositeFace(ff.m_nativeFace), faultIdx); } } diff --git a/ApplicationCode/ReservoirDataModel/RigFault.h b/ApplicationCode/ReservoirDataModel/RigFault.h index 39198b5feb..e259850d57 100644 --- a/ApplicationCode/ReservoirDataModel/RigFault.h +++ b/ApplicationCode/ReservoirDataModel/RigFault.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -38,22 +39,22 @@ class RigFaultsPrCellAccumulator : public cvf::Object enum { NO_FAULT = -1, UNKNOWN_FAULT = -2 }; public: - RigFaultsPrCellAccumulator(size_t globalCellCount) + RigFaultsPrCellAccumulator(size_t reservoirCellCount) { const int initVals[6] = { NO_FAULT, NO_FAULT, NO_FAULT, NO_FAULT, NO_FAULT, NO_FAULT}; caf::IntArray6 initVal; initVal = initVals; - m_faultIdxForCellFace.resize(globalCellCount, initVal); + m_faultIdxForCellFace.resize(reservoirCellCount, initVal); } - inline int faultIdx(size_t globalCellIdx, cvf::StructGridInterface::FaceType face) + inline int faultIdx(size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face) const { - return m_faultIdxForCellFace[globalCellIdx][face]; + return m_faultIdxForCellFace[reservoirCellIndex][face]; } - inline void setFaultIdx(size_t globalCellIdx, cvf::StructGridInterface::FaceType face, int faultIdx) + inline void setFaultIdx(size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face, int faultIdx) { - m_faultIdxForCellFace[globalCellIdx][face] = faultIdx; + m_faultIdxForCellFace[reservoirCellIndex][face] = faultIdx; } private: @@ -66,15 +67,15 @@ class RigFault : public cvf::Object struct FaultFace { - FaultFace(size_t nativeGlobalCellIndex, cvf::StructGridInterface::FaceType nativeFace, size_t oppositeGlobalCellIndex) : - m_nativeGlobalCellIndex(nativeGlobalCellIndex), + FaultFace(size_t nativeReservoirCellIndex, cvf::StructGridInterface::FaceType nativeFace, size_t oppositeReservoirCellIndex) : + m_nativeReservoirCellIndex(nativeReservoirCellIndex), m_nativeFace(nativeFace), - m_oppositeGlobalCellIndex(oppositeGlobalCellIndex) + m_oppositeReservoirCellIndex(oppositeReservoirCellIndex) { } - size_t m_nativeGlobalCellIndex; + size_t m_nativeReservoirCellIndex; cvf::StructGridInterface::FaceType m_nativeFace; - size_t m_oppositeGlobalCellIndex; + size_t m_oppositeReservoirCellIndex; }; public: @@ -94,9 +95,6 @@ class RigFault : public cvf::Object std::vector& connectionIndices() { return m_connectionIndices; } const std::vector& connectionIndices() const { return m_connectionIndices; } - static RigFaultsPrCellAccumulator* faultsPrCellAccumulator() { CVF_ASSERT(m_faultsPrCellAcc.notNull()); return m_faultsPrCellAcc.p();} - static void initFaultsPrCellAccumulator(size_t globalCellCount) { m_faultsPrCellAcc = new RigFaultsPrCellAccumulator(globalCellCount); } - private: QString m_name; diff --git a/ApplicationCode/ReservoirDataModel/RigGridBase.cpp b/ApplicationCode/ReservoirDataModel/RigGridBase.cpp index dc602d41ed..08b9ce84d6 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridBase.cpp +++ b/ApplicationCode/ReservoirDataModel/RigGridBase.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,7 +22,7 @@ #include "RigMainGrid.h" #include "RigCell.h" #include "RigCaseCellResultsData.h" -#include "RigGridScalarDataAccess.h" +#include "RigResultAccessorFactory.h" #include "cvfAssert.h" @@ -351,7 +353,7 @@ cvf::Vec3d RigGridBase::displayModelOffset() const //-------------------------------------------------------------------------------------------------- /// Returns the min size of the I and J charactristic cell sizes //-------------------------------------------------------------------------------------------------- -double RigGridBase::characteristicIJCellSize() +double RigGridBase::characteristicIJCellSize() const { double characteristicCellSize = HUGE_VAL; @@ -368,9 +370,9 @@ double RigGridBase::characteristicIJCellSize() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigGridBase::globalGridCellIndex(size_t localGridCellIndex) const +size_t RigGridBase::reservoirCellIndex(size_t gridLocalCellIndex) const { - return m_indexToStartOfCells + localGridCellIndex; + return m_indexToStartOfCells + gridLocalCellIndex; } //-------------------------------------------------------------------------------------------------- @@ -490,18 +492,3 @@ bool RigGridCellFaceVisibilityFilter::isFaceVisible(size_t i, size_t j, size_t k return false; } - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RigFaultFaceVisibilityFilter::isFaceVisible(size_t i, size_t j, size_t k, cvf::StructGridInterface::FaceType face, const cvf::UByteArray* cellVisibility) const -{ - size_t cellIndex = m_grid->cellIndexFromIJK(i, j, k); - if (m_grid->cell(cellIndex).isCellFaceFault(face)) - { - return true; - } - - return false; -} diff --git a/ApplicationCode/ReservoirDataModel/RigGridBase.h b/ApplicationCode/ReservoirDataModel/RigGridBase.h index cc061c18fa..7ea661d93f 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridBase.h +++ b/ApplicationCode/ReservoirDataModel/RigGridBase.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -24,7 +26,6 @@ #include "cvfBoundingBox.h" #include "cvfStructGrid.h" #include "cvfStructGridGeometryGenerator.h" -#include "cvfStructGridScalarDataAccess.h" #include "cafFixedArray.h" @@ -37,7 +38,6 @@ class RigMainGrid; class RigCell; -class RigGridScalarDataAccess; class RigActiveCellInfo; class RigGridBase : public cvf::StructGridInterface @@ -53,7 +53,7 @@ class RigGridBase : public cvf::StructGridInterface RigCell& cell(size_t gridCellIndex); const RigCell& cell(size_t gridCellIndex) const; - size_t globalGridCellIndex(size_t localGridCellIndex) const; + size_t reservoirCellIndex(size_t gridLocalCellIndex) const; void setIndexToStartOfCells(size_t indexToStartOfCells) { m_indexToStartOfCells = indexToStartOfCells; } void setGridIndex(size_t index) { m_gridIndex = index; } @@ -62,7 +62,7 @@ class RigGridBase : public cvf::StructGridInterface void setGridId(int id) { m_gridId = id; } int gridId() const { return m_gridId; } - double characteristicIJCellSize(); + double characteristicIJCellSize() const; std::string gridName() const; void setGridName(const std::string& gridName); @@ -135,17 +135,3 @@ class RigGridCellFaceVisibilityFilter : public cvf::CellFaceVisibilityFilter private: const RigGridBase* m_grid; }; - -class RigFaultFaceVisibilityFilter : public cvf::CellFaceVisibilityFilter -{ -public: - RigFaultFaceVisibilityFilter(const RigGridBase* grid) - : m_grid(grid) - { - } - - virtual bool isFaceVisible( size_t i, size_t j, size_t k, cvf::StructGridInterface::FaceType face, const cvf::UByteArray* cellVisibility ) const; - -private: - const RigGridBase* m_grid; -}; diff --git a/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp b/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp index 655e8939ae..218d8fb2f2 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp +++ b/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RigGridScalarDataAccess.h" +#include "RigResultAccessObjectFactory.h" #include "cvfLibCore.h" #include "cvfBase.h" @@ -84,10 +84,10 @@ void RigGridAllCellsScalarDataAccess::setCellScalar(size_t gridLocalCellIndex, d //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -class RigGridMatrixActiveCellsScalarDataAccess : public cvf::StructGridScalarDataAccess +class RigGridActiveCellsScalarDataAccess : public cvf::StructGridScalarDataAccess { public: - RigGridMatrixActiveCellsScalarDataAccess(const RigGridBase* grid, std::vector* reservoirResultValues, const RigActiveCellInfo* activeCellInfo) + RigGridActiveCellsScalarDataAccess(const RigGridBase* grid, std::vector* reservoirResultValues, const RigActiveCellInfo* activeCellInfo) : m_grid(grid), m_reservoirResultValues(reservoirResultValues), m_activeCellInfo(activeCellInfo) @@ -146,7 +146,7 @@ class StructGridScalarDataAccessHugeVal : public cvf::StructGridScalarDataAccess //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RigGridScalarDataAccessFactory::createPerGridDataAccessObject(RigCaseData* eclipseCase, +cvf::ref RigResultAccessObjectFactory::createNativeDataAccessObject(RigCaseData* eclipseCase, size_t gridIndex, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStepIndex, @@ -186,7 +186,7 @@ cvf::ref RigGridScalarDataAccessFactory::create bool useGlobalActiveIndex = eclipseCase->results(porosityModel)->isUsingGlobalActiveIndex(scalarSetIndex); if (useGlobalActiveIndex) { - cvf::ref object = new RigGridMatrixActiveCellsScalarDataAccess(grid, resultValues, eclipseCase->activeCellInfo(porosityModel)); + cvf::ref object = new RigGridActiveCellsScalarDataAccess(grid, resultValues, eclipseCase->activeCellInfo(porosityModel)); return object; } else diff --git a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp index 10d6ae9aaf..0e5412221f 100644 --- a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp +++ b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,6 +22,8 @@ #include "cvfAssert.h" #include "RimDefines.h" +#include "RigFault.h" + RigMainGrid::RigMainGrid(void) : RigGridBase(this) @@ -213,13 +217,12 @@ void RigMainGrid::setFaults(const cvf::Collection& faults) //-------------------------------------------------------------------------------------------------- void RigMainGrid::calculateFaults() { - //RigFault::initFaultsPrCellAccumulator(m_cells.size()); - cvf::ref faultsPrCellAcc = new RigFaultsPrCellAccumulator(m_cells.size()); + m_faultsPrCellAcc = new RigFaultsPrCellAccumulator(m_cells.size()); // Spread fault idx'es on the cells from the faults for (size_t fIdx = 0 ; fIdx < m_faults.size(); ++fIdx) { - m_faults[fIdx]->accumulateFaultsPrCell(faultsPrCellAcc.p(), static_cast(fIdx)); + m_faults[fIdx]->accumulateFaultsPrCell(m_faultsPrCellAcc.p(), static_cast(fIdx)); } // Find the geometrical faults that is in addition @@ -234,7 +237,7 @@ void RigMainGrid::calculateFaults() continue; } - size_t neighborGlobalCellIdx; + size_t neighborReservoirCellIdx; size_t neighborGridCellIdx; size_t i, j, k; RigGridBase* hostGrid = NULL; @@ -244,13 +247,13 @@ void RigMainGrid::calculateFaults() { cvf::StructGridInterface::FaceType face = cvf::StructGridInterface::FaceType(faceIdx); - if (faultsPrCellAcc->faultIdx(gcIdx, face) == RigFaultsPrCellAccumulator::NO_FAULT) + if (m_faultsPrCellAcc->faultIdx(gcIdx, face) == RigFaultsPrCellAccumulator::NO_FAULT) { // Find neighbor cell if (firstNO_FAULTFaceForCell) // To avoid doing this for every face, and only when detecting a NO_FAULT { hostGrid = m_cells[gcIdx].hostGrid(); - hostGrid->ijkFromCellIndex(m_cells[gcIdx].cellIndex(), &i,&j, &k); + hostGrid->ijkFromCellIndex(m_cells[gcIdx].gridLocalCellIndex(), &i,&j, &k); firstNO_FAULTFaceForCell = false; } @@ -259,8 +262,8 @@ void RigMainGrid::calculateFaults() continue; } - neighborGlobalCellIdx = hostGrid->globalGridCellIndex(neighborGridCellIdx); - if (m_cells[neighborGlobalCellIdx].isInvalid()) + neighborReservoirCellIdx = hostGrid->reservoirCellIndex(neighborGridCellIdx); + if (m_cells[neighborReservoirCellIdx].isInvalid()) { continue; } @@ -271,7 +274,7 @@ void RigMainGrid::calculateFaults() caf::SizeTArray4 faceIdxs; m_cells[gcIdx].faceIndices(face, &faceIdxs); caf::SizeTArray4 nbFaceIdxs; - m_cells[neighborGlobalCellIdx].faceIndices(StructGridInterface::oppositeFace(face), &nbFaceIdxs); + m_cells[neighborReservoirCellIdx].faceIndices(StructGridInterface::oppositeFace(face), &nbFaceIdxs); const std::vector& vxs = m_mainGrid->nodes(); @@ -288,18 +291,15 @@ void RigMainGrid::calculateFaults() // To avoid doing this calculation for the opposite face - faultsPrCellAcc->setFaultIdx(gcIdx, face, unNamedFaultIdx); - faultsPrCellAcc->setFaultIdx(neighborGlobalCellIdx, StructGridInterface::oppositeFace(face), unNamedFaultIdx); - - //m_cells[gcIdx].setCellFaceFault(face); - //m_cells[neighborGlobalCellIdx].setCellFaceFault(StructGridInterface::oppositeFace(face)); + m_faultsPrCellAcc->setFaultIdx(gcIdx, face, unNamedFaultIdx); + m_faultsPrCellAcc->setFaultIdx(neighborReservoirCellIdx, StructGridInterface::oppositeFace(face), unNamedFaultIdx); // Add as fault face only if the grid index is less than the neighbors - if (gcIdx < neighborGlobalCellIdx) + if (static_cast(gcIdx) < neighborReservoirCellIdx) { { - RigFault::FaultFace ff(gcIdx, cvf::StructGridInterface::FaceType(faceIdx), neighborGlobalCellIdx); + RigFault::FaultFace ff(gcIdx, cvf::StructGridInterface::FaceType(faceIdx), neighborReservoirCellIdx); unNamedFault->faultFaces().push_back(ff); } @@ -330,8 +330,8 @@ void RigMainGrid::calculateFaults() if (conn.m_c1Face != StructGridInterface::NO_FACE) { - fIdx1 = faultsPrCellAcc->faultIdx(conn.m_c1GlobIdx, conn.m_c1Face); - fIdx2 = faultsPrCellAcc->faultIdx(conn.m_c2GlobIdx, StructGridInterface::oppositeFace(conn.m_c1Face)); + fIdx1 = m_faultsPrCellAcc->faultIdx(conn.m_c1GlobIdx, conn.m_c1Face); + fIdx2 = m_faultsPrCellAcc->faultIdx(conn.m_c2GlobIdx, StructGridInterface::oppositeFace(conn.m_c1Face)); } if (fIdx1 < 0 && fIdx2 < 0) @@ -363,9 +363,79 @@ void RigMainGrid::calculateFaults() //-------------------------------------------------------------------------------------------------- /// The cell is normally inverted due to Depth becoming -Z at import, -/// but if (only) one of the flipX/Y is done, the cell is back to nomal +/// but if (only) one of the flipX/Y is done, the cell is back to normal //-------------------------------------------------------------------------------------------------- -bool RigMainGrid::faceNormalsIsOutwards() const +bool RigMainGrid::isFaceNormalsOutwards() const { - return m_flipXAxis ^ m_flipYAxis; + + for (int gcIdx = 0 ; gcIdx < static_cast(m_cells.size()); ++gcIdx) + { + if (!m_cells[gcIdx].isInvalid()) + { + cvf::Vec3d cellCenter = m_cells[gcIdx].center(); + cvf::Vec3d faceCenter = m_cells[gcIdx].faceCenter(StructGridInterface::POS_I); + cvf::Vec3d faceNormal = m_cells[gcIdx].faceNormalWithAreaLenght(StructGridInterface::POS_I); + + double typicalIJCellSize = characteristicIJCellSize(); + double dummy, dummy2, typicalKSize; + characteristicCellSizes(&dummy, &dummy2, &typicalKSize); + + if ( (faceCenter - cellCenter).length() > 0.2 * typicalIJCellSize + && (faceNormal.length() > (0.2 * typicalIJCellSize * 0.2* typicalKSize))) + { + // Cell is assumed ok to use, so calculate whether the normals are outwards or inwards + + if ((faceCenter - cellCenter) * faceNormal >= 0) + { + return true; + } + else + { + return false; + } + } + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigFault* RigMainGrid::findFaultFromCellIndexAndCellFace(size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face) const +{ + int faultIdx = m_faultsPrCellAcc->faultIdx(reservoirCellIndex, face); + if (faultIdx != RigFaultsPrCellAccumulator::NO_FAULT ) + { + return m_faults.at(faultIdx); + } + +#if 0 + for (size_t i = 0; i < m_faults.size(); i++) + { + const RigFault* rigFault = m_faults.at(i); + const std::vector& faultFaces = rigFault->faultFaces(); + + for (size_t fIdx = 0; fIdx < faultFaces.size(); fIdx++) + { + if (faultFaces[fIdx].m_nativeReservoirCellIndex == cellIndex) + { + if (face == faultFaces[fIdx].m_nativeFace ) + { + return rigFault; + } + } + + if (faultFaces[fIdx].m_oppositeReservoirCellIndex == cellIndex) + { + if (face == cvf::StructGridInterface::oppositeFace(faultFaces[fIdx].m_nativeFace)) + { + return rigFault; + } + } + } + } +#endif + return NULL; } diff --git a/ApplicationCode/ReservoirDataModel/RigMainGrid.h b/ApplicationCode/ReservoirDataModel/RigMainGrid.h index f7fc927571..f208d3f5cb 100644 --- a/ApplicationCode/ReservoirDataModel/RigMainGrid.h +++ b/ApplicationCode/ReservoirDataModel/RigMainGrid.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -51,7 +53,8 @@ class RigMainGrid : public RigGridBase void setFaults(const cvf::Collection& faults); const cvf::Collection& faults() { return m_faults; } void calculateFaults(); - bool faceNormalsIsOutwards() const; + const RigFault* findFaultFromCellIndexAndCellFace(size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face) const; + bool isFaceNormalsOutwards() const; void computeCachedData(); @@ -75,6 +78,7 @@ class RigMainGrid : public RigGridBase cvf::Collection m_faults; cvf::ref m_nncData; + cvf::ref m_faultsPrCellAcc; cvf::Vec3d m_displayModelOffset; diff --git a/ApplicationCode/ReservoirDataModel/RigNNCData.cpp b/ApplicationCode/ReservoirDataModel/RigNNCData.cpp index c5da5e45de..2b5abde1f0 100644 --- a/ApplicationCode/ReservoirDataModel/RigNNCData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigNNCData.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -50,9 +51,9 @@ void RigNNCData::processConnections(const RigMainGrid& mainGrid) if (c1.hostGrid() == c2.hostGrid()) { size_t i1, j1, k1; - c1.hostGrid()->ijkFromCellIndex(c1.cellIndex(), &i1, &j1, &k1); + c1.hostGrid()->ijkFromCellIndex(c1.gridLocalCellIndex(), &i1, &j1, &k1); size_t i2, j2, k2; - c2.hostGrid()->ijkFromCellIndex(c2.cellIndex(), &i2, &j2, &k2); + c2.hostGrid()->ijkFromCellIndex(c2.gridLocalCellIndex(), &i2, &j2, &k2); isPossibleNeighborInDirection[cvf::StructGridInterface::POS_I] = ((i1 + 1) == i2); @@ -95,7 +96,7 @@ void RigNNCData::processConnections(const RigMainGrid& mainGrid) cvf::Vec3d fc1 = c1.faceCenter((cvf::StructGridInterface::FaceType)(fIdx)); cvf::Vec3d fc2 = c2.faceCenter(cvf::StructGridInterface::oppositeFace((cvf::StructGridInterface::FaceType)(fIdx))); cvf::Vec3d fc1ToFc2 = fc2 - fc1; - normal = c1.faceNormal((cvf::StructGridInterface::FaceType)(fIdx)); + normal = c1.faceNormalWithAreaLenght((cvf::StructGridInterface::FaceType)(fIdx)); normal.normalize(); // Check that face centers are approx in the face plane if (normal.dot(fc1ToFc2) < 0.01*fc1ToFc2.length()) @@ -160,16 +161,63 @@ void RigNNCData::processConnections(const RigMainGrid& mainGrid) } } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector& RigNNCData::makeConnectionScalarResult(size_t scalarResultIndex) +{ + std::vector& results = m_connectionResults[scalarResultIndex]; + results.resize(m_connections.size(), HUGE_VAL); + return results; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector* RigNNCData::connectionScalarResult(size_t scalarResultIndex) const +{ + std::map >::const_iterator it = m_connectionResults.find(scalarResultIndex); + if (it != m_connectionResults.end()) + return &(it->second); + else + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigNNCData::setCombTransmisibilityScalarResultIndex(size_t scalarResultIndex) +{ + std::map >::iterator it = m_connectionResults.find(cvf::UNDEFINED_SIZE_T); + if (it != m_connectionResults.end()) + { + std::vector& emptyData = m_connectionResults[scalarResultIndex]; + std::vector& realData = m_connectionResults[cvf::UNDEFINED_SIZE_T]; + emptyData.swap(realData); + m_connectionResults.erase(cvf::UNDEFINED_SIZE_T); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigNNCData::hasScalarValues(size_t scalarResultIndex) +{ + std::map >::iterator it = m_connectionResults.find(scalarResultIndex); + return (it != m_connectionResults.end()); +} + /* //-------------------------------------------------------------------------------------------------- /// TODO: Possibly not needed ! //-------------------------------------------------------------------------------------------------- -const std::vector& RigNNCData::findConnectionIndices( size_t globalCellIndex, cvf::StructGridInterface::FaceType face) const +const std::vector& RigNNCData::findConnectionIndices( size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face) const { ConnectionSearchMap::const_iterator it; static std::vector empty; - it = m_cellIdxToFaceToConnectionIdxMap.find(globalCellIndex); + it = m_cellIdxToFaceToConnectionIdxMap.find(reservoirCellIndex); if (it != m_cellIdxToFaceToConnectionIdxMap.end()) { return it->second[face]; diff --git a/ApplicationCode/ReservoirDataModel/RigNNCData.h b/ApplicationCode/ReservoirDataModel/RigNNCData.h index ca4b9bf54d..d9d55439a8 100644 --- a/ApplicationCode/ReservoirDataModel/RigNNCData.h +++ b/ApplicationCode/ReservoirDataModel/RigNNCData.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -21,33 +22,36 @@ #include "cvfBase.h" #include "cvfObject.h" #include "cvfVector3.h" +#include "cvfStructGrid.h" + +#include "cafFixedArray.h" +#include // Needed for HUGE_VAL on Linux +#include #include -#include "cvfStructGrid.h" -#include "cafFixedArray.h" class RigMainGrid; - class RigConnection { public: RigConnection( ) : m_c1GlobIdx(cvf::UNDEFINED_SIZE_T), m_c1Face(cvf::StructGridInterface::NO_FACE), - m_c2GlobIdx(cvf::UNDEFINED_SIZE_T), - m_transmissibility(0.0) + m_c2GlobIdx(cvf::UNDEFINED_SIZE_T) {} + bool hasCommonArea() const + { + return m_polygon.size() > 0; + } + size_t m_c1GlobIdx; cvf::StructGridInterface::FaceType m_c1Face; size_t m_c2GlobIdx; - double m_transmissibility; - std::vector m_polygon; - }; @@ -62,11 +66,19 @@ class RigNNCData : public cvf::Object std::vector& connections() { return m_connections; } const std::vector& connections() const { return m_connections; }; + std::vector& makeConnectionScalarResult(size_t scalarResultIndex); + const std::vector* connectionScalarResult(size_t scalarResultIndex) const; + + void setCombTransmisibilityScalarResultIndex(size_t scalarResultIndex); + + bool hasScalarValues(size_t scalarResultIndex); + private: // This section is possibly not needed - //const std::vector& findConnectionIndices(size_t globalCellIndex, cvf::StructGridInterface::FaceType face) const; + //const std::vector& findConnectionIndices(size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face) const; //typedef std::map, 7 > > ConnectionSearchMap; //ConnectionSearchMap m_cellIdxToFaceToConnectionIdxMap; private: std::vector m_connections; + std::map > m_connectionResults; ///< scalarResultIndex to value array map }; diff --git a/ApplicationCode/ReservoirDataModel/RigPipeInCellEvaluator.h b/ApplicationCode/ReservoirDataModel/RigPipeInCellEvaluator.h new file mode 100644 index 0000000000..5a435ca99e --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigPipeInCellEvaluator.h @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfArray.h" + +class RigPipeInCellEvaluator: public cvf::Object +{ +public: + RigPipeInCellEvaluator(const std::vector& isWellPipeVisibleForWellIndex, + const cvf::UIntArray* gridCellToWellIndexMap) + : m_isWellPipeVisibleForWellIndex(isWellPipeVisibleForWellIndex), + m_gridCellToWellIndexMap(gridCellToWellIndexMap) + { + } + + bool isWellPipeInCell( size_t cellIndex) const + { + cvf::uint wellIndex = m_gridCellToWellIndexMap->get(cellIndex); + + if (wellIndex == cvf::UNDEFINED_UINT) + { + return false; + } + + return m_isWellPipeVisibleForWellIndex[wellIndex]; + } + +private: + + const std::vector& m_isWellPipeVisibleForWellIndex; + const cvf::UIntArray* m_gridCellToWellIndexMap; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index ec981ebc21..c245f4eeff 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -146,7 +148,7 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun RigCell& riCell = cells[cellIndexStart + i]; riCell.setHostGrid(hostGrid); - riCell.setCellIndex(i); + riCell.setGridLocalCellIndex(i); riCell.cornerIndices()[0] = nodeStartIndex + i * 8 + 0; riCell.cornerIndices()[1] = nodeStartIndex + i * 8 + 1; @@ -247,7 +249,7 @@ void RigReservoirBuilderMock::populateReservoir(RigCaseData* eclipseCase) // Set all cells active RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); - activeCellInfo->setGlobalCellCount(eclipseCase->mainGrid()->cells().size()); + activeCellInfo->setReservoirCellCount(eclipseCase->mainGrid()->cells().size()); for (size_t i = 0; i < eclipseCase->mainGrid()->cells().size(); i++) { activeCellInfo->setCellResultIndex(i, i); @@ -499,7 +501,7 @@ void RigReservoirBuilderMock::addFaults(RigCaseData* eclipseCase) if (cellDimension().x() > 5) { min.x() = cellDimension().x() / 2; - max.x() = min.x() + 1; + max.x() = min.x() + 2; } if (cellDimension().y() > 5) @@ -515,6 +517,39 @@ void RigReservoirBuilderMock::addFaults(RigCaseData* eclipseCase) } grid->setFaults(faults); + + // NNCs + std::vector& nncConnections = grid->nncData()->connections(); + { + size_t i1 = 2; + size_t j1 = 2; + size_t k1 = 3; + + size_t i2 = 2; + size_t j2 = 3; + size_t k2 = 4; + + addNnc(grid, i1, j1, k1, i2, j2, k2, nncConnections); + } + + { + size_t i1 = 2; + size_t j1 = 2; + size_t k1 = 3; + + size_t i2 = 2; + size_t j2 = 5; + size_t k2 = 4; + + addNnc(grid, i1, j1, k1, i2, j2, k2, nncConnections); + } + + std::vector& tranVals = grid->nncData()->makeConnectionScalarResult(cvf::UNDEFINED_SIZE_T); + for (size_t cIdx = 0; cIdx < tranVals.size(); ++cIdx) + { + tranVals[cIdx] = 0.2; + } + } //-------------------------------------------------------------------------------------------------- @@ -525,3 +560,18 @@ void RigReservoirBuilderMock::enableWellData(bool enableWellData) m_enableWellData = false; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigReservoirBuilderMock::addNnc(RigMainGrid* grid, size_t i1, size_t j1, size_t k1, size_t i2, size_t j2, size_t k2, std::vector &nncConnections) +{ + size_t c1GlobalIndex = grid->cellIndexFromIJK(i1, j1, k1); + size_t c2GlobalIndex = grid->cellIndexFromIJK(i2, j2, k2); + + RigConnection conn; + conn.m_c1GlobIdx = c1GlobalIndex; + conn.m_c2GlobIdx = c2GlobalIndex; + + nncConnections.push_back(conn); +} + diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h index 7076027264..37b1c786ab 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -64,6 +66,8 @@ class RigReservoirBuilderMock private: void addFaults(RigCaseData* eclipseCase); + + static void addNnc(RigMainGrid* grid, size_t i1, size_t j1, size_t k1, size_t i2, size_t j2, size_t k2, std::vector &nncConnections); void addWellData(RigCaseData* eclipseCase, RigGridBase* grid); static void appendCells(size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector& cells); diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigResultAccessor.cpp new file mode 100644 index 0000000000..7d208c2774 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessor.cpp @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigResultAccessor.h" + +#include // Needed for HUGE_VAL on Linux + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigHugeValResultAccessor::cellScalar(size_t gridLocalCellIndex) const +{ + return HUGE_VAL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigHugeValResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + return cellScalar(gridLocalCellIndex); +} diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigResultAccessor.h new file mode 100644 index 0000000000..19c0037b49 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessor.h @@ -0,0 +1,47 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfStructGrid.h" + + +//================================================================================================== +/// +//================================================================================================== +class RigResultAccessor : public cvf::Object +{ +public: + virtual double cellScalar(size_t gridLocalCellIndex) const = 0; + virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const = 0; +}; + +//================================================================================================== +/// +//================================================================================================== +class RigHugeValResultAccessor : public RigResultAccessor +{ +public: + virtual double cellScalar(size_t gridLocalCellIndex) const; + virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessor2d.h b/ApplicationCode/ReservoirDataModel/RigResultAccessor2d.h new file mode 100644 index 0000000000..2e86aa1f78 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessor2d.h @@ -0,0 +1,37 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfVector2.h" +#include "cvfStructGrid.h" + +//================================================================================================== +/// +//================================================================================================== +class RigResultAccessor2d : public cvf::Object +{ +public: + virtual cvf::Vec2d cellScalar(size_t gridLocalCellIndex) const = 0; + virtual cvf::Vec2d cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const = 0; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp new file mode 100644 index 0000000000..1986fcc3e0 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp @@ -0,0 +1,232 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigResultAccessorFactory.h" + +#include "RigActiveCellInfo.h" +#include "RigActiveCellsResultAccessor.h" +#include "RigAllGridCellsResultAccessor.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigCombMultResultAccessor.h" +#include "RigCombTransResultAccessor.h" +#include "RigGridBase.h" +#include "RigMainGrid.h" +#include "RigResultAccessor.h" + +#include "cvfAssert.h" +#include "cvfBase.h" +#include "cvfLibCore.h" +#include "cvfObject.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RigResultAccessorFactory::createResultAccessor(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName) +{ + CVF_ASSERT(gridIndex < eclipseCase->gridCount()); + CVF_ASSERT(eclipseCase); + CVF_ASSERT(eclipseCase->results(porosityModel)); + CVF_ASSERT(eclipseCase->activeCellInfo(porosityModel)); + + RigGridBase* grid = eclipseCase->grid(gridIndex); + + if (uiResultName == RimDefines::combinedTransmissibilityResultName()) + { + cvf::ref cellFaceAccessObject = new RigCombTransResultAccessor(grid); + + cvf::ref xTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANX"); + cvf::ref yTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANY"); + cvf::ref zTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANZ"); + + cellFaceAccessObject->setTransResultAccessors(xTransAccessor.p(), yTransAccessor.p(), zTransAccessor.p()); + + return cellFaceAccessObject; + } + else if (uiResultName == RimDefines::combinedMultResultName()) + { + cvf::ref cellFaceAccessObject = new RigCombMultResultAccessor(grid); + + cvf::ref multXPos = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTX"); + cvf::ref multXNeg = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTX-"); + cvf::ref multYPos = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTY"); + cvf::ref multYNeg = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTY-"); + cvf::ref multZPos = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTZ"); + cvf::ref multZNeg = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "MULTZ-"); + + cellFaceAccessObject->setMultResultAccessors(multXPos.p(), multXNeg.p(), multYPos.p(), multYNeg.p(), multZPos.p(), multZNeg.p()); + + return cellFaceAccessObject; + } + else if (uiResultName == RimDefines::combinedRiTranResultName()) + { + cvf::ref cellFaceAccessObject = new RigCombTransResultAccessor(grid); + + cvf::ref xTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riTranXResultName()); + cvf::ref yTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riTranYResultName()); + cvf::ref zTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riTranZResultName()); + + cellFaceAccessObject->setTransResultAccessors(xTransAccessor.p(), yTransAccessor.p(), zTransAccessor.p()); + + return cellFaceAccessObject; + } + else if (uiResultName == RimDefines::combinedRiMultResultName()) + { + cvf::ref cellFaceAccessObject = new RigCombTransResultAccessor(grid); + + cvf::ref xRiMultAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riMultXResultName()); + cvf::ref yRiMultAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riMultYResultName()); + cvf::ref zRiMultAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riMultZResultName()); + + cellFaceAccessObject->setTransResultAccessors(xRiMultAccessor.p(), yRiMultAccessor.p(), zRiMultAccessor.p()); + + return cellFaceAccessObject; + } + else if (uiResultName == RimDefines::combinedRiAreaNormTranResultName()) + { + cvf::ref cellFaceAccessObject = new RigCombTransResultAccessor(grid); + + cvf::ref xRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riAreaNormTranXResultName()); + cvf::ref yRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riAreaNormTranYResultName()); + cvf::ref zRiAreaNormTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, RimDefines::riAreaNormTranZResultName()); + + cellFaceAccessObject->setTransResultAccessors(xRiAreaNormTransAccessor.p(), yRiAreaNormTransAccessor.p(), zRiAreaNormTransAccessor.p()); + + return cellFaceAccessObject; + } + return RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, uiResultName); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RigResultAccessorFactory::createResultAccessor(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName, + RimDefines::ResultCatType resultType) +{ + CVF_ASSERT(gridIndex < eclipseCase->gridCount()); + CVF_ASSERT(eclipseCase); + CVF_ASSERT(eclipseCase->results(porosityModel)); + CVF_ASSERT(eclipseCase->activeCellInfo(porosityModel)); + + RigGridBase *grid = eclipseCase->grid(gridIndex); + + if (!eclipseCase || !eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) + { + return NULL; + } + + size_t scalarSetIndex = eclipseCase->results(porosityModel)->findScalarResultIndex(resultType, uiResultName); + if (scalarSetIndex == cvf::UNDEFINED_SIZE_T) + { + return NULL; + } + + return createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, scalarSetIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// This function must be harmonized with RigResultModifierFactory::createResultModifier() +//-------------------------------------------------------------------------------------------------- +cvf::ref RigResultAccessorFactory::createNativeResultAccessor(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName) +{ + CVF_ASSERT(gridIndex < eclipseCase->gridCount()); + CVF_ASSERT(eclipseCase); + CVF_ASSERT(eclipseCase->results(porosityModel)); + CVF_ASSERT(eclipseCase->activeCellInfo(porosityModel)); + + RigGridBase *grid = eclipseCase->grid(gridIndex); + + if (!eclipseCase || !eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) + { + return NULL; + } + + size_t scalarSetIndex = eclipseCase->results(porosityModel)->findScalarResultIndex(uiResultName); + if (scalarSetIndex == cvf::UNDEFINED_SIZE_T) + { + return NULL; + } + + return createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, scalarSetIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RigResultAccessorFactory::createResultAccessor(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t resultIndex) +{ + if (resultIndex == cvf::UNDEFINED_SIZE_T) + { + return new RigHugeValResultAccessor; + } + + if (!eclipseCase) return NULL; + + RigGridBase* grid = eclipseCase->grid(gridIndex); + if (!grid) return NULL; + + std::vector< std::vector >& scalarSetResults = eclipseCase->results(porosityModel)->cellScalarResults(resultIndex); + + if (timeStepIndex >= scalarSetResults.size()) + { + return new RigHugeValResultAccessor; + } + + std::vector* resultValues = NULL; + if (timeStepIndex < scalarSetResults.size()) + { + resultValues = &(scalarSetResults[timeStepIndex]); + } + + if (!resultValues || resultValues->size() == 0) + { + return new RigHugeValResultAccessor; + } + + bool useGlobalActiveIndex = eclipseCase->results(porosityModel)->isUsingGlobalActiveIndex(resultIndex); + if (useGlobalActiveIndex) + { + cvf::ref object = new RigActiveCellsResultAccessor(grid, resultValues, eclipseCase->activeCellInfo(porosityModel)); + return object; + } + else + { + cvf::ref object = new RigAllGridCellsResultAccessor(grid, resultValues); + return object; + } +} + diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.h b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.h new file mode 100644 index 0000000000..53815e4189 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.h @@ -0,0 +1,67 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RifReaderInterface.h" +#include "RigResultAccessor.h" +#include "RimDefines.h" + +class RigActiveCellInfo; +class RigGridBase; + +class RigResultAccessorFactory +{ +public: + static cvf::ref + createResultAccessor(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName); + + static cvf::ref + createResultAccessor(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName, + RimDefines::ResultCatType resultType); + + static cvf::ref + createResultAccessor(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t resultIndex); + + + +private: + static cvf::ref + createNativeResultAccessor(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& resultName); + + +}; + + diff --git a/ApplicationCode/ReservoirDataModel/RigResultModifier.h b/ApplicationCode/ReservoirDataModel/RigResultModifier.h new file mode 100644 index 0000000000..79bb36495d --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigResultModifier.h @@ -0,0 +1,92 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigGridBase.h" +#include "RigActiveCellInfo.h" + + +//================================================================================================== +/// +//================================================================================================== +class RigResultModifier : public cvf::Object +{ +public: + virtual void setCellScalar(size_t gridLocalCellIndex, double scalarValue) = 0; +}; + + + +//================================================================================================== +/// +//================================================================================================== +class RigAllGridCellsResultModifier : public RigResultModifier +{ +public: + RigAllGridCellsResultModifier(const RigGridBase* grid, std::vector* reservoirResultValues) + : m_grid(grid), + m_reservoirResultValues(reservoirResultValues) + { + } + + virtual void setCellScalar(size_t gridLocalCellIndex, double scalarValue) + { + size_t reservoirCellIndex = m_grid->reservoirCellIndex(gridLocalCellIndex); + CVF_TIGHT_ASSERT(reservoirCellIndex < m_reservoirResultValues->size()); + + (*m_reservoirResultValues)[reservoirCellIndex] = scalarValue; + } + +private: + const RigGridBase* m_grid; + std::vector* m_reservoirResultValues; +}; + + +//================================================================================================== +/// +//================================================================================================== +class RigActiveCellsResultModifier : public RigResultModifier +{ +public: + RigActiveCellsResultModifier(const RigGridBase* grid, std::vector* reservoirResultValues, const RigActiveCellInfo* activeCellInfo) + : m_grid(grid), + m_reservoirResultValues(reservoirResultValues), + m_activeCellInfo(activeCellInfo) + { + } + + virtual void setCellScalar(size_t gridLocalCellIndex, double scalarValue) + { + size_t reservoirCellIndex = m_grid->reservoirCellIndex(gridLocalCellIndex); + size_t resultValueIndex = m_activeCellInfo->cellResultIndex(reservoirCellIndex); + + CVF_TIGHT_ASSERT(m_reservoirResultValues != NULL && resultValueIndex < m_reservoirResultValues->size()); + + (*m_reservoirResultValues)[resultValueIndex] = scalarValue; + } + + +private: + const RigActiveCellInfo* m_activeCellInfo; + const RigGridBase* m_grid; + std::vector* m_reservoirResultValues; +}; + diff --git a/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.cpp b/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.cpp new file mode 100644 index 0000000000..30cb443232 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.cpp @@ -0,0 +1,101 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigResultModifierFactory.h" + +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigResultModifier.h" + +#include + + +//-------------------------------------------------------------------------------------------------- +/// This function must be harmonized with RigResultAccessorFactory::createNativeResultAccessor() +//-------------------------------------------------------------------------------------------------- +cvf::ref RigResultModifierFactory::createResultModifier(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + QString& uiResultName) +{ + if (!eclipseCase) return NULL; + + if (!eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) + { + return NULL; + } + + size_t scalarSetIndex = eclipseCase->results(porosityModel)->findScalarResultIndex(uiResultName); + + return createResultModifier(eclipseCase, gridIndex, porosityModel, timeStepIndex, scalarSetIndex); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RigResultModifierFactory::createResultModifier(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, size_t scalarResultIndex) +{ + if (!eclipseCase) return NULL; + + if (!eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) + { + return NULL; + } + + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) + { + return NULL; + } + + RigGridBase* grid = eclipseCase->grid(gridIndex); + if (!grid) + { + return NULL; + } + + std::vector< std::vector >& scalarSetResults = eclipseCase->results(porosityModel)->cellScalarResults(scalarResultIndex); + + if (timeStepIndex >= scalarSetResults.size()) + { + return NULL; + } + + std::vector* resultValues = NULL; + if (timeStepIndex < scalarSetResults.size()) + { + resultValues = &(scalarSetResults[timeStepIndex]); + } + + bool useGlobalActiveIndex = eclipseCase->results(porosityModel)->isUsingGlobalActiveIndex(scalarResultIndex); + if (useGlobalActiveIndex) + { + cvf::ref object = new RigActiveCellsResultModifier(grid, resultValues, eclipseCase->activeCellInfo(porosityModel)); + return object; + } + else + { + cvf::ref object = new RigAllGridCellsResultModifier(grid, resultValues); + return object; + } +} diff --git a/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.h b/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.h new file mode 100644 index 0000000000..7c320fa4ad --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.h @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RifReaderInterface.h" + +class RigCaseData; +class RigResultModifier; + +class RigResultModifierFactory +{ +public: + static cvf::ref + createResultModifier(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + QString& uiResultName); + + static cvf::ref + createResultModifier(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t scalarResultIndex); +}; + + diff --git a/ApplicationCode/ReservoirDataModel/RigStatisticsCalculator.cpp b/ApplicationCode/ReservoirDataModel/RigStatisticsCalculator.cpp new file mode 100644 index 0000000000..af56724a2d --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigStatisticsCalculator.cpp @@ -0,0 +1,262 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigStatisticsCalculator.h" + +#include "RigStatisticsMath.h" +#include "RigCaseCellResultsData.h" + +#include // Needed for HUGE_VAL on Linux + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStatisticsCalculator::meanCellScalarValue(double& meanValue) +{ + double valueSum = 0.0; + size_t sampleCount = 0; + + this->valueSumAndSampleCount(valueSum, sampleCount); + + if (sampleCount == 0) + { + meanValue = HUGE_VAL; + } + else + { + meanValue = valueSum / sampleCount; + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigNativeStatCalc::RigNativeStatCalc(RigCaseCellResultsData* cellResultsData, size_t scalarResultIndex) + : m_resultsData(cellResultsData), + m_scalarResultIndex(scalarResultIndex) +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigNativeStatCalc::minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) +{ + std::vector& values = m_resultsData->cellScalarResults(m_scalarResultIndex, timeStepIndex); + + size_t i; + for (i = 0; i < values.size(); i++) + { + if (values[i] == HUGE_VAL) + { + continue; + } + + if (values[i] < min) + { + min = values[i]; + } + + if (values[i] > max) + { + max = values[i]; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigNativeStatCalc::posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) +{ + std::vector& values = m_resultsData->cellScalarResults(m_scalarResultIndex, timeStepIndex); + + size_t i; + for (i = 0; i < values.size(); i++) + { + if (values[i] == HUGE_VAL) + { + continue; + } + + if (values[i] < pos && values[i] > 0) + { + pos = values[i]; + } + + if (values[i] > neg && values[i] < 0) + { + neg = values[i]; + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigNativeStatCalc::addDataToHistogramCalculator(RigHistogramCalculator& histogramCalculator) +{ + for (size_t tIdx = 0; tIdx < m_resultsData->timeStepCount(m_scalarResultIndex); tIdx++) + { + std::vector& values = m_resultsData->cellScalarResults(m_scalarResultIndex, tIdx); + + histogramCalculator.addData(values); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigNativeStatCalc::valueSumAndSampleCount(double& valueSum, size_t& sampleCount) +{ + for (size_t tIdx = 0; tIdx < m_resultsData->timeStepCount(m_scalarResultIndex); tIdx++) + { + std::vector& values = m_resultsData->cellScalarResults(m_scalarResultIndex, tIdx); + size_t undefValueCount = 0; + for (size_t cIdx = 0; cIdx < values.size(); ++cIdx) + { + double value = values[cIdx]; + if (value == HUGE_VAL || value != value) + { + ++undefValueCount; + continue; + } + + valueSum += value; + } + + sampleCount += values.size(); + sampleCount -= undefValueCount; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigNativeStatCalc::timeStepCount() +{ + return m_resultsData->timeStepCount(m_scalarResultIndex); +} + + + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigMultipleDatasetStatCalc::RigMultipleDatasetStatCalc() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigMultipleDatasetStatCalc::addStatisticsCalculator(RigStatisticsCalculator* statisticsCalculator) +{ + if (statisticsCalculator) + { + m_nativeStatisticsCalculators.push_back(statisticsCalculator); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigMultipleDatasetStatCalc::minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) +{ + for (size_t i = 0; i < m_nativeStatisticsCalculators.size(); i++) + { + if (m_nativeStatisticsCalculators.at(i)) + { + m_nativeStatisticsCalculators.at(i)->minMaxCellScalarValues(timeStepIndex, min, max); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigMultipleDatasetStatCalc::posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) +{ + for (size_t i = 0; i < m_nativeStatisticsCalculators.size(); i++) + { + if (m_nativeStatisticsCalculators.at(i)) + { + m_nativeStatisticsCalculators.at(i)->posNegClosestToZero(timeStepIndex, pos, neg); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigMultipleDatasetStatCalc::valueSumAndSampleCount(double& valueSum, size_t& sampleCount) +{ + for (size_t i = 0; i < m_nativeStatisticsCalculators.size(); i++) + { + if (m_nativeStatisticsCalculators.at(i)) + { + m_nativeStatisticsCalculators.at(i)->valueSumAndSampleCount(valueSum, sampleCount); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigMultipleDatasetStatCalc::addDataToHistogramCalculator(RigHistogramCalculator& histogramCalculator) +{ + for (size_t i = 0; i < m_nativeStatisticsCalculators.size(); i++) + { + if (m_nativeStatisticsCalculators.at(i)) + { + m_nativeStatisticsCalculators.at(i)->addDataToHistogramCalculator(histogramCalculator); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigMultipleDatasetStatCalc::timeStepCount() +{ + if (m_nativeStatisticsCalculators.size() > 0) + { + return m_nativeStatisticsCalculators[0]->timeStepCount(); + } + + return 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigMultipleDatasetStatCalc::addNativeStatisticsCalculator(RigCaseCellResultsData* cellResultsData, size_t scalarResultIndex) +{ + if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) + { + this->addStatisticsCalculator(new RigNativeStatCalc(cellResultsData, scalarResultIndex)); + } +} + diff --git a/ApplicationCode/ReservoirDataModel/RigStatisticsCalculator.h b/ApplicationCode/ReservoirDataModel/RigStatisticsCalculator.h new file mode 100644 index 0000000000..7ecc4f48ee --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigStatisticsCalculator.h @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "cvfBase.h" +#include "cvfObject.h" +#include "cvfCollection.h" + +#include + +class RigHistogramCalculator; +class RigCaseCellResultsData; + +//================================================================================================== +/// +//================================================================================================== +class RigStatisticsCalculator : public cvf::Object +{ +public: + virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) = 0; + virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) = 0; + + void meanCellScalarValue(double& meanValue); + virtual void valueSumAndSampleCount(double& valueSum, size_t& sampleCount) = 0; + virtual void addDataToHistogramCalculator(RigHistogramCalculator& histogramCalculator) = 0; + + virtual size_t timeStepCount() = 0; +}; + + +//================================================================================================== +/// +//================================================================================================== +class RigNativeStatCalc : public RigStatisticsCalculator +{ +public: + RigNativeStatCalc(RigCaseCellResultsData* cellResultsData, size_t scalarResultIndex); + + virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); + virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); + virtual void valueSumAndSampleCount(double& valueSum, size_t& sampleCount); + + virtual void addDataToHistogramCalculator(RigHistogramCalculator& histogramCalculator); + virtual size_t timeStepCount(); + +private: + cvf::ref m_resultsData; + size_t m_scalarResultIndex; +}; + + +//================================================================================================== +/// +//================================================================================================== +class RigMultipleDatasetStatCalc : public RigStatisticsCalculator +{ +public: + RigMultipleDatasetStatCalc(); + void addStatisticsCalculator(RigStatisticsCalculator* statisticsCalculator); + void addNativeStatisticsCalculator(RigCaseCellResultsData* cellResultsData, size_t scalarResultIndices); + + virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); + virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); + + virtual void valueSumAndSampleCount(double& valueSum, size_t& sampleCount); + virtual void addDataToHistogramCalculator(RigHistogramCalculator& histogramCalculator); + + virtual size_t timeStepCount(); + +private: + cvf::Collection m_nativeStatisticsCalculators; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigStatisticsDataCache.cpp b/ApplicationCode/ReservoirDataModel/RigStatisticsDataCache.cpp new file mode 100644 index 0000000000..87b8c6d403 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigStatisticsDataCache.cpp @@ -0,0 +1,206 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigStatisticsDataCache.h" + +#include "RigStatisticsCalculator.h" +#include "RigStatisticsMath.h" + +#include // Needed for HUGE_VAL on Linux + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigStatisticsDataCache::RigStatisticsDataCache(RigStatisticsCalculator* statisticsCalculator) + : m_statisticsCalculator(statisticsCalculator) +{ + clearAllStatistics(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStatisticsDataCache::clearAllStatistics() +{ + m_minValue = HUGE_VAL; + m_maxValue = -HUGE_VAL; + m_posClosestToZero = HUGE_VAL; + m_negClosestToZero = -HUGE_VAL; + m_p10 = HUGE_VAL; + m_p90 = HUGE_VAL; + m_meanValue = HUGE_VAL; + + m_histogram.clear(); + m_maxMinValuesPrTs.clear(); + m_posNegClosestToZeroPrTs.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStatisticsDataCache::minMaxCellScalarValues(double& min, double& max) +{ + if (m_minValue == HUGE_VAL) + { + min = HUGE_VAL; + max = -HUGE_VAL; + + size_t i; + for (i = 0; i < m_statisticsCalculator->timeStepCount(); i++) + { + double tsmin, tsmax; + this->minMaxCellScalarValues(i, tsmin, tsmax); + if (tsmin < min) min = tsmin; + if (tsmax > max) max = tsmax; + } + + m_minValue = min; + m_maxValue = max; + } + + min = m_minValue; + max = m_maxValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStatisticsDataCache::minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) +{ + if (timeStepIndex >= m_maxMinValuesPrTs.size()) + { + m_maxMinValuesPrTs.resize(timeStepIndex + 1, std::make_pair(HUGE_VAL, -HUGE_VAL)); + } + + if (m_maxMinValuesPrTs[timeStepIndex].first == HUGE_VAL) + { + min = HUGE_VAL; + max = -HUGE_VAL; + + m_statisticsCalculator->minMaxCellScalarValues(timeStepIndex, min, max); + + m_maxMinValuesPrTs[timeStepIndex].first = min; + m_maxMinValuesPrTs[timeStepIndex].second = max; + } + + min = m_maxMinValuesPrTs[timeStepIndex].first; + max = m_maxMinValuesPrTs[timeStepIndex].second; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStatisticsDataCache::posNegClosestToZero(double& pos, double& neg) +{ + if (m_posClosestToZero == HUGE_VAL) + { + pos = HUGE_VAL; + neg = -HUGE_VAL; + + size_t i; + for (i = 0; i < m_statisticsCalculator->timeStepCount(); i++) + { + double tsNeg, tsPos; + this->posNegClosestToZero(i, tsPos, tsNeg); + if (tsNeg > neg && tsNeg < 0) neg = tsNeg; + if (tsPos < pos && tsPos > 0) pos = tsPos; + } + + m_posClosestToZero = pos; + m_negClosestToZero = neg; + } + + pos = m_posClosestToZero; + neg = m_negClosestToZero; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStatisticsDataCache::posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) +{ + if (timeStepIndex >= m_posNegClosestToZeroPrTs.size()) + { + m_posNegClosestToZeroPrTs.resize(timeStepIndex + 1, std::make_pair(HUGE_VAL, -HUGE_VAL)); + } + + if (m_posNegClosestToZeroPrTs[timeStepIndex].first == HUGE_VAL) + { + pos = HUGE_VAL; + neg = -HUGE_VAL; + + m_statisticsCalculator->posNegClosestToZero(timeStepIndex, pos, neg); + + m_posNegClosestToZeroPrTs[timeStepIndex].first = pos; + m_posNegClosestToZeroPrTs[timeStepIndex].second = neg; + } + + pos = m_posNegClosestToZeroPrTs[timeStepIndex].first; + neg = m_posNegClosestToZeroPrTs[timeStepIndex].second; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigStatisticsDataCache::cellScalarValuesHistogram() +{ + if (m_histogram.size() == 0) + { + double min; + double max; + size_t nBins = 100; + this->minMaxCellScalarValues(min, max); + + RigHistogramCalculator histCalc(min, max, nBins, &m_histogram); + + m_statisticsCalculator->addDataToHistogramCalculator(histCalc); + + m_p10 = histCalc.calculatePercentil(0.1); + m_p90 = histCalc.calculatePercentil(0.9); + } + + return m_histogram; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStatisticsDataCache::p10p90CellScalarValues(double& p10, double& p90) +{ + // First make sure they are calculated + const std::vector& histogr = this->cellScalarValuesHistogram(); + + p10 = m_p10; + p90 = m_p90; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStatisticsDataCache::meanCellScalarValues(double& meanValue) +{ + if (m_meanValue == HUGE_VAL) + { + m_statisticsCalculator->meanCellScalarValue(m_meanValue); + } + + meanValue = m_meanValue; +} + diff --git a/ApplicationCode/ReservoirDataModel/RigStatisticsDataCache.h b/ApplicationCode/ReservoirDataModel/RigStatisticsDataCache.h new file mode 100644 index 0000000000..0688ea00d0 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigStatisticsDataCache.h @@ -0,0 +1,66 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigStatisticsCalculator.h" + +#include "cvfBase.h" +#include "cvfObject.h" + +#include + + +//================================================================================================== +/// +//================================================================================================== +class RigStatisticsDataCache : public cvf::Object +{ +public: + RigStatisticsDataCache(RigStatisticsCalculator* statisticsCalculator); + + void clearAllStatistics(); + + void minMaxCellScalarValues(double& min, double& max); + void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); + void posNegClosestToZero(double& pos, double& neg); + void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); + + void p10p90CellScalarValues(double& p10, double& p90); + void meanCellScalarValues(double& meanValue); + const std::vector& cellScalarValuesHistogram(); + +private: + double m_minValue; + double m_maxValue; + double m_posClosestToZero; + double m_negClosestToZero; + + double m_p10; + double m_p90; + double m_meanValue; + + std::vector m_histogram; + + std::vector > m_maxMinValuesPrTs; ///< Max min values for each time step + std::vector > m_posNegClosestToZeroPrTs; ///< PosNeg values for each time step + + cvf::ref m_statisticsCalculator; +}; + diff --git a/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.cpp b/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.cpp new file mode 100644 index 0000000000..d3ab6568b8 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.cpp @@ -0,0 +1,98 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigTernaryResultAccessor2d.h" + +#include "RigResultAccessor.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigTernaryResultAccessor::RigTernaryResultAccessor() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// Requires at least two data objects present, asserts if more than one data accessor is NULL +//-------------------------------------------------------------------------------------------------- +void RigTernaryResultAccessor::setTernaryResultAccessors(RigResultAccessor* soil, RigResultAccessor* sgas, RigResultAccessor* swat) +{ + m_soilAccessor = soil; + m_sgasAccessor = sgas; + m_swatAccessor = swat; +} + +//-------------------------------------------------------------------------------------------------- +/// If only swat is present, soil is set to (1.0 - swat) and sgas to 0 +//-------------------------------------------------------------------------------------------------- +cvf::Vec2d RigTernaryResultAccessor::cellScalar(size_t gridLocalCellIndex) const +{ + double soil = 0.0; + double sgas = 0.0; + + if (m_soilAccessor.notNull()) + { + soil = m_soilAccessor->cellScalar(gridLocalCellIndex); + + if (m_sgasAccessor.notNull()) + { + sgas = m_sgasAccessor->cellScalar(gridLocalCellIndex); + } + else if (m_swatAccessor.notNull()) + { + sgas = 1.0 - soil - m_swatAccessor->cellScalar(gridLocalCellIndex); + } + else + { + sgas = 1.0 - soil; + } + } + else + { + if (m_sgasAccessor.notNull()) + { + sgas = m_sgasAccessor->cellScalar(gridLocalCellIndex); + + if (m_swatAccessor.notNull()) + { + soil = 1.0 - sgas - m_swatAccessor->cellScalar(gridLocalCellIndex); + } + else + { + soil = 1.0 - sgas; + } + } + else if (m_swatAccessor.notNull()) + { + soil = 1.0 - m_swatAccessor->cellScalar(gridLocalCellIndex); + } + } + + return cvf::Vec2d(soil, sgas); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2d RigTernaryResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + return cellScalar(gridLocalCellIndex); +} diff --git a/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.h b/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.h new file mode 100644 index 0000000000..c081ae3896 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.h @@ -0,0 +1,46 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RigResultAccessor2d.h" +#include "RigResultAccessor.h" + +//================================================================================================== +/// +//================================================================================================== +class RigTernaryResultAccessor : public RigResultAccessor2d +{ +public: + RigTernaryResultAccessor(); + + /// Requires two of the arguments to be present + void setTernaryResultAccessors(RigResultAccessor* soil, RigResultAccessor* sgas, RigResultAccessor* swat); + + /// Returns [SOIL, SGAS] regardless of which one of the three is missing. if Soil or SWat is missing, it is calculated + /// based on the two others + virtual cvf::Vec2d cellScalar(size_t gridLocalCellIndex) const; + virtual cvf::Vec2d cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + +private: + cvf::ref m_soilAccessor; + cvf::ref m_sgasAccessor; + cvf::ref m_swatAccessor; +}; + diff --git a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.cpp b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.cpp index ad850323c6..b354a71787 100644 --- a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.cpp +++ b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.cpp @@ -1,3 +1,22 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "cvfGeometryTools.h" #pragma warning (disable : 4503) @@ -517,6 +536,60 @@ void GeometryTools::addMidEdgeNodes(std::list >* poly } } +//-------------------------------------------------------------------------------------------------- +/// Based on http://geomalgorithms.com/a01-_area.html +/// This method returns the polygon normal with length equal to the polygon area. +/// The components of the normal is thus the size of projected area into each of the main axis planes +//-------------------------------------------------------------------------------------------------- +cvf::Vec3d GeometryTools::polygonAreaNormal3D(const std::vector& polygon) +{ + size_t pSize = polygon.size(); + switch (pSize) + { + case 0: + case 1: + case 2: + { + return cvf::Vec3d::ZERO; + } + break; + case 3: + { + return 0.5 * ((polygon[1]-polygon[0]) ^ (polygon[2] - polygon[0])); + } + break; + case 4: + { + // Cross product of diagonal = 2*A + return 0.5* ((polygon[2]-polygon[0]) ^ (polygon[3] - polygon[1])); + } + break; + default: + { + /// JJS: + // This is possibly not the fastest approach with large polygons, where a scaled projections approach would be better, + // but I suspect this (simpler) approach is faster for small polygons, as long as we do not have the polygon normal up front. + // + cvf::Vec3d areaNormal(cvf::Vec3d::ZERO); + size_t h = (pSize - 1)/2; + size_t k = (pSize % 2) ? 0 : pSize - 1; + + // First quads + for (size_t i = 1; i < h; ++i) + { + areaNormal += ( (polygon[2*i] - polygon[0]) ^ (polygon[2*i + 1] - polygon[2*i-1] ) ); + } + + // Last triangle or quad + areaNormal += ( (polygon[2*h] - polygon[0]) ^ (polygon[k] - polygon[2*h-1] ) ); + + areaNormal *= 0.5; + + return areaNormal; + } + } +} + @@ -599,7 +672,7 @@ bool EarClipTesselator::calculateTriangles( std::vector* triangleIndices // We want m_polygonIndices to be a counter-clockwise polygon to make the validation test work - if (calculatePolygonArea() < 0 ) + if (calculateProjectedPolygonArea() < 0 ) { m_polygonIndices.reverse(); } @@ -732,7 +805,7 @@ bool EarClipTesselator::isPointInsideTriangle(const cvf::Vec3d& A, const cvf::Ve /// Computes area of the currently stored 2D polygon/contour //-------------------------------------------------------------------------------------------------- -double EarClipTesselator::calculatePolygonArea() const +double EarClipTesselator::calculateProjectedPolygonArea() const { CVF_ASSERT(m_X > -1 && m_Y > -1); @@ -834,7 +907,7 @@ bool FanEarClipTesselator::calculateTriangles(std::vector* triangles) // We want m_polygonIndices to be a counter-clockwise polygon to make the validation test work - if (calculatePolygonArea() < 0 ) + if (calculateProjectedPolygonArea() < 0 ) { m_polygonIndices.reverse(); } diff --git a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.h b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.h index c124762ddd..fb11aefddf 100644 --- a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.h +++ b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.h @@ -1,3 +1,22 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "cvfBase.h" #include "cvfArray.h" @@ -27,6 +46,8 @@ class GeometryTools static double getAngle(const cvf::Vec3d& positiveNormalAxis, const cvf::Vec3d& v1, const cvf::Vec3d& v2); static double getAngle(const cvf::Vec3d& v1, const cvf::Vec3d& v2); + static cvf::Vec3d polygonAreaNormal3D(const std::vector& polygon); + enum IntersectionStatus { NO_INTERSECTION, @@ -138,7 +159,7 @@ class EarClipTesselator protected: bool isTriangleValid( std::list::const_iterator u, std::list::const_iterator v, std::list::const_iterator w) const; bool isPointInsideTriangle(const cvf::Vec3d& A, const cvf::Vec3d& B, const cvf::Vec3d& C, const cvf::Vec3d& P) const; - double calculatePolygonArea() const; + double calculateProjectedPolygonArea() const; protected: std::list m_polygonIndices; diff --git a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.inl b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.inl index f698490c3d..7b9aeed23d 100644 --- a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.inl +++ b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.inl @@ -1,3 +1,22 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 @@ -299,7 +318,7 @@ bool GeometryTools::calculateOverlapPolygonOfTwoQuads(std::vector * p { int k; - for (k = 0; k < 4; ++k) + for (k = 3; k >= 0; --k) // Return opposite winding, to match winding of face 1 { polygon->push_back(cv2CubeFaceIndices[k]); } diff --git a/ApplicationCode/Resources/ResInsight.qrc b/ApplicationCode/Resources/ResInsight.qrc index 73cb02a712..384db079ed 100644 --- a/ApplicationCode/Resources/ResInsight.qrc +++ b/ApplicationCode/Resources/ResInsight.qrc @@ -48,5 +48,6 @@ fs_CellFace.glsl vs_CellFace.glsl + vs_2dTextureCellFace.glsl diff --git a/ApplicationCode/Resources/vs_2dTextureCellFace.glsl b/ApplicationCode/Resources/vs_2dTextureCellFace.glsl new file mode 100644 index 0000000000..a42ba28a43 --- /dev/null +++ b/ApplicationCode/Resources/vs_2dTextureCellFace.glsl @@ -0,0 +1,130 @@ +uniform sampler2D u_edgeTexture2D; +uniform sampler2D u_cellTexture2D; + +attribute vec2 a_localCoord; +attribute float a_face; + +attribute vec2 a_cellTextureCoord; +attribute float a_colorPosI; +attribute float a_colorNegI; +attribute float a_colorPosJ; +attribute float a_colorNegJ; +attribute float a_colorPosK; +attribute float a_colorNegK; + +varying vec2 v_localCoord; +varying vec4 v_cellColor; +varying vec4 v_bottomColor; +varying vec4 v_rightColor; +varying vec4 v_topColor; +varying vec4 v_leftColor; + +// Native visualization lib stuff +uniform mat4 cvfu_modelViewProjectionMatrix; +uniform mat4 cvfu_modelViewMatrix; +uniform mat3 cvfu_normalMatrix; + +attribute vec4 cvfa_vertex; +attribute vec3 cvfa_normal; + +varying vec3 v_ecPosition; +varying vec3 v_ecNormal; +// End native vz stuff + +#define POS_I 0.0 +#define NEG_I 1.0 +#define POS_J 2.0 +#define NEG_J 3.0 +#define POS_K 4.0 +#define NEG_K 5.0 + +// +// 7---------6 +// /| /| |k +// / | / | | /j +// 4---------5 | |/ +// | 3------|--2 *---i +// | / | / +// |/ |/ +// 0---------1 +// +// Face layout expected +// POS_I 1, 2, 6, 5 +// NEG_I 0, 4, 7, 3 +// POS_J 3, 7, 6, 2 +// NEG_J 0, 1, 5, 4 +// POS_K 4, 5, 6, 7 +// NEG_K 0, 3, 2, 1 +// + +vec4 getColorFromTextureCoord(float textureCoord, vec4 cellColor) +{ + if (textureCoord < 0.0) + return cellColor; + else + return texture2D(u_edgeTexture2D, vec2(textureCoord, 0.5f )); +} + +void main() +{ + v_localCoord = a_localCoord; + + v_cellColor = texture2D(u_cellTexture2D, a_cellTextureCoord); + + if (a_face == POS_I) + { + v_bottomColor = getColorFromTextureCoord(a_colorNegK, v_cellColor); + v_rightColor = getColorFromTextureCoord(a_colorPosJ, v_cellColor); + v_topColor = getColorFromTextureCoord(a_colorPosK, v_cellColor); + v_leftColor = getColorFromTextureCoord(a_colorNegJ, v_cellColor); + } + else if (a_face == NEG_I) + { + v_bottomColor = getColorFromTextureCoord(a_colorNegJ, v_cellColor); + v_rightColor = getColorFromTextureCoord(a_colorPosK, v_cellColor); + v_topColor = getColorFromTextureCoord(a_colorPosJ, v_cellColor); + v_leftColor = getColorFromTextureCoord(a_colorNegK, v_cellColor); + } + else if (a_face == POS_J ) + { + v_bottomColor = getColorFromTextureCoord(a_colorNegI, v_cellColor); + v_rightColor = getColorFromTextureCoord(a_colorPosK, v_cellColor); + v_topColor = getColorFromTextureCoord(a_colorPosI, v_cellColor); + v_leftColor = getColorFromTextureCoord(a_colorNegK, v_cellColor); + } + else if (a_face == NEG_J) + { + v_bottomColor = getColorFromTextureCoord(a_colorNegK, v_cellColor); + v_rightColor = getColorFromTextureCoord(a_colorPosI, v_cellColor); + v_topColor = getColorFromTextureCoord(a_colorPosK, v_cellColor); + v_leftColor = getColorFromTextureCoord(a_colorNegI, v_cellColor); + } + else if (a_face == POS_K ) + { + v_bottomColor = getColorFromTextureCoord(a_colorNegJ, v_cellColor); + v_rightColor = getColorFromTextureCoord(a_colorPosI, v_cellColor); + v_topColor = getColorFromTextureCoord(a_colorPosJ, v_cellColor); + v_leftColor = getColorFromTextureCoord(a_colorNegI, v_cellColor); + } + else if (a_face == NEG_K) + { + v_bottomColor = getColorFromTextureCoord(a_colorNegI, v_cellColor); + v_rightColor = getColorFromTextureCoord(a_colorPosJ, v_cellColor); + v_topColor = getColorFromTextureCoord(a_colorPosI, v_cellColor); + v_leftColor = getColorFromTextureCoord(a_colorNegJ, v_cellColor); + } + else + { + v_bottomColor = v_cellColor; + v_rightColor = v_cellColor; + v_topColor = v_cellColor; + v_leftColor = v_cellColor; + } + + // Transforms vertex position and normal vector to eye space + v_ecPosition = (cvfu_modelViewMatrix * cvfa_vertex).xyz; + v_ecNormal = cvfu_normalMatrix * cvfa_normal; + + gl_Position = cvfu_modelViewProjectionMatrix*cvfa_vertex; +} + diff --git a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp index e81b9db3ea..2c495d83a5 100644 --- a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp @@ -1,5 +1,8 @@ +///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -30,7 +33,7 @@ #include "RimCellPropertyFilterCollection.h" #include "RimWellCollection.h" #include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "RimCase.h" #include "RigCaseData.h" @@ -158,7 +161,7 @@ class RiaGetActiveCellInfo: public RiaSocketCommand } RigActiveCellInfo* actCellInfo = reservoirCase->reservoirData()->activeCellInfo(porosityModel); - size_t numMatrixModelActiveCells = actCellInfo->globalActiveCellCount(); + size_t numMatrixModelActiveCells = actCellInfo->reservoirActiveCellCount(); gridNumber.reserve(numMatrixModelActiveCells); cellI.reserve(numMatrixModelActiveCells); @@ -170,7 +173,7 @@ class RiaGetActiveCellInfo: public RiaSocketCommand hostCellK.reserve(numMatrixModelActiveCells); globalCoarseningBoxIdx.reserve(numMatrixModelActiveCells); - const std::vector& globalCells = reservoirCase->reservoirData()->mainGrid()->cells(); + const std::vector& reservoirCells = reservoirCase->reservoirData()->mainGrid()->cells(); std::vector globalCoarseningBoxIndexStart; @@ -190,13 +193,13 @@ class RiaGetActiveCellInfo: public RiaSocketCommand } - for (size_t cIdx = 0; cIdx < globalCells.size(); ++cIdx) + for (size_t cIdx = 0; cIdx < reservoirCells.size(); ++cIdx) { if (actCellInfo->isActive(cIdx)) { - RigGridBase* grid = globalCells[cIdx].hostGrid(); + RigGridBase* grid = reservoirCells[cIdx].hostGrid(); CVF_ASSERT(grid != NULL); - size_t cellIndex = globalCells[cIdx].cellIndex(); + size_t cellIndex = reservoirCells[cIdx].gridLocalCellIndex(); size_t i, j, k; grid->ijkFromCellIndex(cellIndex, &i, &j, &k); @@ -213,7 +216,7 @@ class RiaGetActiveCellInfo: public RiaSocketCommand } else { - size_t parentCellIdx = globalCells[cIdx].parentCellIndex(); + size_t parentCellIdx = reservoirCells[cIdx].parentCellIndex(); parentGrid = (static_cast(grid))->parentGrid(); CVF_ASSERT(parentGrid != NULL); parentGrid->ijkFromCellIndex(parentCellIdx, &pi, &pj, &pk); @@ -229,7 +232,7 @@ class RiaGetActiveCellInfo: public RiaSocketCommand hostCellJ.push_back(static_cast(pj + 1)); // NB: 1-based index in Octave hostCellK.push_back(static_cast(pk + 1)); // NB: 1-based index in Octave - size_t coarseningIdx = globalCells[cIdx].coarseningBoxIndex(); + size_t coarseningIdx = reservoirCells[cIdx].coarseningBoxIndex(); if (coarseningIdx != cvf::UNDEFINED_SIZE_T) { size_t globalCoarseningIdx = globalCoarseningBoxIndexStart[grid->gridIndex()] + coarseningIdx; diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index c76bc690ae..018cc97d19 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -1,5 +1,8 @@ +///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -27,7 +30,7 @@ #include "RimCellPropertyFilterCollection.h" #include "RimWellCollection.h" #include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "RimCase.h" #include "RigCaseData.h" @@ -101,8 +104,8 @@ class RiaGetCellCenters : public RiaSocketCommand { for (size_t i = 0; i < cellCountI; i++) { - size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); - cvf::Vec3d center = rigGrid->cell(localCellIdx).center(); + size_t gridLocalCellIndex = rigGrid->cellIndexFromIJK(i, j, k); + cvf::Vec3d center = rigGrid->cell(gridLocalCellIndex).center(); doubleValues[valueIndex++] = center[coordIdx]; } @@ -152,7 +155,7 @@ class RiaGetActiveCellCenters : public RiaSocketCommand RigActiveCellInfo* actCellInfo = rimCase->reservoirData()->activeCellInfo(porosityModelEnum); RigMainGrid* mainGrid = rimCase->reservoirData()->mainGrid(); - size_t activeCellCount = actCellInfo->globalActiveCellCount(); + size_t activeCellCount = actCellInfo->reservoirActiveCellCount(); size_t doubleValueCount = activeCellCount * 3; socketStream << (quint64)activeCellCount; @@ -177,11 +180,11 @@ class RiaGetActiveCellCenters : public RiaSocketCommand { quint64 valueIndex = 0; - for (size_t globalCellIdx = 0; globalCellIdx < mainGrid->cells().size(); globalCellIdx++) + for (size_t reservoirCellIndex = 0; reservoirCellIndex < mainGrid->cells().size(); reservoirCellIndex++) { - if (!actCellInfo->isActive(globalCellIdx)) continue; + if (!actCellInfo->isActive(reservoirCellIndex)) continue; - cvf::Vec3d center = mainGrid->cells()[globalCellIdx].center(); + cvf::Vec3d center = mainGrid->cells()[reservoirCellIndex].center(); doubleValues[valueIndex++] = center[coordIdx]; } @@ -268,8 +271,8 @@ class RiaGetCellCorners : public RiaSocketCommand { for (size_t i = 0; i < cellCountI; i++) { - size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k); - rigGrid->cellCornerVertices(localCellIdx, cornerVerts); + size_t gridLocalCellIndex = rigGrid->cellIndexFromIJK(i, j, k); + rigGrid->cellCornerVertices(gridLocalCellIndex, cornerVerts); doubleValues[valueIndex++] = cornerVerts[cornerIndexMapping][coordIdx]; } @@ -321,7 +324,7 @@ class RiaGetActiveCellCorners : public RiaSocketCommand RigActiveCellInfo* actCellInfo = rimCase->reservoirData()->activeCellInfo(porosityModelEnum); RigMainGrid* mainGrid = rimCase->reservoirData()->mainGrid(); - size_t activeCellCount = actCellInfo->globalActiveCellCount(); + size_t activeCellCount = actCellInfo->reservoirActiveCellCount(); size_t doubleValueCount = activeCellCount * 3 * 8; socketStream << (quint64)activeCellCount; @@ -351,11 +354,11 @@ class RiaGetActiveCellCorners : public RiaSocketCommand quint64 valueIndex = 0; - for (size_t globalCellIdx = 0; globalCellIdx < mainGrid->cells().size(); globalCellIdx++) + for (size_t reservoirCellIndex = 0; reservoirCellIndex < mainGrid->cells().size(); reservoirCellIndex++) { - if (!actCellInfo->isActive(globalCellIdx)) continue; + if (!actCellInfo->isActive(reservoirCellIndex)) continue; - mainGrid->cellCornerVertices(globalCellIdx, cornerVerts); + mainGrid->cellCornerVertices(reservoirCellIndex, cornerVerts); doubleValues[valueIndex++] = cornerVerts[cornerIndexMapping][coordIdx]; } diff --git a/ApplicationCode/SocketInterface/RiaProjectInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaProjectInfoCommands.cpp index 660effb8b5..96c2b69c9a 100644 --- a/ApplicationCode/SocketInterface/RiaProjectInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaProjectInfoCommands.cpp @@ -1,5 +1,8 @@ +///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -27,7 +30,7 @@ #include "RimCellPropertyFilterCollection.h" #include "RimWellCollection.h" #include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "RimCase.h" #include "RigCaseData.h" diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index fa5fc419fd..048da8f0ca 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -1,5 +1,8 @@ +///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,33 +19,32 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiaStdInclude.h" + #include "RiaSocketCommand.h" +#include "RiaSocketDataTransfer.h" #include "RiaSocketServer.h" #include "RiaSocketTools.h" -#include "RiuMainWindow.h" -#include "RiuProcessMonitor.h" +#include "RifReaderInterface.h" -#include "RigCaseData.h" +#include "RigActiveCellInfo.h" #include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigResultModifier.h" +#include "RigResultModifierFactory.h" -#include "RimReservoirCellResultsCacher.h" #include "RimCase.h" #include "RimInputCase.h" +#include "RimInputProperty.h" #include "RimInputPropertyCollection.h" -#include "RimUiTreeModelPdm.h" +#include "RimReservoirCellResultsStorage.h" #include "RimReservoirView.h" #include "RimResultSlot.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "RimCellPropertyFilterCollection.h" -#include "RimWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" - -#include -#include "RiaApplication.h" -#include "RiaPreferences.h" -#include "RiaSocketDataTransfer.h" +#include "RimUiTreeModelPdm.h" + +#include "RiuMainWindow.h" +#include "RiuProcessMonitor.h" +#include "RigResultAccessorFactory.h" //-------------------------------------------------------------------------------------------------- @@ -140,7 +142,7 @@ class RiaGetActiveCellProperty: public RiaSocketCommand // then the byte-size of the result values in one timestep const RigActiveCellInfo* activeInfo = rimCase->reservoirData()->activeCellInfo(porosityModelEnum); - size_t timestepResultCount = activeInfo->globalActiveCellCount(); + size_t timestepResultCount = activeInfo->reservoirActiveCellCount(); quint64 timestepByteCount = (quint64)(timestepResultCount*sizeof(double)); socketStream << timestepByteCount ; @@ -150,18 +152,18 @@ class RiaGetActiveCellProperty: public RiaSocketCommand std::vector values(valueCount); size_t valueIndex = 0; - size_t globalCellCount = activeInfo->globalCellCount(); + size_t reservoirCellCount = activeInfo->reservoirCellCount(); for (size_t tIdx = 0; tIdx < requestedTimesteps.size(); ++tIdx) { std::vector& doubleValues = scalarResultFrames->at(requestedTimesteps[tIdx]); - for (size_t gcIdx = 0; gcIdx < globalCellCount; ++gcIdx) + for (size_t gcIdx = 0; gcIdx < reservoirCellCount; ++gcIdx) { size_t resultIdx = activeInfo->cellResultIndex(gcIdx); if (resultIdx == cvf::UNDEFINED_SIZE_T) continue; if (resultIdx < doubleValues.size()) { - if (doubleValues.size() == activeInfo->globalCellCount()) + if (doubleValues.size() == activeInfo->reservoirCellCount()) { // When reading data from input text files, result data is read for all grid cells // Read out values from data vector using global cell index instead of active cell result index @@ -321,8 +323,9 @@ class RiaGetGridProperty: public RiaSocketCommand for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { - cvf::ref cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex); - if (cellCenterDataAccessObject.isNull()) + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(rimCase->reservoirData(), gridIdx, porosityModelEnum, requestedTimesteps[tsIdx], propertyName); + + if (resultAccessor.isNull()) { continue; } @@ -332,7 +335,7 @@ class RiaGetGridProperty: public RiaSocketCommand size_t valueIndex = 0; for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++) { - double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx); + double cellValue = resultAccessor->cellScalar(cellIdx); if (cellValue == HUGE_VAL) { cellValue = 0.0; @@ -416,6 +419,9 @@ class RiaSetActiveCellProperty: public RiaSocketCommand if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) { scalarResultFrames = &(rimCase->results(m_porosityModelEnum)->cellResults()->cellScalarResults(scalarResultIndex)); + size_t timeStepCount = rimCase->results(m_porosityModelEnum)->cellResults()->maxTimeStepCount(); + scalarResultFrames->resize(timeStepCount); + m_currentScalarIndex = scalarResultIndex; m_currentPropertyName = propertyName; } @@ -484,17 +490,6 @@ class RiaSetActiveCellProperty: public RiaSocketCommand return true; } - // Resize the result container to be able to receive timesteps at the specified timestep idices - - std::vector::iterator maxTimeStepIt = std::max_element(m_requestedTimesteps.begin(), m_requestedTimesteps.end()); - CVF_ASSERT(maxTimeStepIt != m_requestedTimesteps.end()); - - size_t maxTimeStepIdx = (*maxTimeStepIt); - if (scalarResultFrames->size() <= maxTimeStepIdx) - { - scalarResultFrames->resize(maxTimeStepIdx+1); - } - m_currentReservoir = rimCase; m_scalarResultsToAdd = scalarResultFrames; @@ -530,18 +525,18 @@ class RiaSetActiveCellProperty: public RiaSocketCommand RigActiveCellInfo* activeCellInfo = m_currentReservoir->reservoirData()->activeCellInfo(m_porosityModelEnum); - size_t globalActiveCellCount = activeCellInfo->globalActiveCellCount(); - size_t totalCellCount = activeCellInfo->globalCellCount(); - size_t globalCellResultCount = activeCellInfo->globalCellResultCount(); + size_t activeCellCountReservoir = activeCellInfo->reservoirActiveCellCount(); + size_t totalCellCount = activeCellInfo->reservoirCellCount(); + size_t reservoirCellResultCount = activeCellInfo->reservoirCellResultCount(); - bool isCoarseningActive = globalCellResultCount != globalActiveCellCount; + bool isCoarseningActive = reservoirCellResultCount != activeCellCountReservoir; - if (cellCountFromOctave != globalActiveCellCount ) + if (cellCountFromOctave != activeCellCountReservoir ) { server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("The number of cells in the data coming from octave does not match the case") + ":\"" + m_currentReservoir->caseUserDescription() + "\"\n" " Octave: " + QString::number(cellCountFromOctave) + "\n" - " " + m_currentReservoir->caseUserDescription() + ": Active cell count: " + QString::number(globalActiveCellCount) + " Total cell count: " + QString::number(totalCellCount)) ; + " " + m_currentReservoir->caseUserDescription() + ": Active cell count: " + QString::number(activeCellCountReservoir) + " Total cell count: " + QString::number(totalCellCount)) ; cellCountFromOctave = 0; m_invalidActiveCellCountDetected = true; @@ -556,7 +551,7 @@ class RiaSetActiveCellProperty: public RiaSocketCommand for (size_t tIdx = 0; tIdx < m_timeStepCountToRead; ++tIdx) { size_t tsId = m_requestedTimesteps[tIdx]; - m_scalarResultsToAdd->at(tsId).resize(globalCellResultCount, HUGE_VAL); + m_scalarResultsToAdd->at(tsId).resize(reservoirCellResultCount, HUGE_VAL); } std::vector readBuffer; @@ -640,7 +635,7 @@ class RiaSetActiveCellProperty: public RiaSocketCommand m_currentReservoir->reservoirData() && m_currentReservoir->reservoirData()->results(m_porosityModelEnum) ) { - m_currentReservoir->reservoirData()->results(m_porosityModelEnum)->recalculateMinMax(m_currentScalarIndex); + m_currentReservoir->reservoirData()->results(m_porosityModelEnum)->recalculateStatistics(m_currentScalarIndex); } for (size_t i = 0; i < m_currentReservoir->reservoirViews.size(); ++i) @@ -778,6 +773,9 @@ class RiaSetGridProperty : public RiaSocketCommand if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) { scalarResultFrames = &(rimCase->results(m_porosityModelEnum)->cellResults()->cellScalarResults(scalarResultIndex)); + size_t timeStepCount = rimCase->results(m_porosityModelEnum)->cellResults()->maxTimeStepCount(); + scalarResultFrames->resize(timeStepCount); + m_currentScalarIndex = scalarResultIndex; m_currentPropertyName = propertyName; } @@ -834,17 +832,6 @@ class RiaSetGridProperty : public RiaSocketCommand return true; } - // Resize the result container to be able to receive time steps at the specified time step indices - - std::vector::iterator maxTimeStepIt = std::max_element(m_requestedTimesteps.begin(), m_requestedTimesteps.end()); - CVF_ASSERT(maxTimeStepIt != m_requestedTimesteps.end()); - - size_t maxTimeStepIdx = (*maxTimeStepIt); - if (scalarResultFrames->size() <= maxTimeStepIdx) - { - scalarResultFrames->resize(maxTimeStepIdx+1); - } - m_currentReservoir = rimCase; m_scalarResultsToAdd = scalarResultFrames; @@ -933,14 +920,12 @@ class RiaSetGridProperty : public RiaSocketCommand return true; } - cvf::ref cellCenterDataAccessObject = - m_currentReservoir->reservoirData()->dataAccessObject(grid, m_porosityModelEnum, m_requestedTimesteps[m_currentTimeStepNumberToRead], m_currentScalarIndex); - - if (!cellCenterDataAccessObject.isNull()) + cvf::ref resultModifier = RigResultModifierFactory::createResultModifier(m_currentReservoir->reservoirData(), grid->gridIndex(), m_porosityModelEnum, m_requestedTimesteps[m_currentTimeStepNumberToRead], m_currentScalarIndex); + if (!resultModifier.isNull()) { for (size_t cellIdx = 0; static_cast(cellIdx) < cellCountFromOctave; cellIdx++) { - cellCenterDataAccessObject->setCellScalar(cellIdx, doubleValues[cellIdx]); + resultModifier->setCellScalar(cellIdx, doubleValues[cellIdx]); } } @@ -976,7 +961,7 @@ class RiaSetGridProperty : public RiaSocketCommand m_currentReservoir->reservoirData() && m_currentReservoir->reservoirData()->results(m_porosityModelEnum) ) { - m_currentReservoir->reservoirData()->results(m_porosityModelEnum)->recalculateMinMax(m_currentScalarIndex); + m_currentReservoir->reservoirData()->results(m_porosityModelEnum)->recalculateStatistics(m_currentScalarIndex); } for (size_t i = 0; i < m_currentReservoir->reservoirViews.size(); ++i) diff --git a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp index 0d2ec8879f..e68e48899d 100644 --- a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.cpp @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h index 7c16beb8aa..4298ad6363 100644 --- a/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h +++ b/ApplicationCode/SocketInterface/RiaSocketDataTransfer.h @@ -1,6 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA, Ceetron Solutions AS +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/SocketInterface/RiaSocketServer.cpp b/ApplicationCode/SocketInterface/RiaSocketServer.cpp index 1258030bcf..28b9bb3826 100644 --- a/ApplicationCode/SocketInterface/RiaSocketServer.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketServer.cpp @@ -1,5 +1,8 @@ +///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -41,7 +44,7 @@ #include "RimScriptCollection.h" #include "RimCaseCollection.h" #include "RimWellPathCollection.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "RigCaseData.h" #include "RigCaseCellResultsData.h" @@ -86,7 +89,7 @@ RiaSocketServer::RiaSocketServer(QObject* parent) return; } - connect(m_nextPendingConnectionTimer, SIGNAL(timeout()), this, SLOT(handleNextPendingConnection())); + connect(m_nextPendingConnectionTimer, SIGNAL(timeout()), this, SLOT(slotNewClientConnection())); connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(slotNewClientConnection())); } @@ -114,7 +117,7 @@ void RiaSocketServer::slotNewClientConnection() { // If we are currently handling a connection, just ignore the new one until the current one is disconnected. - if (m_currentClient && (m_currentClient->state() == QAbstractSocket::ConnectedState) ) + if (m_currentClient && (m_currentClient->state() != QAbstractSocket::UnconnectedState) ) { //PMonLog("Starting Timer"); m_nextPendingConnectionTimer->start(); // Reset and start again @@ -318,7 +321,7 @@ void RiaSocketServer::terminateCurrentConnection() //-------------------------------------------------------------------------------------------------- void RiaSocketServer::handleNextPendingConnection() { - if (m_currentClient && (m_currentClient->state() == QAbstractSocket::ConnectedState) ) + if (m_currentClient && (m_currentClient->state() != QAbstractSocket::UnconnectedState) ) { //PMonLog("Starting Timer"); m_nextPendingConnectionTimer->start(); // Reset and start again diff --git a/ApplicationCode/SocketInterface/RiaSocketServer.h b/ApplicationCode/SocketInterface/RiaSocketServer.h index 2b55424629..1dd24af67b 100644 --- a/ApplicationCode/SocketInterface/RiaSocketServer.h +++ b/ApplicationCode/SocketInterface/RiaSocketServer.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -60,9 +62,9 @@ private slots: void slotNewClientConnection(); void slotCurrentClientDisconnected(); void slotReadyRead(); - void handleNextPendingConnection(); private: + void handleNextPendingConnection(); void terminateCurrentConnection(); bool readCommandFromOctave(); diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index 967c0b43b4..71e6d5cd47 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -1,5 +1,8 @@ +///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -34,7 +37,7 @@ #include "RimCellPropertyFilterCollection.h" #include "RimWellCollection.h" #include "Rim3dOverlayInfoConfig.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "RimInputPropertyCollection.h" diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.h b/ApplicationCode/SocketInterface/RiaSocketTools.h index b331799e2e..b324a25292 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.h +++ b/ApplicationCode/SocketInterface/RiaSocketTools.h @@ -1,5 +1,8 @@ +///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp b/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp index 4c9d935206..b8b3857ee7 100644 --- a/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp @@ -1,5 +1,8 @@ +///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -25,7 +28,7 @@ #include "RigCaseData.h" #include "RigCaseCellResultsData.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "RimCase.h" #include "RimInputCase.h" #include "RimInputPropertyCollection.h" diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index a1fe0b204e..5ebb970e73 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -19,51 +21,42 @@ #include "RiaStdInclude.h" #include "RiuMainWindow.h" -#include "RiaApplication.h" -#include "RimProject.h" +#include "RiaApplication.h" +#include "RiaBaseDefs.h" +#include "RiaPreferences.h" +#include "RiaRegressionTest.h" +#include "RigCaseCellResultsData.h" #include "RimAnalysisModels.h" +#include "RimCase.h" +#include "RimCaseCollection.h" +#include "RimCellPropertyFilterCollection.h" +#include "RimCommandObject.h" +#include "RimFaultCollection.h" #include "RimOilField.h" +#include "RimProject.h" +#include "RimReservoirCellResultsStorage.h" #include "RimReservoirView.h" -#include "RimUiTreeView.h" -#include "RimCase.h" #include "RimResultSlot.h" -#include "RimCellPropertyFilterCollection.h" +#include "RimTools.h" +#include "RimUiTreeModelPdm.h" +#include "RimUiTreeView.h" #include "RimWellCollection.h" -#include "RimReservoirCellResultsCacher.h" -#include "RimCaseCollection.h" #include "RimWellPathCollection.h" - -#include "RimUiTreeModelPdm.h" - -#include "RiaBaseDefs.h" -#include "RiuViewer.h" -#include "RiuResultInfoPanel.h" -#include "RiuProcessMonitor.h" +#include "RimWellPathImport.h" #include "RiuMultiCaseImportDialog.h" +#include "RiuProcessMonitor.h" +#include "RiuResultInfoPanel.h" +#include "RiuViewer.h" +#include "RiuWellImportWizard.h" -#include "RiaPreferences.h" - -#include "RigCaseCellResultsData.h" - -#include "cafAnimationToolBar.h" -#include "cafPdmUiPropertyView.h" #include "cafAboutDialog.h" -#include "cvfTimer.h" - +#include "cafAnimationToolBar.h" #include "cafPdmFieldCvfMat4d.h" - -#include "RimIdenticalGridCaseGroup.h" -#include "RimScriptCollection.h" -#include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RiuWellImportWizard.h" -#include "RimCalcScript.h" -#include "RimTools.h" -#include "RiaRegressionTest.h" #include "cafPdmUiPropertyDialog.h" +#include "cafPdmUiPropertyView.h" +#include "cvfTimer.h" //================================================================================================== @@ -214,7 +207,15 @@ void RiuMainWindow::createActions() m_saveProjectAsAction = new QAction(QIcon(":/Save.png"), "Save Project &As", this); m_closeProjectAction = new QAction("&Close Project", this); - m_exitAction = new QAction("E&xit", this); + + for (int i = 0; i < MaxRecentFiles; ++i) + { + m_recentFileActions[i] = new QAction(this); + m_recentFileActions[i]->setVisible(false); + connect(m_recentFileActions[i], SIGNAL(triggered()), this, SLOT(slotOpenRecentFile())); + } + + m_exitAction = new QAction("E&xit", this); connect(m_openProjectAction, SIGNAL(triggered()), SLOT(slotOpenProject())); connect(m_openLastUsedProjectAction, SIGNAL(triggered()), SLOT(slotOpenLastUsedProject())); @@ -324,13 +325,53 @@ void RiuMainWindow::createActions() } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class ToolTipableMenu : public QMenu +{ +public: + ToolTipableMenu( QWidget * parent ) : QMenu( parent ) {}; + + bool event(QEvent* e) + { + if (e->type() == QEvent::ToolTip) + { + QHelpEvent* he = dynamic_cast(e); + QAction* act = actionAt(he->pos()); + if (act) + { + // Remove ampersand as this is used to define shortcut key + QString actionTextWithoutAmpersand = act->text().remove("&"); + + if (actionTextWithoutAmpersand != act->toolTip()) + { + QToolTip::showText(he->globalPos(), act->toolTip(), this); + } + + return true; + } + } + else if (e->type() == QEvent::Paint && QToolTip::isVisible()) + { + QToolTip::hideText(); + } + + return QMenu::event(e); + } +}; + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuMainWindow::createMenus() { // File menu - QMenu* fileMenu = menuBar()->addMenu("&File"); + QMenu* fileMenu = new ToolTipableMenu(menuBar()); + fileMenu->setTitle("&File"); + + menuBar()->addMenu(fileMenu); fileMenu->addAction(m_openProjectAction); fileMenu->addAction(m_openLastUsedProjectAction); @@ -352,6 +393,12 @@ void RiuMainWindow::createMenus() fileMenu->addAction(m_saveProjectAction); fileMenu->addAction(m_saveProjectAsAction); + m_recentFilesSeparatorAction = fileMenu->addSeparator(); + for (int i = 0; i < MaxRecentFiles; ++i) + fileMenu->addAction(m_recentFileActions[i]); + + updateRecentFileActions(); + fileMenu->addSeparator(); QMenu* testMenu = fileMenu->addMenu("&Testing"); @@ -661,10 +708,7 @@ void RiuMainWindow::refreshAnimationActions() if (app->activeReservoirView()->currentGridCellResults()) { - if (app->activeReservoirView()->cellResult()->hasDynamicResult() - || app->activeReservoirView()->propertyFilterCollection()->hasActiveDynamicFilters() - || app->activeReservoirView()->wellCollection()->hasVisibleWellPipes() - || app->activeReservoirView()->cellResult()->isTernarySaturationSelected()) + if (app->activeReservoirView()->isTimeStepDependentDataVisible()) { std::vector timeStepDates = app->activeReservoirView()->currentGridCellResults()->cellResults()->timeStepDates(0); bool showHoursAndMinutes = false; @@ -719,7 +763,7 @@ void RiuMainWindow::slotAbout() dlg.setApplicationName(RI_APPLICATION_NAME); dlg.setApplicationVersion(RiaApplication::getVersionStringApp(true)); - dlg.setCopyright("Copyright 2011-2013 Statoil ASA, Ceetron AS"); + dlg.setCopyright("Copyright Statoil ASA, Ceetron Solutions AS, Ceetron AS"); dlg.showQtVersion(false); #ifdef _DEBUG dlg.setIsDebugBuild(true); @@ -763,7 +807,10 @@ void RiuMainWindow::slotImportEclipseCase() if (!fileNames.isEmpty()) { - app->openEclipseCaseFromFile(fileName); + if (app->openEclipseCaseFromFile(fileName)) + { + addRecentFiles(fileName); + } } } } @@ -807,7 +854,10 @@ void RiuMainWindow::slotOpenProject() // Remember the path to next time app->setDefaultFileDialogDirectory("BINARY_GRID", QFileInfo(fileName).absolutePath()); - app->loadProject(fileName); + if (app->loadProject(fileName)) + { + addRecentFiles(fileName); + } } } @@ -819,8 +869,11 @@ void RiuMainWindow::slotOpenLastUsedProject() { RiaApplication* app = RiaApplication::instance(); QString fileName = app->preferences()->lastUsedProjectFileName; - app->loadProject(fileName); - + + if (app->loadProject(fileName)) + { + addRecentFiles(fileName); + } } //-------------------------------------------------------------------------------------------------- @@ -937,6 +990,92 @@ void RiuMainWindow::slotCloseProject() bool ret = app->closeProject(true); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::slotOpenRecentFile() +{ + QAction *action = qobject_cast(sender()); + if (action) + { + QString filename = action->data().toString(); + bool loadingSucceded = false; + + if (filename.contains(".rsp", Qt::CaseInsensitive) || filename.contains(".rip", Qt::CaseInsensitive) ) + { + loadingSucceded = RiaApplication::instance()->loadProject(action->data().toString()); + } + else if ( filename.contains(".egrid", Qt::CaseInsensitive) || filename.contains(".grid", Qt::CaseInsensitive) ) + { + loadingSucceded = RiaApplication::instance()->openEclipseCaseFromFile(filename); + } + + if (loadingSucceded) + { + addRecentFiles(filename); + } + else + { + removeRecentFiles(filename); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::updateRecentFileActions() +{ + QSettings settings; + QStringList files = settings.value("recentFileList").toStringList(); + + int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles); + + for (int i = 0; i < numRecentFiles; ++i) { + QString text = tr("&%1 %2").arg(i + 1).arg(QFileInfo(files[i]).fileName()); + m_recentFileActions[i]->setText(text); + m_recentFileActions[i]->setData(files[i]); + m_recentFileActions[i]->setToolTip(files[i]); + m_recentFileActions[i]->setVisible(true); + } + for (int j = numRecentFiles; j < MaxRecentFiles; ++j) + m_recentFileActions[j]->setVisible(false); + + m_recentFilesSeparatorAction->setVisible(numRecentFiles > 0); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::addRecentFiles(const QString& file) +{ + QSettings settings; + QStringList files = settings.value("recentFileList").toStringList(); + files.removeAll(file); + files.prepend(file); + while (files.size() > MaxRecentFiles) + files.removeLast(); + + settings.setValue("recentFileList", files); + + updateRecentFileActions(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::removeRecentFiles(const QString& file) +{ + QSettings settings; + QStringList files = settings.value("recentFileList").toStringList(); + files.removeAll(file); + + settings.setValue("recentFileList", files); + + updateRecentFileActions(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1842,7 +1981,7 @@ void RiuMainWindow::slotAddWellCellsToRangeFilterAction(bool doAdd) //-------------------------------------------------------------------------------------------------- void RiuMainWindow::slotOpenUsersGuideInBrowserAction() { - QString usersGuideUrl = "https://github.com/OPM/ResInsight/wiki"; + QString usersGuideUrl = "http://resinsight.org/"; if (!QDesktopServices::openUrl(usersGuideUrl)) { @@ -1873,3 +2012,15 @@ void RiuMainWindow::appendActionsContextMenuForPdmObject(caf::PdmObject* pdmObje menu->addAction(m_openMultipleEclipseCasesAction); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::setExpanded(const caf::PdmObject* pdmObject, bool expanded) +{ + QModelIndex mi = m_treeModelPdm->getModelIndexFromPdmObject(pdmObject); + if (m_treeView && mi.isValid()) + { + m_treeView->setExpanded(mi, expanded); + } +} diff --git a/ApplicationCode/UserInterface/RiuMainWindow.h b/ApplicationCode/UserInterface/RiuMainWindow.h index ae3f922af3..8ce06d71b1 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.h +++ b/ApplicationCode/UserInterface/RiuMainWindow.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -97,7 +99,8 @@ class RiuMainWindow : public QMainWindow void appendActionsContextMenuForPdmObject(caf::PdmObject* pdmObject, QMenu* menu); void refreshDrawStyleActions(); - + + void setExpanded(const caf::PdmObject* pdmObject, bool expanded); protected: virtual void closeEvent(QCloseEvent* event); @@ -111,7 +114,9 @@ class RiuMainWindow : public QMainWindow bool checkForDocumentModifications(); - void updateMRUList(const QString &fileName, bool remove = false); + void updateRecentFileActions(); + void addRecentFiles(const QString& file); + void removeRecentFiles(const QString& file); QMdiSubWindow* findMdiSubWindow(RiuViewer* viewer); @@ -137,6 +142,13 @@ class RiuMainWindow : public QMainWindow QAction* m_closeProjectAction; QAction* m_exitAction; + // Recent files + enum { MaxRecentFiles = 5 }; + QAction* m_recentFilesSeparatorAction; + QMenu* m_recentFilesMenu; + QAction* m_recentFileActions[MaxRecentFiles]; + + // Edit actions QAction* m_editPreferences; QAction* m_newPropertyView; @@ -203,6 +215,8 @@ private slots: void slotSaveProjectAs(); void slotCloseProject(); + void slotOpenRecentFile(); + void slotRefreshFileActions(); // Edit slots diff --git a/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp b/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp new file mode 100644 index 0000000000..a21b951e17 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp @@ -0,0 +1,663 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "RiuResultTextBuilder.h" + +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigMainGrid.h" +#include "RigResultAccessor.h" +#include "RigResultAccessorFactory.h" + +#include "RimCase.h" +#include "RimCellEdgeResultSlot.h" +#include "RimFaultResultSlot.h" +#include "RimReservoirCellResultsStorage.h" +#include "RimReservoirView.h" +#include "RimResultSlot.h" + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuResultTextBuilder::RiuResultTextBuilder(RimReservoirView* reservoirView, size_t gridIndex, size_t cellIndex, size_t timeStepIndex) +{ + CVF_ASSERT(reservoirView); + + m_reservoirView = reservoirView; + m_gridIndex = gridIndex; + m_cellIndex = cellIndex; + m_timeStepIndex = timeStepIndex; + + m_nncIndex = cvf::UNDEFINED_SIZE_T; + m_intersectionPoint = cvf::Vec3d::UNDEFINED; + m_face = cvf::StructGridInterface::NO_FACE; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuResultTextBuilder::setNncIndex(size_t nncIndex) +{ + m_nncIndex = nncIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuResultTextBuilder::setIntersectionPoint(cvf::Vec3d intersectionPoint) +{ + m_intersectionPoint = intersectionPoint; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuResultTextBuilder::setFace(cvf::StructGridInterface::FaceType face) +{ + m_face = face; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuResultTextBuilder::mainResultText() +{ + QString text; + + // Produce result text for all variants + // Priority defined as follows : NNC, Fault, Grid + { + QString nncText = nncResultText(); + QString faultText = faultResultText(); + + if (!nncText.isEmpty()) + { + text = "NNC : " + nncText; + } + else if (!faultResultText().isEmpty()) + { + text = "Fault : " + faultText; + } + else + { + text = "Grid cell : " + gridResultText(); + } + + text += "\n"; + } + + QString topoText = this->topologyText("\n"); + text += topoText; + text += "\n"; + + appendDetails(text, nncDetails()); + + appendDetails(text, faultResultDetails()); + + appendDetails(text, cellEdgeResultDetails()); + + appendDetails(text, gridResultDetails()); + + appendDetails(text, wellResultText()); + + return text; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuResultTextBuilder::topologyText(QString itemSeparator) +{ + QString text; + + if (m_reservoirView->eclipseCase()) + { + const RigCaseData* eclipseCase = m_reservoirView->eclipseCase()->reservoirData(); + if (eclipseCase) + { + size_t i = 0; + size_t j = 0; + size_t k = 0; + if (eclipseCase->grid(m_gridIndex)->ijkFromCellIndex(m_cellIndex, &i, &j, &k)) + { + // Adjust to 1-based Eclipse indexing + i++; + j++; + k++; + + cvf::Vec3d domainCoord = m_intersectionPoint + eclipseCase->grid(m_gridIndex)->displayModelOffset(); + + cvf::StructGridInterface::FaceEnum faceEnum(m_face); + + QString faceText = faceEnum.text(); + + text += QString("Face : %1").arg(faceText) + itemSeparator; + text += QString("Hit grid %1").arg(m_gridIndex) + itemSeparator; + text += QString("Cell : [%1, %2, %3]").arg(i).arg(j).arg(k) + itemSeparator; + + QString formattedText; + formattedText.sprintf("Intersection point : [E: %.2f, N: %.2f, Depth: %.2f]", domainCoord.x(), domainCoord.y(), -domainCoord.z()); + + text += formattedText; + } + } + } + + return text; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuResultTextBuilder::gridResultDetails() +{ + QString text; + + if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) + { + RigCaseData* eclipseCaseData = m_reservoirView->eclipseCase()->reservoirData(); + RigGridBase* grid = eclipseCaseData->grid(m_gridIndex); + + this->appendTextFromResultSlot(eclipseCaseData, m_gridIndex, m_cellIndex, m_timeStepIndex, m_reservoirView->cellResult(), &text); + + if (!text.isEmpty()) + { + text.prepend("-- Grid cell result details --\n"); + } + } + + return text; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuResultTextBuilder::faultResultDetails() +{ + QString text; + + if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) + { + RigCaseData* eclipseCaseData = m_reservoirView->eclipseCase()->reservoirData(); + RigGridBase* grid = eclipseCaseData->grid(m_gridIndex); + RigMainGrid* mainGrid = grid->mainGrid(); + + const RigFault* fault = mainGrid->findFaultFromCellIndexAndCellFace(m_cellIndex, m_face); + if (fault) + { + text += "-- Fault result details --\n"; + + text += QString("Fault Name: %1\n").arg(fault->name()); + + cvf::StructGridInterface::FaceEnum faceHelper(m_face); + text += "Fault Face : " + faceHelper.text() + "\n"; + + if (m_reservoirView->faultResultSettings()->hasValidCustomResult()) + { + text += "Fault result data:\n"; + this->appendTextFromResultSlot(eclipseCaseData, m_gridIndex, m_cellIndex, m_timeStepIndex, m_reservoirView->currentFaultResultSlot(), &text); + } + } + } + + return text; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuResultTextBuilder::gridResultText() +{ + QString text = cellResultText(m_reservoirView->cellResult()); + + return text; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuResultTextBuilder::faultResultText() +{ + QString text; + + if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) + { + RigCaseData* eclipseCaseData = m_reservoirView->eclipseCase()->reservoirData(); + RigGridBase* grid = eclipseCaseData->grid(m_gridIndex); + RigMainGrid* mainGrid = grid->mainGrid(); + + const RigFault* fault = mainGrid->findFaultFromCellIndexAndCellFace(m_cellIndex, m_face); + if (fault) + { + cvf::StructGridInterface::FaceEnum faceHelper(m_face); + if (m_reservoirView->faultResultSettings()->hasValidCustomResult()) + { + text = cellResultText(m_reservoirView->currentFaultResultSlot()); + } + } + } + + return text; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuResultTextBuilder::nncResultText() +{ + QString text; + + if (m_nncIndex != cvf::UNDEFINED_SIZE_T) + { + if (m_reservoirView.notNull() && m_reservoirView->eclipseCase()) + { + RigCaseData* eclipseCase = m_reservoirView->eclipseCase()->reservoirData(); + + RigMainGrid* grid = eclipseCase->mainGrid(); + CVF_ASSERT(grid); + + RigNNCData* nncData = grid->nncData(); + CVF_ASSERT(nncData); + + if (nncData) + { + const RigConnection& conn = nncData->connections()[m_nncIndex]; + cvf::StructGridInterface::FaceEnum face(conn.m_c1Face); + + if (m_reservoirView->currentFaultResultSlot()) + { + size_t scalarResultIdx = m_reservoirView->currentFaultResultSlot()->scalarResultIndex(); + const std::vector* nncValues = nncData->connectionScalarResult(scalarResultIdx); + if (nncValues) + { + QString resultVar = m_reservoirView->currentFaultResultSlot()->resultVariable(); + double scalarValue = (*nncValues)[m_nncIndex]; + + text = QString("%1 : %2").arg(resultVar).arg(scalarValue); + } + } + } + } + } + + return text; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuResultTextBuilder::appendTextFromResultSlot(RigCaseData* eclipseCase, size_t gridIndex, size_t cellIndex, size_t timeStepIndex, RimResultSlot* resultSlot, QString* resultInfoText) +{ + if (!resultSlot) + { + return; + } + + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultSlot->porosityModel()); + if (resultSlot->isTernarySaturationSelected()) + { + RimReservoirCellResultsStorage* gridCellResults = resultSlot->currentGridCellResults(); + if (gridCellResults) + { + size_t soilScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); + size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); + size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); + + cvf::ref dataAccessObjectX = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, soilScalarSetIndex); + cvf::ref dataAccessObjectY = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, sgasScalarSetIndex); + cvf::ref dataAccessObjectZ = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, swatScalarSetIndex); + + double scalarValue = 0.0; + + if (dataAccessObjectX.notNull()) scalarValue = dataAccessObjectX->cellScalar(cellIndex); + else scalarValue = 0.0; + resultInfoText->append(QString("SOIL : %1\n").arg(scalarValue)); + + if (dataAccessObjectY.notNull()) scalarValue = dataAccessObjectY->cellScalar(cellIndex); + else scalarValue = 0.0; + resultInfoText->append(QString("SGAS : %1\n").arg(scalarValue)); + + if (dataAccessObjectZ.notNull()) scalarValue = dataAccessObjectZ->cellScalar(cellIndex); + else scalarValue = 0.0; + resultInfoText->append(QString("SWAT : %1\n").arg(scalarValue)); + } + } + else if (resultSlot->hasResult()) + { + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultSlot->porosityModel()); + cvf::ref resultAccessor; + + if (resultSlot->hasStaticResult()) + { + if (resultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) + { + cvf::ref transResultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedTransmissibilityResultName()); + { + double scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); + resultInfoText->append(QString("Tran X : %1\n").arg(scalarValue)); + + scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); + resultInfoText->append(QString("Tran Y : %1\n").arg(scalarValue)); + + scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); + resultInfoText->append(QString("Tran Z : %1\n").arg(scalarValue)); + } + } + else if (resultSlot->resultVariable().compare(RimDefines::combinedMultResultName(), Qt::CaseInsensitive) == 0) + { + cvf::ref multResultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedMultResultName()); + { + double scalarValue = 0.0; + + scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); + resultInfoText->append(QString("MULTX : %1\n").arg(scalarValue)); + scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::NEG_I); + resultInfoText->append(QString("MULTX- : %1\n").arg(scalarValue)); + + scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); + resultInfoText->append(QString("MULTY : %1\n").arg(scalarValue)); + scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::NEG_J); + resultInfoText->append(QString("MULTY- : %1\n").arg(scalarValue)); + + scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); + resultInfoText->append(QString("MULTZ : %1\n").arg(scalarValue)); + scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::NEG_K); + resultInfoText->append(QString("MULTZ- : %1\n").arg(scalarValue)); + } + } + else if (resultSlot->resultVariable().compare(RimDefines::combinedRiTranResultName(), Qt::CaseInsensitive) == 0) + { + cvf::ref transResultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiTranResultName()); + { + double scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); + resultInfoText->append(QString("riTran X : %1\n").arg(scalarValue)); + + scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); + resultInfoText->append(QString("riTran Y : %1\n").arg(scalarValue)); + + scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); + resultInfoText->append(QString("riTran Z : %1\n").arg(scalarValue)); + } + } + else if (resultSlot->resultVariable().compare(RimDefines::combinedRiMultResultName(), Qt::CaseInsensitive) == 0) + { + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiMultResultName()); + { + double scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); + resultInfoText->append(QString("riMult X : %1\n").arg(scalarValue)); + + scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); + resultInfoText->append(QString("riMult Y : %1\n").arg(scalarValue)); + + scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); + resultInfoText->append(QString("riMult Z : %1\n").arg(scalarValue)); + } + } + else if (resultSlot->resultVariable().compare(RimDefines::combinedRiAreaNormTranResultName(), Qt::CaseInsensitive) == 0) + { + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiAreaNormTranResultName()); + { + double scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); + resultInfoText->append(QString("riTransByArea X : %1\n").arg(scalarValue)); + + scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); + resultInfoText->append(QString("riTransByArea Y : %1\n").arg(scalarValue)); + + scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); + resultInfoText->append(QString("riTransByArea Z : %1\n").arg(scalarValue)); + } + } + else + { + resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, resultSlot->scalarResultIndex()); + } + } + else + { + resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, resultSlot->scalarResultIndex()); + } + + if (resultAccessor.notNull()) + { + double scalarValue = resultAccessor->cellScalar(cellIndex); + resultInfoText->append("Cell result : "); + resultInfoText->append(resultSlot->resultVariable()); + resultInfoText->append(QString(" : %1\n").arg(scalarValue)); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuResultTextBuilder::cellEdgeResultDetails() +{ + QString text; + + if (m_reservoirView->cellEdgeResult()->hasResult()) + { + size_t resultIndices[6]; + QStringList resultNames; + m_reservoirView->cellEdgeResult()->gridScalarIndices(resultIndices); + m_reservoirView->cellEdgeResult()->gridScalarResultNames(&resultNames); + + text += "-- Cell edge result data --\n"; + for (int idx = 0; idx < 6; idx++) + { + if (resultIndices[idx] == cvf::UNDEFINED_SIZE_T) continue; + + // Cell edge results are static, results are loaded for first time step only + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(m_reservoirView->cellResult()->porosityModel()); + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(m_reservoirView->eclipseCase()->reservoirData(), m_gridIndex, porosityModel, 0, resultIndices[idx]); + if (resultAccessor.notNull()) + { + double scalarValue = resultAccessor->cellScalar(m_cellIndex); + text.append(QString("%1 : %2\n").arg(resultNames[idx]).arg(scalarValue)); + } + } + } + + return text; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuResultTextBuilder::nncDetails() +{ + QString text; + + if (m_nncIndex != cvf::UNDEFINED_SIZE_T) + { + if (m_reservoirView.notNull() && m_reservoirView->eclipseCase()) + { + RigCaseData* eclipseCase = m_reservoirView->eclipseCase()->reservoirData(); + + RigMainGrid* grid = eclipseCase->mainGrid(); + CVF_ASSERT(grid); + + RigNNCData* nncData = grid->nncData(); + CVF_ASSERT(nncData); + + if (nncData) + { + text += "-- NNC details --\n"; + { + const RigConnection& conn = nncData->connections()[m_nncIndex]; + cvf::StructGridInterface::FaceEnum face(conn.m_c1Face); + + // First cell of NNC + { + CVF_ASSERT(conn.m_c1GlobIdx < grid->cells().size()); + const RigCell& cell = grid->cells()[conn.m_c1GlobIdx]; + + RigGridBase* hostGrid = cell.hostGrid(); + size_t gridLocalCellIndex = cell.gridLocalCellIndex(); + + size_t i, j, k; + if (hostGrid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k)) + { + // Adjust to 1-based Eclipse indexing + i++; + j++; + k++; + + QString gridName = QString::fromStdString(hostGrid->gridName()); + text.append(QString("NNC 1 : cell [%1, %2, %3] face %4 (%5)\n").arg(i).arg(j).arg(k).arg(face.text()).arg(gridName)); + } + } + + // Second cell of NNC + { + CVF_ASSERT(conn.m_c2GlobIdx < grid->cells().size()); + const RigCell& cell = grid->cells()[conn.m_c2GlobIdx]; + + RigGridBase* hostGrid = cell.hostGrid(); + size_t gridLocalCellIndex = cell.gridLocalCellIndex(); + + size_t i, j, k; + if (hostGrid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k)) + { + // Adjust to 1-based Eclipse indexing + i++; + j++; + k++; + + QString gridName = QString::fromStdString(hostGrid->gridName()); + cvf::StructGridInterface::FaceEnum oppositeFaceEnum(cvf::StructGridInterface::oppositeFace(face)); + QString faceText = oppositeFaceEnum.text(); + + text.append(QString("NNC 2 : cell [%1, %2, %3] face %4 (%5)\n").arg(i).arg(j).arg(k).arg(faceText).arg(gridName)); + } + } + } + } + } + } + + return text; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuResultTextBuilder::appendDetails(QString& text, const QString& details) +{ + if (!details.isEmpty()) + { + text += "\n"; + text += details; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuResultTextBuilder::cellResultText(RimResultSlot* resultSlot) +{ + QString text; + + if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) + { + RigCaseData* eclipseCaseData = m_reservoirView->eclipseCase()->reservoirData(); + RigGridBase* grid = eclipseCaseData->grid(m_gridIndex); + + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultSlot->porosityModel()); + + QString resultVar = resultSlot->resultVariable(); + + if (resultSlot->isTernarySaturationSelected()) + { + RimReservoirCellResultsStorage* gridCellResults = m_reservoirView->cellResult()->currentGridCellResults(); + if (gridCellResults) + { + size_t soilScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); + size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); + size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); + + cvf::ref dataAccessObjectX = RigResultAccessorFactory::createResultAccessor(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, soilScalarSetIndex); + cvf::ref dataAccessObjectY = RigResultAccessorFactory::createResultAccessor(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, sgasScalarSetIndex); + cvf::ref dataAccessObjectZ = RigResultAccessorFactory::createResultAccessor(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, swatScalarSetIndex); + + double scalarValue = 0.0; + + if (dataAccessObjectX.notNull()) scalarValue = dataAccessObjectX->cellScalar(m_cellIndex); + else scalarValue = 0.0; + text += QString("SOIL : %1 ").arg(scalarValue); + + if (dataAccessObjectY.notNull()) scalarValue = dataAccessObjectY->cellScalar(m_cellIndex); + else scalarValue = 0.0; + text += QString("SGAS : %1 ").arg(scalarValue); + + if (dataAccessObjectZ.notNull()) scalarValue = dataAccessObjectZ->cellScalar(m_cellIndex); + else scalarValue = 0.0; + text += QString("SWAT : %1 ").arg(scalarValue); + } + } + else + { + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, resultVar); + if (resultAccessor.notNull()) + { + double scalarValue = resultAccessor->cellFaceScalar(m_cellIndex, m_face); + text = QString("%1 : %2").arg(resultVar).arg(scalarValue); + } + } + } + + return text; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuResultTextBuilder::wellResultText() +{ + QString text; + + if (m_reservoirView->eclipseCase() && + m_reservoirView->eclipseCase()->reservoirData() ) + { + cvf::Collection wellResults = m_reservoirView->eclipseCase()->reservoirData()->wellResults(); + for (size_t i = 0; i < wellResults.size(); i++) + { + RigSingleWellResultsData* singleWellResultData = wellResults.at(i); + + if (m_timeStepIndex < static_cast(singleWellResultData->firstResultTimeStep())) + { + continue; + } + + const RigWellResultFrame& wellResultFrame = singleWellResultData->wellResultFrame(m_timeStepIndex); + const RigWellResultPoint* wellResultCell = wellResultFrame.findResultCell(m_gridIndex, m_cellIndex); + if (wellResultCell) + { + text += QString("-- Well-cell connection info --\n Well Name: %1\n Branch Id: %2\n Segment Id: %3\n").arg(singleWellResultData->m_wellName).arg(wellResultCell->m_ertBranchId).arg(wellResultCell->m_ertSegmentId); + } + } + } + + return text; +} + diff --git a/ApplicationCode/UserInterface/RiuResultTextBuilder.h b/ApplicationCode/UserInterface/RiuResultTextBuilder.h new file mode 100644 index 0000000000..0b7aaede2c --- /dev/null +++ b/ApplicationCode/UserInterface/RiuResultTextBuilder.h @@ -0,0 +1,81 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// 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 "cvfBase.h" +#include "cafPdmPointer.h" +#include "cvfStructGrid.h" + + +class RimReservoirView; +class RimResultSlot; +class QString; +class RigCaseData; + +namespace cvf { + class Part; +} + +//================================================================================================== +// +// +//================================================================================================== +class RiuResultTextBuilder +{ +public: + RiuResultTextBuilder(RimReservoirView* reservoirView, size_t gridIndex, size_t cellIndex, size_t timeStepIndex); + void setFace(cvf::StructGridInterface::FaceType face); + void setNncIndex(size_t nncIndex); + void setIntersectionPoint(cvf::Vec3d intersectionPoint); + + QString mainResultText(); + + QString topologyText(QString itemSeparator); + +private: + void appendDetails(QString& text, const QString& details); + + QString gridResultDetails(); + QString faultResultDetails(); + QString cellEdgeResultDetails(); + QString nncDetails(); + + QString gridResultText(); + QString faultResultText(); + QString nncResultText(); + QString wellResultText(); + + QString cellResultText(RimResultSlot* resultSlot); + + void appendTextFromResultSlot(RigCaseData* eclipseCase, size_t gridIndex, size_t cellIndex, size_t timeStepIndex, RimResultSlot* resultSlot, QString* resultInfoText); + +private: + caf::PdmPointer m_reservoirView; + + size_t m_gridIndex; + size_t m_cellIndex; + size_t m_timeStepIndex; + + cvf::StructGridInterface::FaceType m_face; + + size_t m_nncIndex; + + cvf::Vec3d m_intersectionPoint; +}; diff --git a/ApplicationCode/UserInterface/RiuViewer.cpp b/ApplicationCode/UserInterface/RiuViewer.cpp index 354cc30af3..730db7629c 100644 --- a/ApplicationCode/UserInterface/RiuViewer.cpp +++ b/ApplicationCode/UserInterface/RiuViewer.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -25,17 +27,18 @@ #include "RimReservoirView.h" +#include "Rim3dOverlayInfoConfig.h" #include "RimCase.h" -#include "RimResultSlot.h" #include "RimCellEdgeResultSlot.h" -#include "RimCellRangeFilterCollection.h" #include "RimCellPropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" +#include "RimCellRangeFilterCollection.h" +#include "RimFaultCollection.h" +#include "RimResultSlot.h" #include "RimWellCollection.h" #include "RimUiTreeModelPdm.h" -#include "RimReservoirCellResultsCacher.h" +#include "RimReservoirCellResultsStorage.h" #include "RigCaseData.h" @@ -47,6 +50,7 @@ #include "cafPdmFieldCvfColor.h" #include "cafPdmFieldCvfMat4d.h" #include "RivSourceInfo.h" +#include "RiuResultTextBuilder.h" using cvf::ManipulatorTrackball; @@ -145,55 +149,6 @@ RiuViewer::~RiuViewer() } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuViewer::setColorLegend1(cvf::OverlayScalarMapperLegend* legend) -{ - m_mainRendering->removeOverlayItem(m_legend1.p()); - - m_legend1 = legend; - - this->updateLegends(); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuViewer::setColorLegend2(cvf::OverlayScalarMapperLegend* legend) -{ - m_mainRendering->removeOverlayItem(m_legend2.p()); - - m_legend2 = legend; - - this->updateLegends(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuViewer::updateLegends() -{ - cvf::Rendering* firstRendering = m_renderingSequence->firstRendering(); - CVF_ASSERT(firstRendering); - - firstRendering->removeOverlayItem(m_legend1.p()); - firstRendering->removeOverlayItem(m_legend2.p()); - - if (m_legend1.notNull()) - { - m_legend1->setLayout(cvf::OverlayItem::VERTICAL, cvf::OverlayItem::BOTTOM_LEFT); - firstRendering->addOverlayItem(m_legend1.p()); - } - - if (m_legend2.notNull()) - { - m_legend2->setLayout(cvf::OverlayItem::VERTICAL, cvf::OverlayItem::BOTTOM_LEFT); - firstRendering->addOverlayItem(m_legend2.p()); - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -263,8 +218,9 @@ void RiuViewer::mouseReleaseEvent(QMouseEvent* event) uint faceIndex = cvf::UNDEFINED_UINT; cvf::Vec3d localIntersectionPoint(cvf::Vec3d::ZERO); - cvf::Part * firstHitPart = NULL; - firstHitPart = pickPointAndFace(winPosX, winPosY, &faceIndex, &localIntersectionPoint); + cvf::Part* firstHitPart = NULL; + cvf::Part* nncFirstHitPart = NULL; + pickPointAndFace(winPosX, winPosY, &localIntersectionPoint, &firstHitPart, &faceIndex, &nncFirstHitPart, NULL); if (firstHitPart) { if (faceIndex != cvf::UNDEFINED_UINT) @@ -274,15 +230,28 @@ void RiuViewer::mouseReleaseEvent(QMouseEvent* event) const RivSourceInfo* rivSourceInfo = dynamic_cast(firstHitPart->sourceInfo()); if (rivSourceInfo) { - if (rivSourceInfo->hasCellIndices()) + if (rivSourceInfo->hasCellFaceMapping()) { m_currentGridIdx = firstHitPart->id(); - m_currentCellIndex = rivSourceInfo->m_cellIndices->get(faceIndex); + m_currentCellIndex = rivSourceInfo->m_cellFaceFromTriangleMapper->cellIndex(faceIndex); + m_currentFaceIndex = rivSourceInfo->m_cellFaceFromTriangleMapper->cellFace(faceIndex); QMenu menu; + menu.addAction(QString("I-slice range filter"), this, SLOT(slotRangeFilterI())); menu.addAction(QString("J-slice range filter"), this, SLOT(slotRangeFilterJ())); menu.addAction(QString("K-slice range filter"), this, SLOT(slotRangeFilterK())); + + const RigCaseData* reservoir = m_reservoirView->eclipseCase()->reservoirData(); + const RigFault* fault = reservoir->mainGrid()->findFaultFromCellIndexAndCellFace(m_currentCellIndex, m_currentFaceIndex); + if (fault) + { + menu.addSeparator(); + + QString faultName = fault->name(); + menu.addAction(QString("Hide ") + faultName, this, SLOT(slotHideFault())); + } + menu.exec(event->globalPos()); } } @@ -324,6 +293,8 @@ void RiuViewer::slotRangeFilterI() mainWindow->setCurrentObjectInTreeView(rangeFilter); } + + m_reservoirView->setShowFaultsOnly(false); } //-------------------------------------------------------------------------------------------------- @@ -357,6 +328,8 @@ void RiuViewer::slotRangeFilterJ() mainWindow->setCurrentObjectInTreeView(rangeFilter); } + + m_reservoirView->setShowFaultsOnly(false); } //-------------------------------------------------------------------------------------------------- @@ -390,6 +363,8 @@ void RiuViewer::slotRangeFilterK() mainWindow->setCurrentObjectInTreeView(rangeFilter); } + + m_reservoirView->setShowFaultsOnly(false); } //-------------------------------------------------------------------------------------------------- @@ -404,7 +379,6 @@ void RiuViewer::keyPressEvent(QKeyEvent* event) } } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -415,65 +389,67 @@ void RiuViewer::handlePickAction(int winPosX, int winPosY) RiuMainWindow* mainWnd = RiuMainWindow::instance(); if (!mainWnd) return; - QString pickInfo = "No hits"; - QString resultInfo = ""; - - uint faceIndex = cvf::UNDEFINED_UINT; + size_t gridIndex = cvf::UNDEFINED_SIZE_T; + size_t cellIndex = cvf::UNDEFINED_SIZE_T; + size_t nncIndex = cvf::UNDEFINED_SIZE_T; + cvf::StructGridInterface::FaceType face = cvf::StructGridInterface::NO_FACE; cvf::Vec3d localIntersectionPoint(cvf::Vec3d::ZERO); - cvf::Part * firstHitPart = NULL; - firstHitPart = pickPointAndFace(winPosX, winPosY, &faceIndex, &localIntersectionPoint); - if (firstHitPart) { - // If a drawable geometry was hit, get info about the picked geometry - // and possibly the picked scalar value, if any - if (faceIndex != cvf::UNDEFINED_UINT) - { - size_t gridIndex = firstHitPart->id(); + cvf::Part* firstHitPart = NULL; + uint firstPartFaceIndex = cvf::UNDEFINED_UINT; + + cvf::Part* firstNncHitPart = NULL; + uint nncPartFaceIndex = cvf::UNDEFINED_UINT; + pickPointAndFace(winPosX, winPosY, &localIntersectionPoint, &firstHitPart, &firstPartFaceIndex, &firstNncHitPart, &nncPartFaceIndex); + + if (firstHitPart) + { + gridIndex = firstHitPart->id(); if (firstHitPart->sourceInfo()) { const RivSourceInfo* rivSourceInfo = dynamic_cast(firstHitPart->sourceInfo()); if (rivSourceInfo) { - if (rivSourceInfo->hasCellIndices()) - { - size_t cellIndex = cvf::UNDEFINED_SIZE_T; - cellIndex = rivSourceInfo->m_cellIndices->get(faceIndex); - - CVF_ASSERT(rivSourceInfo->m_faceTypes.notNull()); - cvf::StructGridInterface::FaceType face = rivSourceInfo->m_faceTypes->get(faceIndex); - - m_reservoirView->pickInfo(gridIndex, cellIndex, face, localIntersectionPoint, &pickInfo); - - // Build up result from from both pick info and result values - m_reservoirView->pickInfo(gridIndex, cellIndex, face, localIntersectionPoint, &resultInfo); - resultInfo += "\n"; - m_reservoirView->appendCellResultInfo(gridIndex, cellIndex, face, &resultInfo); -#if 0 - const RigCaseData* reservoir = m_reservoirView->eclipseCase()->reservoirData(); - const RigGridBase* grid = reservoir->grid(gridIndex); - const RigCell& cell = grid->cell(cellIndex); - const caf::SizeTArray8& cellNodeIndices = cell.cornerIndices(); - const std::vector& nodes = reservoir->mainGrid()->nodes(); - for (int i = 0; i < 8; ++i) - { - resultInfo += QString::number(i) + " : "; - for (int j = 0; j < 3; ++j) - resultInfo += QString::number(nodes[cellNodeIndices[i]][j], 'g', 10) + " "; - resultInfo += "\n"; - } -#endif - } - else if (rivSourceInfo->m_NNCIndices.notNull()) + if (rivSourceInfo->hasCellFaceMapping()) { - size_t nncIndex = rivSourceInfo->m_NNCIndices->get(faceIndex); + CVF_ASSERT(rivSourceInfo->m_cellFaceFromTriangleMapper.notNull()); - m_reservoirView->appendNNCResultInfo(nncIndex, &resultInfo); + cellIndex = rivSourceInfo->m_cellFaceFromTriangleMapper->cellIndex(firstPartFaceIndex); + face = rivSourceInfo->m_cellFaceFromTriangleMapper->cellFace(firstPartFaceIndex); } } } } + + + if (firstNncHitPart && firstNncHitPart->sourceInfo()) + { + const RivSourceInfo* rivSourceInfo = dynamic_cast(firstNncHitPart->sourceInfo()); + if (rivSourceInfo) + { + if (nncPartFaceIndex < rivSourceInfo->m_NNCIndices->size()) + { + nncIndex = rivSourceInfo->m_NNCIndices->get(nncPartFaceIndex); + } + } + } + } + + QString pickInfo = "No hits"; + QString resultInfo = ""; + + if (cellIndex != cvf::UNDEFINED_SIZE_T) + { + RiuResultTextBuilder textBuilder(m_reservoirView, gridIndex, cellIndex, m_reservoirView->currentTimeStep()); + textBuilder.setFace(face); + textBuilder.setNncIndex(nncIndex); + textBuilder.setIntersectionPoint(localIntersectionPoint); + + resultInfo = textBuilder.mainResultText(); + + pickInfo = textBuilder.topologyText(", "); } mainWnd->statusBar()->showMessage(pickInfo); @@ -489,9 +465,6 @@ void RiuViewer::slotEndAnimation() cvf::Rendering* firstRendering = m_renderingSequence->firstRendering(); CVF_ASSERT(firstRendering); - firstRendering->removeOverlayItem(m_legend1.p()); - firstRendering->removeOverlayItem(m_legend2.p()); - if (m_reservoirView) m_reservoirView->endAnimation(); caf::Viewer::slotEndAnimation(); @@ -509,8 +482,6 @@ void RiuViewer::slotSetCurrentFrame(int frameIndex) if (m_reservoirView) m_reservoirView->setCurrentTimeStep(frameIndex); - this->updateLegends(); - caf::Viewer::slotSetCurrentFrame(frameIndex); } @@ -549,10 +520,8 @@ void RiuViewer::setEnableMask(unsigned int mask) //-------------------------------------------------------------------------------------------------- /// Perform picking and return the index of the face that was hit, if a drawable geo was hit //-------------------------------------------------------------------------------------------------- -cvf::Part* RiuViewer::pickPointAndFace(int winPosX, int winPosY, uint* faceHit, cvf::Vec3d* localIntersectionPoint) +void RiuViewer::pickPointAndFace(int winPosX, int winPosY, cvf::Vec3d* localIntersectionPoint, cvf::Part** firstPart, uint* firstPartFaceHit, cvf::Part** nncPart, uint* nncPartFaceHit) { - CVF_ASSERT(faceHit); - cvf::HitItemCollection hitItems; bool isSomethingHit = rayPick(winPosX, winPosY, &hitItems); @@ -564,8 +533,8 @@ cvf::Part* RiuViewer::pickPointAndFace(int winPosX, int winPosY, uint* faceHit, double pickDepthThresholdSquared = characteristicCellSize / 100.0; pickDepthThresholdSquared = pickDepthThresholdSquared * pickDepthThresholdSquared; - cvf::HitItem* hitItem = hitItems.firstItem(); - cvf::Vec3d firstItemIntersectionPoint = hitItem->intersectionPoint(); + cvf::HitItem* firstNonNncHitItem = NULL; + cvf::Vec3d firstItemIntersectionPoint = hitItems.item(0)->intersectionPoint(); // Check if we have a close hit item with NNC data for (size_t i = 0; i < hitItems.count(); i++) @@ -573,26 +542,47 @@ cvf::Part* RiuViewer::pickPointAndFace(int winPosX, int winPosY, uint* faceHit, cvf::HitItem* hitItemCandidate = hitItems.item(i); cvf::Vec3d diff = firstItemIntersectionPoint - hitItemCandidate->intersectionPoint(); - // Hit items are ordered by distance from eye - if (diff.lengthSquared() > pickDepthThresholdSquared) break; - const cvf::Part* pickedPartCandidate = hitItemCandidate->part(); + bool isNncpart = false; if (pickedPartCandidate && pickedPartCandidate->sourceInfo()) { - const RivSourceInfo* rivSourceInfo = dynamic_cast(pickedPartCandidate->sourceInfo()); - if (rivSourceInfo && rivSourceInfo->hasNNCIndices()) + // Hit items are ordered by distance from eye + if (diff.lengthSquared() < pickDepthThresholdSquared) { - hitItem = hitItemCandidate; - break; + const RivSourceInfo* rivSourceInfo = dynamic_cast(pickedPartCandidate->sourceInfo()); + if (rivSourceInfo && rivSourceInfo->hasNNCIndices()) + { + *nncPart = const_cast(pickedPartCandidate); + + const cvf::HitDetailDrawableGeo* detail = dynamic_cast(hitItemCandidate->detail()); + if (detail && nncPartFaceHit) + { + *nncPartFaceHit = detail->faceIndex(); + } + + isNncpart = true; + } } } + + if (!isNncpart && !firstNonNncHitItem) + { + firstNonNncHitItem = hitItemCandidate; + firstItemIntersectionPoint = firstNonNncHitItem->intersectionPoint(); + } + + if (firstNonNncHitItem && *nncPart) + { + break; + } } - const cvf::Part* pickedPart = hitItem->part(); + const cvf::Part* pickedPart = firstNonNncHitItem->part(); CVF_ASSERT(pickedPart); + *firstPart = const_cast(pickedPart); const cvf::Transform* xf = pickedPart->transform(); - cvf::Vec3d globalPickedPoint = hitItem->intersectionPoint(); + cvf::Vec3d globalPickedPoint = firstNonNncHitItem->intersectionPoint(); if(localIntersectionPoint) { @@ -606,21 +596,14 @@ cvf::Part* RiuViewer::pickPointAndFace(int winPosX, int winPosY, uint* faceHit, } } - if (faceHit) + if (firstPartFaceHit) { - - const cvf::HitDetailDrawableGeo* detail = dynamic_cast(hitItem->detail()); + const cvf::HitDetailDrawableGeo* detail = dynamic_cast(firstNonNncHitItem->detail()); if (detail) { - *faceHit = detail->faceIndex(); + *firstPartFaceHit = detail->faceIndex(); } } - - return const_cast(pickedPart); // Hack. The const'ness of HitItem will probably change to non-const - } - else - { - return NULL; } } @@ -742,19 +725,53 @@ void RiuViewer::mousePressEvent(QMouseEvent* event) m_lastMousePressPosition = event->pos(); } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuViewer::addOverlayItem(cvf::OverlayItem* overlayItem) +void RiuViewer::slotHideFault() { - m_renderingSequence->firstRendering()->addOverlayItem(overlayItem); + const RigCaseData* reservoir = m_reservoirView->eclipseCase()->reservoirData(); + const RigFault* fault = reservoir->mainGrid()->findFaultFromCellIndexAndCellFace(m_currentCellIndex, m_currentFaceIndex); + if (fault) + { + QString faultName = fault->name(); + + RimFault* rimFault = m_reservoirView->faultCollection()->findFaultByName(faultName); + if (rimFault) + { + rimFault->showFault.setValueFromUi(!rimFault->showFault); + } + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuViewer::removeOverlayItem(cvf::OverlayItem* overlayItem) +void RiuViewer::removeAllColorLegends() { - m_renderingSequence->firstRendering()->removeOverlayItem(overlayItem); + for (size_t i = 0; i < m_visibleLegends.size(); i++) + { + m_mainRendering->removeOverlayItem(m_visibleLegends[i].p()); + } + + m_visibleLegends.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewer::addColorLegendToBottomLeftCorner(cvf::OverlayItem* legend) +{ + cvf::Rendering* firstRendering = m_renderingSequence->firstRendering(); + CVF_ASSERT(firstRendering); + + if (legend) + { + legend->setLayout(cvf::OverlayItem::VERTICAL, cvf::OverlayItem::BOTTOM_LEFT); + firstRendering->addOverlayItem(legend); + + m_visibleLegends.push_back(legend); + } } diff --git a/ApplicationCode/UserInterface/RiuViewer.h b/ApplicationCode/UserInterface/RiuViewer.h index 7e881a1464..a8131d63da 100644 --- a/ApplicationCode/UserInterface/RiuViewer.h +++ b/ApplicationCode/UserInterface/RiuViewer.h @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -24,6 +26,7 @@ #include "cafPdmPointer.h" #include "cafMouseState.h" +#include "cvfStructGrid.h" class RimReservoirView; class QLabel; @@ -50,8 +53,6 @@ class RiuViewer : public caf::Viewer RiuViewer(const QGLFormat& format, QWidget* parent); ~RiuViewer(); - void setColorLegend1(cvf::OverlayScalarMapperLegend* legend); - void setColorLegend2(cvf::OverlayScalarMapperLegend* legend); void setDefaultView(); cvf::Vec3d pointOfInterest(); void setPointOfInterest(cvf::Vec3d poi); @@ -66,8 +67,8 @@ class RiuViewer : public caf::Viewer void showAnimationProgress(bool enable); - void addOverlayItem(cvf::OverlayItem* overlayItem); - void removeOverlayItem(cvf::OverlayItem* overlayItem); + void removeAllColorLegends(); + void addColorLegendToBottomLeftCorner(cvf::OverlayItem* legend); public slots: @@ -81,15 +82,15 @@ public slots: void mousePressEvent(QMouseEvent* event); void handlePickAction(int winPosX, int winPosY); - cvf::Part* pickPointAndFace(int winPosX, int winPosY, uint* faceHit, cvf::Vec3d* localIntersectionPoint); + void pickPointAndFace(int winPosX, int winPosY, cvf::Vec3d* localIntersectionPoint, cvf::Part** firstPart, uint* firstPartFaceHit, cvf::Part** nncPart, uint* nncPartFaceHit); private slots: void slotRangeFilterI(); void slotRangeFilterJ(); void slotRangeFilterK(); + void slotHideFault(); private: - void updateLegends(); void ijkFromCellIndex(size_t gridIdx, size_t cellIndex, size_t* i, size_t* j, size_t* k); private: @@ -106,14 +107,13 @@ private slots: QCDEStyle* m_progressBarStyle; - cvf::ref m_legend1; - cvf::ref m_legend2; - + cvf::Collection m_visibleLegends; caf::PdmPointer m_reservoirView; size_t m_currentGridIdx; size_t m_currentCellIndex; + cvf::StructGridInterface::FaceType m_currentFaceIndex; QPoint m_lastMousePressPosition; }; diff --git a/ApplicationCode/WellPathImportSsihub/RimOilFieldEntry.cpp b/ApplicationCode/WellPathImportSsihub/RimOilFieldEntry.cpp index fa61910c5b..53646b15aa 100644 --- a/ApplicationCode/WellPathImportSsihub/RimOilFieldEntry.cpp +++ b/ApplicationCode/WellPathImportSsihub/RimOilFieldEntry.cpp @@ -1,6 +1,8 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// Copyright (C) 2011- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// Copyright (C) 2011-2012 Ceetron AS // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -89,6 +91,8 @@ void RimOilFieldEntry::fieldChangedByUi(const caf::PdmFieldHandle* changedField, void RimOilFieldEntry::initAfterRead() { updateEnabledState(); + + this->updateUiIconFromToggleField(); } //-------------------------------------------------------------------------------------------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index a41fddb4da..1ed8203cdd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required (VERSION 2.8) +include (CheckCSourceCompiles) project (ResInsight) set (VIZ_MODULES_FOLDER_NAME Fwk/VizFwk) diff --git a/Documentation/UsersGuide/BatchCommands.md b/Documentation/UsersGuide/BatchCommands.md deleted file mode 100644 index 26cf3f0a57..0000000000 --- a/Documentation/UsersGuide/BatchCommands.md +++ /dev/null @@ -1,48 +0,0 @@ -[ Contents ](UsersGuide.md#contents) - ------- -## Batch Commands - -ResInsight supports several commands useful in a batch setting. These examples are available from the [test section](https://github.com/OPM/ResInsight/tree/master/TestModels/Case_with_10_timesteps). - -See also [ Command Line Arguments](CommandLineParameters.md) for an overview of all command line arguments. - -### Example 1 : Create snapshots of all views for multiple cases -A list of cases is defined in **CaseList.txt**, containing the following - - Real0/BRUGGE_0000.EGRID - Real10/BRUGGE_0010.EGRID - Real30/BRUGGE_0030.EGRID - Real40/BRUGGE_0040.EGRID - -The command line used to run this example is shown here: - - ResInsight --project BatchTest.rsp --multiCaseSnapshots CaseList.txt --size 500 500 - -This will instruct ResInsight to read the project file **BatchTest.rsp**. All cases will be replaced one by one in ResInsight, and snapshots of all views will be written to file. - - -### Example 2 : Replace a single case and take snapshots of all views - -The command line used to run this example is shown here: - - ResInsight --project BatchTest.rsp --replaceCase "Real10\BRUGGE_0010.EGRID" --savesnapshots - -This will instruct ResInsight to read the project file **BatchTest.rsp**. The specified case **Real10\BRUGGE_0010.EGRID** will be imported into the project, and snapshots of all views will be written to file. - - -### Example 3 : Replace source cases in a case group and create snapshot -A list of cases is defined in **CaseList2.txt**, containing the following - - Real0/BRUGGE_0000.EGRID - Real10/BRUGGE_0010.EGRID - -The command line used to run this example is shown here: - - ResInsight --project BatchStatistics.rsp --replaceSourceCases CaseList2.txt --savesnapshots - -This will instruct ResInsight to read the project file **BatchTest.rsp**. All cases specified will be imported in the case group specified in the project file. Statistics will be computed, and snapshots for all views will be written to file. - - ------- -[ Contents ](UsersGuide.md#contents) diff --git a/Documentation/UsersGuide/CaseGroupsAndStatistics.md b/Documentation/UsersGuide/CaseGroupsAndStatistics.md deleted file mode 100644 index e3671de86c..0000000000 --- a/Documentation/UsersGuide/CaseGroupsAndStatistics.md +++ /dev/null @@ -1,82 +0,0 @@ -[ Contents ](UsersGuide.md#contents) - ------ - -## Grid Case Groups and Statistics - -![](images/GridCaseGroupTree.png) - -**Grid Case Group**'s are designed to make it easy to calculate statistics per cell and per timestep of a large number of Eclipse simulation Cases with identical Grids (often labeled *realizations*). - -If you have several Eclipse simulations with different input parameters available, you can put all the realizations into a Grid Case Group and easily calculate each of the cells mean value, range and max/min values at each timestep between the realizations. - -### Creating Grid Case Groups -#### From files -The easiest way to create a **Grid Case Group** is to use the Import command: -**File->Import->Create Grid Case Group from Files** - -An import dialog is opened: -![](images/CreateGridCaseGroupFromFileDialog.png) - -1. Add one or more search folders to the list on the left. -2. The *.EGRID or *.GRID files found in these directories and sub directories are shown in the list to the right. -3. If you want to remove some *.EGRID files from the list, select them and press the **Remove** button. -4. When you are ready, press the **OK** button. - -ResInsight then creates a **Grid Case Group** for you, and populates its **Source Cases** with the Cases you selected. Then the first of those Cases are read completely, while the others are just scanned to verify that the Grids match and to detect changes in the Active Cells layout. - -This makes it quite fast to lo ad even a quite large number of realizations. - -#### Manually - -A Grid Case Group can be created from the context menu available when right clicking a Result Case, Input Case or a different Grid Case Group. **Source Cases** can then be added by using the mouse to *drag and drop* cases with equal grids into the **Grid Case Group**'s **Source Case** folder. -This is useful if you want to create statistics based only on a subset of the source cases in an already created **Grid Case Group**. - -**Drag and Drop** of cases will normally copy the cases to the new destination, but moving them is possible by pressing and holding the **Shift** key while dropping. - -### Viewing special Source Cases -To reduce the number of views, only a view for the first case is created automatically. If you want to inspect the results of a particular source case, right click the case and select **New view** from the context menu. A new 3D View will the be created on that particular case. - -*TIP:* To reduce memory usage, project loading time etc. it is vise to delete the 3D Views you do not need. 3D Views use a lot of system resources. - -### Statistics ## -After creating a grid case group, an empty **Statistics Case** is created for you in the **Derived Statistics** folder of the **Grid Case Group**. - -#### Setting up and Calculate -The properties of an uncalculated and a calculated **Statistics Case** is shown below: - -![](images/StatisticsCaseProperties.png) ![](images/StatisticsCasePropertiesCalculated.png) - -- **Compute**: Starts to calculate requested statistical Properties. -- **Edit** : Deletes the calculated results, and makes the controls to edit the setup available. -- **Summary of calculation setup** : Summarizes what to calculate -- **Properties to consider**: These options makes it possible to select what Eclipse properties to include in the Statistical calculations. Adding variables increase the memory usage and the computational time. -- **Percentile Setup**: Selects whether to calculate percentiles, what method and what percentile levels should be used. Turning this off speeds up the calculations. -- **Well Data Source Case**: This option selects which set of **Simulation Wells** to be shown along with the statistical results. You can select one of the **Source Cases**. - -##### Percentile Methods - -Three Percentile methods are implemented: - -- **Interpolated Observation** -The values are sorted, and the two observations representing the probabilities closest to the percentile are interpolated to find the value for the percentile. This is the default method. -- **Nearest Observation** -The values are sorted, and the first observation representing a probability higher or equal to the percentile probability is selected as the value for the percentile. This method is by some considered to be statistically more puristic. -- **Histogram based estimate** -A histogram is created and the percentile is calculated based on the histogram. This method will be faster when having a large number of realizations, because no value sorting is involved. You would however need several hundred realizations before this method should be considered. - - -#### Viewing the results -When the computation is complete, you have to create a 3D View on the **Statistics Case** to view the results. Use the Context menu available by right clicking the **Statistics Case** to create it. - -#### Adding Statistics Cases -A new statistical calculation can be created by activating the context menu for **Derived Statistic->New Statistics Case**. - ------- -[ Contents ](UsersGuide.md#contents) - - - - - - diff --git a/Documentation/UsersGuide/CommandLineParameters.md b/Documentation/UsersGuide/CommandLineParameters.md deleted file mode 100644 index 968a772869..0000000000 --- a/Documentation/UsersGuide/CommandLineParameters.md +++ /dev/null @@ -1,24 +0,0 @@ -[ Contents ](UsersGuide.md#contents) - ------- -## Command Line Parameters # - -| Parameter | Description | -|-----------|-------------| -| `--last` | Open last used project. | -| `--project ` | Open project file . | -| `--case ` | Import Eclipse case (do not include .GRID/.EGRID) | -| `--startdir ` | Set startup directory. | -| `--savesnapshots` | Save snapshot of all views to 'snapshots' folder in project file folder. Application closes after snapshots have been written. | -| `--size ` | Set size of the main application window. | -| `--replaceCase [] ` | Replace grid in or first case with . | -| `--replaceSourceCases [] ` | Replace source cases in or first grid case group with the grid files listed in the file. | -| `--multiCaseSnapshots ` | For each grid file listed in the file, replace the first case in the project and save snapshot of all views. | -| `--help, -?` | Displays help text and version info | -| `--regressiontest ` | Run a regression test on all sub-folders starting with `TestCase*` of the given folder. **RegressionTest.rip** files in the sub-folders will be opened and snapshots of all the views is written to the sub-sub-folder **RegTestGeneratedImages**. Then difference images is generated in the sub-sub-folder **RegTestDiffImages** based on the images in sub-sub-folder **RegTestBaseImages**. The results are presented in **ResInsightRegressionTestReport.html** that is written in the given folder. | -| `--updateregressiontestbase ` | For all sub-folders starting with `TestCase*`, copy the images in the sub-sub-folder **RegTestGeneratedImages** to the sub-sub-folder **RegTestBaseImages** after deleting **RegTestBaseImages** completely. | - -See also the [Regression Test System ](RegressionTestSystem.md) for a more in-depth explanation. - ------- -[ Contents ](UsersGuide.md#contents) diff --git a/Documentation/UsersGuide/Faults.md b/Documentation/UsersGuide/Faults.md deleted file mode 100644 index 5ce0bc92f7..0000000000 --- a/Documentation/UsersGuide/Faults.md +++ /dev/null @@ -1,88 +0,0 @@ -[ Contents ](UsersGuide.md#contents) - ------ -## Faults - -ResInsight will detect all the cell faces with no geometrically matching neighbors, and display them as *Faults*. -This means that the are drawn in special ways, and that their visual appearance can be controlled separately from the rest of the grid. - -### Fault Names and NNC - -#### Import of Fault info from `*.DATA`-files -If enabled, ResInsight will also import fault information from the `*.DATA` files and use this information to group the detected faces into named items which is available in the ![](images/draw_style_faults_24x24.png) **Faults** item in the **Project Tree**. The imported faults are ordered in ascending order based on their name. - -> -***Note:*** As import of faults can be time consuming, reading of faults can be disabled from **Preferences -> Read fault data** - -#### Undefined grid faults -All the detected cell faces are compared to the faults imported from the `*.DATA` file in order to group them. If a particular face is *not* found among the fault faces defined in the `*.DATA` file or it's opposite face, the cell face is added to a fault called **Undefined grid faults**. This particular Fault will always be present, even if reading of the `*.DATA` file is disabled. - -#### Fault color - -Each named Fault is given a color on import. This color can be controlled by selecting the fault and edit its **Fault color** in the **Property Editor.** - -#### NNC visualization -ResInsight will read Non Neighbor Connections from the Eclipse output file (`*.INIT`), and create explicit visualizations of those witch have a common surface area. These NNC's are then sorted onto the Fault's and their visibility is controlled from the **Property Editor** of the **Faults** Item in the **Project Tree**. - -The color of the NNC faces are set to be a bit lighter than their corresponding named fault, and can not be controlled directly. - -Currently the only result property that is mapped onto the NNC is the static TRANSXYZ property which displays the transmissibility associated to each face. - -### Picking info - -When clicking on a cell face that is member of a fault, the fault name is displayed in the **Result Info** window, along with cell, and result property info. - -When clicking on a NNC, the relevant data for this NNC is displayed. - -### Fault visualization options - - -#### Toolbar control -Visualization mode and mesh lines can be controlled from the toolbar. - -- ![](images/draw_style_faults_24x24.png) **Faults-Only** visualization mode. -
When turned on, this option hides all the grid cells, and shows only the fault faces in the reservoir limited by the applied range and property filters. (Unless **Show faults outside filters** are turned on. See below.) -- ![](images/draw_style_surface_24x24.png) Turns faces on and mesh off -- ![](images/draw_style_surface_w_fault_mesh_24x24.png) Turns on all faces, and shows meshlines on faults only. -
This is a useful method to highlight the faults in your reservoir, because the faults stands out with black outlining. -- ![](images/draw_style_faults_label_24x24.png) Shows labels for faults - -#### Common Fault Options -By clicking the ![](images/draw_style_faults_24x24.png) **Faults** item in the **Project Tree**, the following options common to all the faults are displayed: - - ![](images/FaultProperties.png) - -##### Fault labels -- **Show labels**: Displays one label per fault with the name defined in the `*.DATA`-file -- **Label color**: Defines the label color - -##### Fault options -- **Show faults outside filters**: Turning this option on, will display faults outside the filter region, making the fault visualization completely ignore the Range and Property filters in action. -- **Show results on faults**: This toggle controls whether to show the selected result property on the faults or not. This should normally be left on. -- **Show NNCs**: Toggles whether to display the Non Neighbor Connections, or not. - -##### Fault Face Visibility -This group of options controls the visibility of the fault faces. Since they work together, and in some cases are overridden by the system, they can be a bit confusing. - -First of all. These options are only available in **Faults-only** visualization mode. ( See *Toolbar Control* above) When not in **Faults-Only** mode, ResInsight overrides the options, and the controls are inactive. - -Secondly: The option you would normally want to adjust is **Dynamic Face Selection** (See below). - -- **Show defined faces**: Displays the fault cell faces that are defined on the Eclipse input file (`*.DATA`) -- **Show opposite faces**: Displays the opposite fault cell faces from what is defined on the input file, based on IJK neighbors. -
*These two options should normally be left **On***.
They are useful when investigating the exact faults information provided on the `*.DATA` file. -
If you need to use them, it is normally wise to set the **Dynamic Face Selection** to "Show Both" - -######Dynamic Face Selection: - -At one particular position on a fault there are usually two cells competing for your attention: The cell closer to you as the viewer, or the one further from you. When showing results, this becomes important because these two cell faces have different result property values, and thus color. - -This option controls which of the two cell faces you actually can see: The one behind the fault, or the one in front of the fault. There is also an option of showing both, which will give you an undefined mixture, making it hard to be certain what you see. - -This means that ResInsight turns on or off the faces based on your view position and this option to make sure that you always see the faces (and thus the result property) you request. - - ------- -[ Contents ](UsersGuide.md#contents) - - diff --git a/Documentation/UsersGuide/GettingStarted.md b/Documentation/UsersGuide/GettingStarted.md deleted file mode 100644 index 7828975ed8..0000000000 --- a/Documentation/UsersGuide/GettingStarted.md +++ /dev/null @@ -1,167 +0,0 @@ -[ Contents ](UsersGuide.md#contents) - ------ -## Getting started with ResInsight - -### Installation -Installation instructions for ResInsight can be found here: [Installation and Configuration](Installation.md) - - -### User interface overview - -The application has a main area and several docking windows. The different docking -windows can be managed from the **Windows** menu or directly using the local menu bar of the docking window. - -![ResInsight User Interface](images/ResInsightUIFullSizeWindows.png) - - -#### Docking Windows - -- **Project Tree** - contains all application objects in a tree structure. -- **Property Editor** - displays all properties for the selected object in the **Project Tree** -- **Process Monitor** - displays output from Octave when executing Octave scripts -- **Result Info** - displays info for the object being hit in the 3D scene when clicking with left mouse button - -*TIP:* A new project tree and property editor can be added from **Windows->New Project and Property View**. - - -### Toolbars - -A selected subset of actions are presented as controls in the toolbar. The different sections in the toolbar can be dragged and positioned anywhere as small floating toolbars. Management of the toolbar is done by right-clicking on the toolbar and then manipulating the displayed menu. - -#### 3D Views - -In the main area of the application, several 3D views can be open at the same time. One of them will be active and the active view can be either maximized to use the whole main area, or normalized so that you can see all the open 3D views. - -*TIP:* To see views next to each other select the **Restore down** icon in the application show here for Windows : - -![Restore Down](images/RestoreDown.PNG) - -#### Editing the views - -Most of the settings and features of ResInsight is accessible through the **Project Tree** and the **Property Editor**. Selecting an item in the **Project Tree** activates the corresponding 3D View, and shows the item properties in the **Property Editor** available for editing. - -Toggling a checkbox next to an item in the **Project Tree** will toggle visibility in the 3D view. Toggling a checkbox for a collection of items will affect the visibility for all items in the collection. ![](images/TreeViewToggle.png) - -Context menu commands are also available to do special operations on a selected set of items. - -### Cases and their types - -A *Case* in ResInsight means a Grid model with a particular set of results or property data. There are -three different Case types: - -##### Result case ![](images/Case24x24.png) -This is a Case based on the results of an Eclipse analysis, read from a grid file together with restart data. - -##### Input case ![](images/EclipseInput24x24.png) -This Case type is based on a `*.GRDECL` file, or a part of an Eclipse *Input* file. This Case type supports loading single ASCII files defining Eclipse Cell Properties, and also to export modified property sets to ASCII files. -Each of the Eclipse properties is listed as separate entities in the **Project Tree**, and can be renamed and exported. - -##### Statistics case ![](images/Histogram24x24.png) -This is a Case type that belongs to a *Grid Case Group* and makes statistical calculations based on the source cases in the Grid Case Group. - -#### Grid Case Groups ![](images/GridCaseGroup24x24.png) - -A **Grid Case Group** is a group of **Result Cases** with identical grids, but generally different active cells, initial values and results. These cases are called *Source Cases*. - -The purpose of a Grid Case group is to make it easy to calculate statistics across the source cases both for static and dynamic Eclipse Properties. - -See [ Multiple realizations and statistics ](CaseGroupsAndStatistics.md) for more on this. - -### Importing data - -#### Input data support ### - -ResInsight supports the following type of Eclipse input data: -- `*.GRID` and `*.EGRID` files along with their `*.INIT` and restart files `*.XNNN` and `*.UNRST`. -- Grid and Property data from `*.GRDECL` files. - -#### Importing Eclipse cases - -##### Eclipse Results -1. Select **File->Import->Import Eclipse Case** and select an `*.EGRID` or `*.GRID` Eclipse file for import. -2. The case is imported, and a view of the case is created - -*TIP:* You can select several grid files in one go by multiple selection of files( Ctrl + left mouse button, Shift + left mouse button). - -##### Eclipse ASCII input data -1. Select **File->Import->Import Input Eclipse Case** and select a `*.GRDECL` file. -2. The case is imported, and a view of the case is created -3. Right click the **Input Properties** in the generated **Input Case** and use the context menu to import additional Eclipse Property data files. - -##### Handling missing or wrong MAPAXES - -The X and Y grid data can be negated in order to make the Grid model appear correctly in ResInsight. This functionality is accessible in the **Property Editor** for all Case types as the toggle buttons **Flip X Axis** and **Flip Y Axis** as shown in the example below. - -![](images/CaseProperties.png) - - -### Model navigation - -ResInsight comes with two 3D navigation modes. The active mode can be selected in the **Preferences** dialog (**Edit -> Preferences**). - -|Abbreviation | Meaning | -|-------------|---------| -|LMB | Pressing left mouse button | -|MMB | Pressing Middle mouse button or scroll wheel button | -|RMB | Pressing Right mouse button | - - -#### Ceetron navigation mode - -|Mouse interaction | Action | -|------------------|---------| -|LMB | Pan model | -|MMB | Zoom to mouse pointer location | -|Scroll wheel | Zoom to mouse pointer location | -|RMB | Rotate model | -| | | -|RMB single click | Context menu | -|LMB single click | Update status bar and **Result Info** | - -#### CAD navigation mode - -|Mouse interaction | Action | -|------------------|--------| -|MMB | Rotate model | -|MMB + Shift | Pan model | -|Scroll wheel | Zoom to mouse pointer location | -| | | -|RMB single click | Context menu | -|LMB single click | Update status bar and **Result Info** | - - -### Project files and Cache directory - -ResInsight stores which cases you have imported and all the settings for each view etc. in a project file with the extension `.rsp`. -This file only contains references to the real data files, and even references to data files generated by ResInsight itself. - -Statistics calculations, property sets you generate by using Octave, and well paths are saved to a folder in the same directory as you save the project file, and is named \_cache. So if you need to move your project, make sure you move this folder as well. - -*TIP:* The `.rsp`-file is an XML file, and can be edited by any text editor. - -### Export options -#### Snapshot images -##### Single View ![](images/SnapShot.png) ![](images/SnapShotSave.png) -Image export of current 3D view can be launched from **File -> Export -> Snapshot To File**. A snapshot can also be copied to clipboard using **Edit->Copy Snapshot To Clipboard**. - -##### All Views ![](images/SnapShotSaveViews.png) -If a project contains multiple views, all views can be exported using **File -> Export -> Snapshot All Views To File**. - -It is also possible to snapshot all views from the command line. See [ Command Line Arguments] (CommandLineParameters.md) - - - - -#### Export of Eclipse Properties as ASCII data -Eclipse Properties can be exported to Eclipse ASCII files by activating the context menu for a **Cell Result**. ![](images/ExportProperty.png) - -The command will export the property set currently loaded and shown in the 3D View to a file with the following format: - - -- Exported from ResInsight - - - / - ------- -[ Contents ](UsersGuide.md#contents) diff --git a/Documentation/UsersGuide/Installation.md b/Documentation/UsersGuide/Installation.md deleted file mode 100644 index 2d46fd2925..0000000000 --- a/Documentation/UsersGuide/Installation.md +++ /dev/null @@ -1,28 +0,0 @@ -[ Contents ](UsersGuide.md#contents) - ------ -## Installation and configuration - -### Windows - -1. Download ZIP binary distribution from [https://github.com/OPM/ResInsight/releases](https://github.com/OPM/ResInsight/releases "release section on GitHub") -2. Extract content from ZIP file -3. (OPTIONAL) Launch ResInsight.exe, open **Edit ->Preferences** and define location of Octave, usually 'ResInsightRoot/octave/bin/octave.exe' - -#### Optional - Octave installation -Currently tested and verified version on Windows is Octave 3.6.1. NB! Version 3.6.2 has compile issues using VS2010, this version will not be able to compile the Octave plugins. - -- Download and install Octave 3.6.1 for VS2010 from [SourceForge](http://sourceforge.net/projects/octave/files/Octave%20Windows%20binaries/Octave%203.6.1%20for%20Windows%20Microsoft%20Visual%20Studio/octave-3.6.1-vs2010-setup-1.exe/download) -- Download a [missing library file](https://github.com/OPM/ResInsight/releases/download/1.0.0/dirent.lib) and copy it into Octave lib folder, typically **c:/Octave-3.6.1/lib/dirent.lib** See details on [SourceForge](http://sourceforge.net/mailarchive/message.php?msg_id=28933804) - - -## Linux - -1. Download TAR.GZ binary distribution from [https://github.com/OPM/ResInsight/releases](https://github.com/OPM/ResInsight/releases "release section on GitHub") -2. Extract content from TAR file -3. (OPTIONAL) Launch ResInsight, open **Edit -> Preferences** and define location of Octave in the field **Octave**, usually 'ResInsightRoot/octave/bin/octave-cli' - - - ------- -[ Contents ](UsersGuide.md#contents) diff --git a/Documentation/UsersGuide/OctaveInterface.md b/Documentation/UsersGuide/OctaveInterface.md deleted file mode 100644 index 4c1a8ba1cd..0000000000 --- a/Documentation/UsersGuide/OctaveInterface.md +++ /dev/null @@ -1,42 +0,0 @@ -[ Contents ](UsersGuide.md#contents) - ------ -## Octave Interface - -ResInsight provides a flexible interface to [Octave](http://www.gnu.org/software/octave/ "Octave"). -This includes a set of Octave functions that communicates with a running ResInsight session, features in ResInsight that makes it easy to manage and edit Octave scripts, and their execution using Octave. - -The Octave functions are documented in [ Octave Interface Reference](OctaveInterfaceReference.md). - - -### Script management -Octave scripts are available in the **Scripts** folder in the **Project Tree**. - -![](images/OctaveScriptTree.png) - -This folder contains an entry for each of the directories you have added as a **Script Folder**. Each of the folder lists available `*.m` files and sub directories. The tree is continuously updated to reflect the file structure on disk. - -#### Adding Script Folders -You can add directories by right clicking the **Scripts** item to access the context menu. - -Multiple standard script folder locations can also be defined in the field **Shared Script Folder(s)** in the **Preferences Dialog** (**Edit -> Preferences**). - -#### Editing scripts -To enable script editing from ResInsight you need to set up the path to a text editor in the **Script Editor** field in the **Preferences Dialog** (**Edit -> Preferences**) - -When done, scripts can be edited using the context menu command **Edit** on the script item in the tree. - -### Script execution -Octave scripts can be executed with or without a selection of cases as context. The [ Octave Interface Reference](OctaveInterfaceReference.md) highlights in more depth how to design your Octave scripts to utilize these features. - -#### Without a case selection -A script can be started by navigating to the script in the **Project Tree**, and selecting **Execute** from the context menu. The currently active case (The one with the active 3D View) will then be set as ResInsight's *Current Case*. - -#### With a case selection -One script can be executed on many cases by first selecting a set of cases, and then activating **Execute script** from the context menu for the case selection. The script is then executed once pr selected case. Each time ResInsight's *Current Case* is updated, making it accessible from the Octave script. - -![](images/ExecuteOctaveScriptOnSelectedCases.png) - - ------- -[ Contents ](UsersGuide.md#contents) diff --git a/Documentation/UsersGuide/OctaveInterfaceReference.md b/Documentation/UsersGuide/OctaveInterfaceReference.md deleted file mode 100644 index ef76b50e7c..0000000000 --- a/Documentation/UsersGuide/OctaveInterfaceReference.md +++ /dev/null @@ -1,222 +0,0 @@ -[ Contents ](UsersGuide.md#contents) - ------ -# Octave Interface Reference - -## Introduction -To identify a ResInsight case uniquely in the Octave script, an integer Id (CaseId) is used. This Id can be retrieved in several ways, but there are two main modes of operation regarding this for a particular octave script: Either the script is designed to work on a single case (the "Current Case"), or the script is designed to access the selection and traverse the cases by itself. - -### Single case scripts -Single case scripts do not need to address cases explicitly, but works on what ResInsight considers being the "Current Case". When the user selects several cases and executes a script on them, ResInsight loops over all cases in the selection, sets the current case and executes the script. All references to the "Current Case" from the script will then refer to the case currently being processed by ResInsight. -The Current Case can be accessed directly using **riGetCurrentCase()**, but the more direct way is to *omit the CaseId parameter* in the functions, the Current Case is then automatically used. - -### Multi case scripts -Scripts can access the selection state in ResInsight, and also retrieve lists of Case Groups and cases including some meta information. This can be used if the scripts need to get values from some cases, and store the results in others, etc. - -### Case Types -The case type (Labeled "CaseType" in the following specification) of a case is returned as a text string when retrieving lists of cases, and is one of the following: - -| Case Type | Description | -|----------------|-------------| -|ResultCase | A binary Eclipse case | -|InputCase | A case based on ASCII Eclipse input data | -|StatisticsCase | A statistics case based on many source cases in Grid Case Group | -|SourceCase | A binary Eclipse case in a Grid Case Group | - -### Unresolved issues -The issue around having multiple instances of ResInsight is still not addressed, but might affect the function signatures by adding a port number parameter to all of them. We will try to find ways to avoid this, but are still not certain that we will succeed. - -## Specification -### Project Information -The case information is presented in an octave Structure called CaseInfo, and contains the following fields: - - CaseInfo = { - CaseId = int # A project-unique integer used to address this - # particular case - CaseName = string # The name that has been assigned to the case - # in ResInsight. - CaseType = string # See the description above - CaseGroupId = int # A project-unique integer identifying the - # CaseGroup this case is a member of. - # -1 if not in a CaseGroup. Valid only for - # Statistics-, and SourceCases - } - -#### CaseInfo riGetCurrentCase() -This function returns a CaseInfo Structure for the Case considered being the "Current Case" by ResInsight. When ResInsight loops over a selection of cases and executes an Octave script for each of them, this function returns the CaseInfo for that particular Case. - -#### Vector[CaseInfo] riGetSelectedCases() -This function returns a CaseInfo Structure for each of the cases selected in ResInsight at the time when the script launched. - -#### Vector[CaseGroupInfo] riGetCaseGroups() -This function returns a CaseGroupInfo Structure for each of the case groups in the current ResInsight project. - - CaseGroupInfo = { - CaseGroupId = int # A project-unique integer used to address - # this particular CaseGroup - CaseGroupName = string # The name assigned to the CaseGroup - # in ResInsight - } - -#### Vector[CaseInfo] riGetCases([CaseGroupId]) -This function returns a CaseInfo Structure for all the cases in the current ResInsight project, including the Statistics cases and Source cases in a Grid Case Group. -If a CaseGroupId is provided, only the cases in that Case Group will be returned. - -### Retrieving Grid Metadata - -#### Matrix[numActiveCells][9] riGetActiveCellInfo([CaseId], [PorosityModel = "Matrix"|"Fracture"] ) -This function returns a two dimensional matrix containing grid and IJK information about each of the active cells in the requested case. The columns contain the following information: - - [GridIdx, I, J, K, ParentGridIdx, PI, PJ, PK, CoarseBoxIdx] - GridIdx # The index of the grid the cell resides in. - # Main grid has index 0 - I, J, K # 1-based index address of the cell in the grid. - ParentGridIdx # The index to the grid that this cell's grid - # is residing in. - PI, PJ, PK # 1-based address of the parent grid cell that - # this cell is a part of. - CoarseBoxIdx # 1-based coarsening box index, -1 if none. - # Coarsening box info can be retrieved using - # **riGetCoarseningInfo()** - -If the CaseId is not defined, ResInsight's Current Case is used. - -#### Matrix[numCoarseGroups][6] riGetCoarseningInfo([CaseId]) -This function returns all coarse box definitions used in the grid. -The columns contain the following information: -[I1, I2, J1, J2, K1, K2]: 1-based index addresses of the min and max corners of the coarsening box. -If the CaseId is not defined, ResInsight's Current Case is used. - -#### Matrix[numGrids][3] riGetGridDimensions([CaseId]) -This function returns a two dimensional matrix: One row for each grid, starting with the main grid. - -*NOTE*: This means that the "normal" GridIndices where 0 means Main Grid does not work directly with this matrix. You have to add 1. - -The columns contain the following information: -[NI, NJ, NK]: I, J, K dimensions of the grid. -If the CaseId is not defined, ResInsight's Current Case is used. - -#### Vector[TimeStepDate] riGetTimeStepDates([CaseId]) -This function returns the date information for each of the time steps in the case as a Vector of Structures. -The Structure is defined as: - - TimeStepDate = { - Year = int # The year eg. 2013 - Month = int # The month. Eg. 12 - Day = int # The day in the month. Eg. 24 - Hour = int # The hour of the day. Eg. 17 - Minute = int # The minute in the hour. Eg. 55 - Second = int # The second within the minute. Eg. 30 - } - -If the CaseId is not defined, ResInsight's Current Case is used. - -#### Vector[DecimalDay] riGetTimeStepDays([CaseId]) -This function returns the time from the simulation start as decimal days for all the time steps as a Vector of doubles. -If the CaseId is not defined, ResInsight's Current Case is used. - -### Retrieving Property Data - -#### Vector[PropertyInfo] riGetPropertyNames([CaseId] ], [PorosityModel = "Matrix"|"Fracture"]) -This function returns the name and type of all the properties in the case as a Vector of Structures. -The Structure is defined as: - - PropertyInfo { - PropName = string # Name of the property as received from - # the analysis tool - PropType = string # The type of the property: "StaticNative", - # "DynamicNative", "Input", "Generated" - } - -If the CaseId is not defined, ResInsight's Current Case is used. - -#### Matrix[numActiveCells][numTimestepsRequested] riGetActiveCellProperty([CaseId], PropertyName, [RequestedTimeSteps], [PorosityModel = "Matrix"|"Fracture"]) - -This function returns a two dimensional matrix: [ActiveCells][Num TimestepsRequested] containing the requested property data from the case with CaseId. -If the case contains coarse-cells, the results are expanded onto the active cells. -If the CaseId is not defined, ResInsight's Current Case is used. -The RequestedTimeSteps must contain a list of indices to the requested timesteps. If not defined, all the timesteps are returned. - -#### Matrix[numI][numJ][numK][numTimestepsRequested] riGetGridProperty ([CaseId], GridIndex , PropertyName, [RequestedTimeSteps], [PorosityModel = "Matrix"|"Fracture"]) -This function returns a matrix of the requested property data for all the grid cells in the requested grid for each requested timestep. -Grids are indexed from 0 (main grid) to max number of LGR's -If the CaseId is not defined, ResInsight's Current Case is used. -The RequestedTimeSteps must contain a list of indices to the requested time steps. If not defined, all the timesteps are returned. -Writing Back to ResInsight - -#### riSetActiveCellProperty( Matrix[numActiveCells][numTimeSteps], [CaseId], PropertyName, [TimeStepIndices], [PorosityModel = "Matrix"|"Fracture"]) -Interprets the supplied matrix as a property set defined for the active cells in the case, and puts the data into ResInsight as a "Generated" property with the name "PropertyName". -The "TimeStepIndices" argument is used to "label" all the time steps present in the supplied data matrix, and must thus be complete. The time step data will then be put into ResInsight at the time steps requested. -If the CaseId is not defined, ResInsight's Current Case is used. - -#### riSetGridProperty( Matrix[numI][numJ][numK][numTimeSteps], [CaseId], GridIndex, PropertyName, [TimeStepIndices], [PorosityModel = "Matrix"|"Fracture"]) -Interprets the supplied matrix as a property set defined for all cells in one of the grids in a case, and puts the data into ResInsight as a "Generated" property with the name "PropertyName". -The "TimeStepIndices" argument is used to "label" all the time steps present in the supplied data matrix, and must thus be complete. The time step data will then be put into ResInsight at the time steps requested. -If the CaseId is not defined, ResInsight's Current Case is used. - -### Cell Geometry Functions - -#### Matrix[numI][numJ][numK][3] riGetCellCenters([CaseId], GridIndex) -This function returns the UTM coordinates (X, Y, Z) of the center point of all the cells in the grid. -If the CaseId is not defined, ResInsight's Current Case is used. - -#### Matrix[ActiveCells][3] riGetActiveCellCenters([CaseId], [PorosityModel = "Matrix"|"Fracture"]) -This function returns the UTM coordinates (X, Y, Z) of the center point of each of the active cells. -If the CaseId is not defined, ResInsight's Current Case is used. -Cell Corner Index layout -The corner indices follow the ECLIPSE standard: - - 6-------------7 |k - /| /| | /j - / | / | |/ - / | / | *---i - 4-------------5 | - | | | | - | 2---------|---3 - | / | / - | / | / - |/ |/ - 0-------------1 - -#### Matrix[numI][numJ][numK][8][3] riGetCellCorners([CaseId], GridIndex) -This function returns the UTM coordinates(X, Y, Z) of the 8 corners of all the cells in the grid. -If the CaseId is not defined, ResInsight's Current Case is used. - -#### Matrix[ActiveCells][8][3] riGetActiveCellCorners([CaseId], [PorosityModel = "Matrix"|"Fracture"]) -This function returns the UTM coordinates (X, Y, Z) of the 8 corners of each of the active cells. -If the CaseId is not defined, ResInsight's Current Case is used. - -### Well Data Functions - -#### Vector[WellNames] riGetWellNames([CaseId]) -This function returns the names of all the wells in the case as a Vector of strings. -If the CaseId is not defined, ResInsight's Current Case is used. -Vector[WellCellInfo] riGetWellCells([CaseId], WellName, TimeStep) -This function returns the cells defined in the specified well for the time step requested as a vector of Structures. The Structure is defined as: - - WellCellInfo { - I, J, K = int # Index to the cell in the grid - GridIndex = int # the index of the grid. Main grid has index 0. - CellStatus = int # is either 0 or 1, meaning the cell is closed - # or open respectively - BranchId = int # Branch id of the branch intersecting the cell - SegmentId = int # Branch segment id of the branch intersecting the cell - } - -If the CaseId is not defined, ResInsight's Current Case is used. - -#### Vector[WellStatus] riGetWellStatus ([CaseId], WellName, [RequestedTimeSteps]) -This function returns the status information for a specified well for each requested time step as a vector of Structures. The Structure is defined as: - - WellStatus { - WellType = string # "Producer", "OilInjector", - # "WaterInjector", "GasInjector", "NotDefined" - WellStatus = int # is either 0 or 1, meaning the well is shut - # or open respectively - } - -If the CaseId is not defined, ResInsight's Current Case is used. - - ------- -[ Contents ](UsersGuide.md#contents) diff --git a/Documentation/UsersGuide/README.md b/Documentation/UsersGuide/README.md deleted file mode 100644 index 03c7f55a34..0000000000 --- a/Documentation/UsersGuide/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# Documentation # -Documentation files uses the GitHub markdown syntax. A common file extension for markdown files is .md. - - -[GitHub Markdown syntax](https://help.github.com/articles/github-flavored-markdown) - -## How to produce PDF from markdown files ## - -Pandoc can be used to generated PDF from a markdown file like this - - pandoc -f markdown_github GettingStarted.md -o GettingStarted.pdf - -See here for information on Pandoc -[http://johnmacfarlane.net/pandoc/](http://johnmacfarlane.net/pandoc/) - - -## Internal documentation notes - -### Produce PDF from markup - 28. oct 2013 - -The documentation for Git is build using a set of markup files. Below is a set of command history on Ubuntu 13.04 to be able to produce PDF from markup. - -NOTE: On Ubuntu, use the following fonts in latex/config.yml -Ubuntu for normal text and DejaVu Sans Mono for monospace. - -https://github.com/progit/progit/issues/11 - - - 16 cd .. - 17 git clone https://github.com/progit/progit.git - 18 cd progit/ - 19 ls - 20 ./makepdfs en - 21 sudo apt-get install ruby - 22 ./makepdfs en - 23 sudo apt-get install pandoc - 24 ./makepdfs en - 25 sudo apt-get install xelatex - 26 sudo apt-get install texlive-xetex - 27 ./makepdfs en - 28 dir - 29 sudo apt-get install texlive - 30 ./makepdfs en - 31 sudo apt-get install texlive-latex-extra - 32 sudo apt-get install texlive-latex-base - 33 ./makepdfs en - 34 sudo apt-get install texlive-latex-extra - 35 ./makepdfs en - 36 ls - 37 cd latex/ - 38 ls - 39 kate config.yml - 40 sudo apt-get install kate - 41 kedit config.yml - 42 gedit config.yml - 43* - 44 cd .. - 45 ls - 46 ./makepdfs en - 47 fc-match helvetica - 48 ./makepdfs en - 49 fc-list - 50 fc-match helvetica - 51 fc-match helvetica neue - 52 ./makepdfs en - 53 fc-list - 54 ./makepdfs en - 55 ./makepdfs en --debug - 56 ./makepdfs en - 57 ls - 58 ./progit.en.pdf - 59 evince - 60 history diff --git a/Documentation/UsersGuide/RegressionTestSystem.md b/Documentation/UsersGuide/RegressionTestSystem.md deleted file mode 100644 index 342ffdb8c6..0000000000 --- a/Documentation/UsersGuide/RegressionTestSystem.md +++ /dev/null @@ -1,48 +0,0 @@ -[ Contents ](UsersGuide.md#contents) - ------ -## Regression test system - -A regression tool for QA is build into ResInsight. This tool will do the following: - -1. Scan a directory for sub directories containing a **RegressionTest.rip** files. -2. Each found project file will be opened, and all views in this project will be exported as snapshot images to file. -3. When snapshot images from all projects are completed, difference images based on generated and QA-approved images are computed. -4. Based on these three sets of images, an HTML report is created and automatically displayed. - -### Starting regression tests - -To be able to run regression tests you need the **compare** tool from the [ImageMagic suite](http://www.imagemagick.org/script/compare.php). - - -You can start the tests either from the command line or from the ResInsight Gui. -From the ResInsight Gui select : **File->Testing->Regression Test Dialog** - -![](images/RegressionTestDialog.png) - -Specify location of compare tool in **Folder containing compare**. The current working directory of ResInsight is temporarily changed to this path during execution. - -### Creating regression tests - -An example of the folder structure is shown below: - - RegressionTestFolder/ - TestCase1/ - RegressionTest.rip - RegTestBaseImages/ - RegTestDiffImages/ - RegTestGeneratedImages/ - TestCase2/ - ... - -To create regression tests you need to do the following: - -1. Create a root directory containing one directory for each test case. -2. In each of the **Test Case** folders create a ResInsight project file called **RegressionTest.rip**. -3. Run the regression test for the first time, and thereby creating images that can be used as Base images. -4. Rename the generated RegTestGeneratedImages/ folder to RegTestBaseImages/ - -Now you are all set to test new releases of ResInsight towards your own Regression tests. - ------- -[ Contents ](UsersGuide.md#contents) diff --git a/Documentation/UsersGuide/ReservoirViews.md b/Documentation/UsersGuide/ReservoirViews.md deleted file mode 100644 index 2a9df5430b..0000000000 --- a/Documentation/UsersGuide/ReservoirViews.md +++ /dev/null @@ -1,147 +0,0 @@ -[ Contents ](UsersGuide.md#contents) - ------ -## Working with 3D Views - -3D Views are the windows displaying the Grid Models. The visualization is controlled by the **Project Tree** item representing the **View** and their subitems. Each item has a set of proerties that can be editied in the **Property View**. - -![](images/3DViewOverview.png) - -Below is a description of the most important View settings and their properties. - -### Cell Result ![](images/CellResult.png) - -The **Cell Result** item defines which Eclipse property the 3D View uses for the main cell color. The property can be chosen in the property panel of the **Cell Result** item. The mapping between cell values and color is defined by the **Legend Definition** ![](images/Legend.png) along with some appearance settings on the Legend itself. (Number format etc.) - -#### TRANSXYZ -Normally the Cell Result setting gives one cell color based on the legend and the selected Result Property. This is *not* the case for the special static TRANXYZ property. This property gives each face the correct color based on the TRANS value that is associated with that particular face. - -The Positive I-face of the cell gets the cell TRANX value, while the J-face gets the TRANY-value etc. The negative faces, however, get the value from the neighbor cell in that direction. The negative I-face gets the TRANX value of the IJK-neighbor in negative I direction, and so on for the -J and -K faces. - -### Cell Edge Results ![](images/EdgeResult_1.png) - -The **Cell Edge Result** visualization mode is one of ResInsight's special features. Its main use is to show the MULT(X, Y, Z) properties at the same time. -This will show the MULT property values *different from 1.0* along the correct edges of the cells. In effect this highlights the faults and makes it easy to verify all the MULT values in one go. - -![](images/CellEdgeExample.png) - -ResInsight supports all properties ending with X, Y, Z and X-, Y-, Z-. However, it is only the MULT property that ignores values of 1.0. - -When selecting a result variable for cell edge, a second legend shows up in the 3D view showing the variation in values for this second property. Color legend management is available when selecting the **Legend Definition** item belonging to the **Cell Edge Result** item. - -### Info Box - -The **Info Box** controls the visibility of the animation progress, the Case description box, and the results histogram. - -The **Results Histogram** shows a histogram of the complete time series of the currently loaded **Cell Result** together with: - -- The mean value ( a blue line ) -- P10 and P90 ( red lines ) - -![](images/HistogramExample.png) - - -### Cell Filters -Cell Filters are used to control visibility of the cells in the 3D view. Three types of filters exists: - -- **Range filter** : Define a IJK subset of the model. -- **Property filter** : Define a value range for a property to control cell visibility. -- **Well cell filter** : Display grid cells that has connections to a well. Controlled from the **Simulation Wells** item. - -All filters can be turned on or off using the toggle in the **Project Tree** and controlled from their corresponding **Property Editor**. - -#### Range filters - -Using range filters enables the user to define a set of IJK visible regions in the 3D view. -A new range filter can be added by activating the context menu for the **Range Filters** collection in the **Project Tree**. - -*TIP:* An I,J or K-slice range filter can be added directly from a Cell in the **3D View** by rightclicking the cell and using the context menu. - -Below is a snapshot of the **Property Editor** of the **Range Filter** : - -![](images/RangeFilterProperties.png) - - - **Filter Type** : The filter can either make the specified range visible ( *Include* ), or remove the range from the View ( *Exclude* ). - - **Grid** : This option selects which of the grids the range is addressing. - - **Apply to Subgrids** : This option tells ResInsight to use the visibility of the cells in the current grid to control the visibility of the cells in sub-LGR's. If this option is turned off, Sub LGR-cells is not included in this particular Range Filter. - -The **Start** and **Width** labels in front of the sliders features a number in parenthesis denoting maximum available value.
-The **Start** labels shows the index of the start of the active cells.
-The **Width** labels shows the number of active cells from the start of the active cells. - -#### Property filters - -**Property filters** apply to the results of the **Range filters**. Below is a snapshot of the **Property Editor** of the **Property Filter**. - -![](images/PropertyFilterProperties.png) - -This filter filters the cells based on a property value range (Min - Max). Cells in the range are either shown or hidden depending on the **Filter Type** ( *Include* / *Exclude* ). Exclude-filters removes the selected cells from the **View** even if some other filter includes them. - -A new property filter can be made by activating the context menu for **Property Filters**. The new property filter is based on the currently viewed cell result by default. - -### Simulation Wells - -This item controls the overall settings for how wells in the Eclipse simulation are visualized. -The wells are shown in two ways: - -1. A pipe through all cells with well connections -2. By adding the well cells to the set of visible cells - -The latter is handled internally as a special range filter, and adds cells to the set of range filtered cells. - -The Property Editor of the **Simulation Wells** item is shown below: - -![](images/SimulationWellsProperties.png) - - - -- **Add cells to range filter** This option controls how the well cells - (cells with connections to wells) are added to the set of range filtered cells. - - *All On* will add the cells from all wells disregarding the individual settings on the well. - - *All Off* will prevent any well cells to be added. - - *Individually* will respect the individual settings for each well, and add the cells from the wells with this option set on. -- **Use Well Fence** and -- **Well Fence direction** Controls whether to add extensions of the well cells in the I, J or K direction to the set of range filtered cells -- **Well head** These options control the appearance and position of the well labels and and symbols of the top of the well -- **Global Well Pipe Visibility** Controls if and when to show the pipe representation of the wells. The options are: - - *All On* will show the pipes from all wells disregarding the individual settings on the well. - - *All Off* will hide all simulation well pipes. - - *Individual* Will respect the individual settings for each well, and only show the well pipes from the wells with this option set on. See below. - - *Visible Cells Filtered* This option will only show the pipes of wells that are connected to visible cells. That means the combined result of **Range Filters**, **Property Filters** and any **Well Range Filters**. - *NOTE* : All Wells with **Well Range Filter** turned on will always be visible with this option selected. -- **Pipe Radius Scale** Scaling the pipe radius by the average max cell size. -- **Geometry based Branch detection** Applies only to ordinary wells (not MSW) - and will detect that parts of a well really is a branch. Those well parts will - be visualized as a branch starting at the well head instead of at the previous connected cell. - -##### Well pipes of Multi Segment Wells - -###### Geometry approximation -The pipe geometry generated for MSW's are based on the topology of the well (branch/segment structure) and the position of the cells being connected. The segment lengths are used as hints to place the branch points at sensible places. Thus the pipe geometry itself is not geometrically correct, but makes the topology of the well easier to see. - -###### Dummy branches -Often MSW's are modeled using a long stem without connections and a multitude of small branches; one for each connection. ResInsight offsets the the pipe within the cell to clearly show how the topology of the well is defined. - -![](images/MSWDummyBranchExample.png) - -###### Picking reveals Segment/Branch info - -Branch and segment info of a MSW-connected-Cell is shown in the **Result Info** window when picking a cell in the 3D View. This can be handy when relating the visualization to the input files. - -### Individual Simulation Well options - -Each of the wells can have some individual settings. These options works as specializations of the ones set on the global level (**Simulation Wells** See above) but will *only come into play when they are not ignored by the global settings*. - -This is particularly important to notice for the **Show Well Pipe** and **Range Filter** options. They will not have effect if the corresponding global settings in **Simulation Wells** allows them to. - -The properties of a single well are shown below. - -![](images/WellProperties.png) - -One option needs further explanation: - -- **Pipe Radius Scale** This option is a scale that is added to the "global" scale set in the **Simulation Wells** properties. - - ------- -[ Contents ](UsersGuide.md#contents) diff --git a/Documentation/UsersGuide/UsersGuide.md b/Documentation/UsersGuide/UsersGuide.md deleted file mode 100644 index 33c21440f4..0000000000 --- a/Documentation/UsersGuide/UsersGuide.md +++ /dev/null @@ -1,32 +0,0 @@ -# ![](images/AppLogo48x48.png) ResInsight 1.2 Users Guide - -## Introduction - -ResInsight is an open source, cross-platform 3D visualization and post processing tool for reservoir models and simulations. The system also constitutes a framework for further development and support for new data sources and visualization methods, e.g. additional solvers, seismic data, CSEM, geomechanics, and more. - -The user interface is tailored for efficient interpretation of reservoir simulation data with specialized visualizations of properties, faults and wells. It enables easy handling of a large number of realizations and calculation of statistics. To be highly responsive, ResInsight exploits multi-core CPUs and GPUs. Integration with GNU Octave enables powerful and flexible result manipulation and computations. Derived results can be returned to ResInsight for further handling and visualization. Eventually, derived and computed properties can be directly exported to Eclipse input formats for further simulation cycles and parameter studies. - -The main input data is -`*.GRID` and `*.EGRID` files along with their `*.INIT` and restart files `*.XNNN` and `*.UNRST`. -ResInsight also supports selected parts of Eclipse input files and can read grid -information and corresponding cell property data sets. - -ResInsight has been co-developed by Statoil ASA, Ceetron Solutions AS, and Ceetron AS with the aim to provide a versatile tool for professionals who need to visualize and process reservoir models. - -### Contents - -- [ Getting Started ](GettingStarted.md) -- [ Working with 3D Views ](ReservoirViews.md) -- [ Multiple realizations and statistics ](CaseGroupsAndStatistics.md) -- [ Octave Interface](OctaveInterface.md) -- [ Well Trajectories ](WellPaths.md) -- [ Faults ](Faults.md) -- [ Batch Commands ](BatchCommands.md) - -### Appendix - -- [ Octave Interface Reference](OctaveInterfaceReference.md) -- [ Regression Test System ](RegressionTestSystem.md) -- [ Command Line Arguments](CommandLineParameters.md) - - diff --git a/Documentation/UsersGuide/WellPaths.md b/Documentation/UsersGuide/WellPaths.md deleted file mode 100644 index 760de3388a..0000000000 --- a/Documentation/UsersGuide/WellPaths.md +++ /dev/null @@ -1,74 +0,0 @@ -[ Contents ](UsersGuide.md#contents) - ------ -## Well trajectories - -ResInsight can import Well trajectories from simple Ascii files. -In addition, a Statoil specific solution to retrieve Well Trajectories from their internal web service is implemented. - -### Ascii Well Trajectories - -The command **File -> Import -> Import Well Paths From File** will read the well paths in the selected file, and create one entry for each trajectory under the ![](images/WellCollection.png) **Wells** item in the **Project Tree**. - -The supported ASCII format is quite flexible but the main requirements are: - -1. Each data line must contain four numbers: X Y TVD MD separated with white-space. -2. A line starting with none-number-characters are ignored, unless : - 1. If the line contains a pair of : ', `, ´, ’ or ‘ the text between the quotation marks is used as a well name. - 2. If the line contains the case insensitive string "name " the rest of the line is used as a well name. -3. If a well name is found, a new well is created and the following data points ends up in it. - -###### Example 1: - - WELLNAME: ‘WELL1’ - 4507.0 5638.5 0.0 0.0 - 4507 5638.5 4628.6 1628.6 - 4297.4 5938.5 4632.4 1998.387 - -999 - WELLNAME: ‘WELL2’ - 5507.0 4638.5 0.0 0.0 - 5507 4638.5 3628.6 1628.6 - 5297.4 4938.5 3632.4 1998.387 - -999 - -###### Example 2: - X Y TVD MD - Name Well_1 - 5507.0 4638.5 0.0 0.0 - 5507 4638.5 3628.6 1628.6 - 5297.4 4938.5 3632.4 1998.387 - - Name Well_2 - 5507.0 4638.5 0.0 0.0 - 5507 4638.5 3628.6 1628.6 - 5297.4 4938.5 3632.4 1998.387 - - -The trajectory data is not copied into the ResInsight project as such. The project file only stores the file path, and the next time you open the project, ResInsight will try to read the well data from the file again. - -### Importing from SSI-Hub (Internal Statoil web-service) - -The command **File -> Import -> Import Well Paths From SSI-hub** launches a wizard to guide you through the process of selecting the well trajectories you need. - -After completing the wizard, the wells imported are accessible as Items under the ![](images/WellCollection.png) **Wells** item in the **Project Tree**. - -The trajectory data is not copied into the ResInsight project as such, but is stored in files in a directory called _wellpaths in the same directory as your project file. - -### Well Trajectory visualization - -All the imported well trajectories are available below the ![](images/WellCollection.png) **Wells** item in the **Project Tree**. - -![](images/WellsInTree.png) - -The visible wells are always shown in all the 3D Views in the complete project, so the toggles and settings control the overall project visibility of the Well Trajectories. The **Property Editor** of the **Wells** item is shown below - -![](images/WellPathCollectionProperties.png) - -- **Global well path visibility** This option forces the well paths on or off, ignoring the individual settings unless it is set to Individual. -- **Clip Well Paths** This option hides the top of the Well Trajectories to avoid displaying the very long lines from the reservoir to the sea surface. -- **Well Path clipping depth distance** This number is the distance from the top of the reservoir to the clipping depth. - ------- -[ Contents ](UsersGuide.md#contents) - - diff --git a/Documentation/UsersGuide/images/3DViewOverview.png b/Documentation/UsersGuide/images/3DViewOverview.png deleted file mode 100644 index e913685e88..0000000000 Binary files a/Documentation/UsersGuide/images/3DViewOverview.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/AppLogo48x48.png b/Documentation/UsersGuide/images/AppLogo48x48.png deleted file mode 100644 index 521a4b86a9..0000000000 Binary files a/Documentation/UsersGuide/images/AppLogo48x48.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/Case24x24.png b/Documentation/UsersGuide/images/Case24x24.png deleted file mode 100644 index 7e5d04ead7..0000000000 Binary files a/Documentation/UsersGuide/images/Case24x24.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/CaseProperties.png b/Documentation/UsersGuide/images/CaseProperties.png deleted file mode 100644 index fe98659132..0000000000 Binary files a/Documentation/UsersGuide/images/CaseProperties.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/CellEdgeExample.png b/Documentation/UsersGuide/images/CellEdgeExample.png deleted file mode 100644 index c25b47b53c..0000000000 Binary files a/Documentation/UsersGuide/images/CellEdgeExample.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/CellFilter_Range.png b/Documentation/UsersGuide/images/CellFilter_Range.png deleted file mode 100644 index 419a9c095c..0000000000 Binary files a/Documentation/UsersGuide/images/CellFilter_Range.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/CellFilter_Values.png b/Documentation/UsersGuide/images/CellFilter_Values.png deleted file mode 100644 index 891753aad2..0000000000 Binary files a/Documentation/UsersGuide/images/CellFilter_Values.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/CellResult.png b/Documentation/UsersGuide/images/CellResult.png deleted file mode 100644 index 08b84b09ac..0000000000 Binary files a/Documentation/UsersGuide/images/CellResult.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/CreateGridCaseGroup16x16.png b/Documentation/UsersGuide/images/CreateGridCaseGroup16x16.png deleted file mode 100644 index 65bb871267..0000000000 Binary files a/Documentation/UsersGuide/images/CreateGridCaseGroup16x16.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/CreateGridCaseGroup24x24.png b/Documentation/UsersGuide/images/CreateGridCaseGroup24x24.png deleted file mode 100644 index 2146672c1c..0000000000 Binary files a/Documentation/UsersGuide/images/CreateGridCaseGroup24x24.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/CreateGridCaseGroupFromFileDialog.png b/Documentation/UsersGuide/images/CreateGridCaseGroupFromFileDialog.png deleted file mode 100644 index 2e1ca073f6..0000000000 Binary files a/Documentation/UsersGuide/images/CreateGridCaseGroupFromFileDialog.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/EclipseInput24x24.png b/Documentation/UsersGuide/images/EclipseInput24x24.png deleted file mode 100644 index ce0d05b3a0..0000000000 Binary files a/Documentation/UsersGuide/images/EclipseInput24x24.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/EdgeResult_1.png b/Documentation/UsersGuide/images/EdgeResult_1.png deleted file mode 100644 index 3f10ae2462..0000000000 Binary files a/Documentation/UsersGuide/images/EdgeResult_1.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/ExecuteOctaveScriptOnSelectedCases.png b/Documentation/UsersGuide/images/ExecuteOctaveScriptOnSelectedCases.png deleted file mode 100644 index 46eaf014fa..0000000000 Binary files a/Documentation/UsersGuide/images/ExecuteOctaveScriptOnSelectedCases.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/ExportProperty.png b/Documentation/UsersGuide/images/ExportProperty.png deleted file mode 100644 index 4b459d0709..0000000000 Binary files a/Documentation/UsersGuide/images/ExportProperty.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/FaultProperties.png b/Documentation/UsersGuide/images/FaultProperties.png deleted file mode 100644 index 435c54ebc7..0000000000 Binary files a/Documentation/UsersGuide/images/FaultProperties.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/GridCaseGroup24x24.png b/Documentation/UsersGuide/images/GridCaseGroup24x24.png deleted file mode 100644 index 030dc36aaf..0000000000 Binary files a/Documentation/UsersGuide/images/GridCaseGroup24x24.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/GridCaseGroupTree.png b/Documentation/UsersGuide/images/GridCaseGroupTree.png deleted file mode 100644 index b18056213b..0000000000 Binary files a/Documentation/UsersGuide/images/GridCaseGroupTree.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/Histogram24x24.png b/Documentation/UsersGuide/images/Histogram24x24.png deleted file mode 100644 index 6e3cd0aa45..0000000000 Binary files a/Documentation/UsersGuide/images/Histogram24x24.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/HistogramExample.png b/Documentation/UsersGuide/images/HistogramExample.png deleted file mode 100644 index 41ac8c05c3..0000000000 Binary files a/Documentation/UsersGuide/images/HistogramExample.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/InfoBox16x16.png b/Documentation/UsersGuide/images/InfoBox16x16.png deleted file mode 100644 index 8a9342875c..0000000000 Binary files a/Documentation/UsersGuide/images/InfoBox16x16.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/Legend.png b/Documentation/UsersGuide/images/Legend.png deleted file mode 100644 index dd23421bde..0000000000 Binary files a/Documentation/UsersGuide/images/Legend.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/MSWDummyBranchExample.png b/Documentation/UsersGuide/images/MSWDummyBranchExample.png deleted file mode 100644 index ce3cf83292..0000000000 Binary files a/Documentation/UsersGuide/images/MSWDummyBranchExample.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/OctaveScriptTree.png b/Documentation/UsersGuide/images/OctaveScriptTree.png deleted file mode 100644 index e36d58749e..0000000000 Binary files a/Documentation/UsersGuide/images/OctaveScriptTree.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/PropertyFilterProperties.png b/Documentation/UsersGuide/images/PropertyFilterProperties.png deleted file mode 100644 index f264a440b3..0000000000 Binary files a/Documentation/UsersGuide/images/PropertyFilterProperties.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/RangeFilterProperties.png b/Documentation/UsersGuide/images/RangeFilterProperties.png deleted file mode 100644 index 96111973ba..0000000000 Binary files a/Documentation/UsersGuide/images/RangeFilterProperties.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/RegressionTestDialog.png b/Documentation/UsersGuide/images/RegressionTestDialog.png deleted file mode 100644 index d9c4ebc9ec..0000000000 Binary files a/Documentation/UsersGuide/images/RegressionTestDialog.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/ResInsightUIFullSize.png b/Documentation/UsersGuide/images/ResInsightUIFullSize.png deleted file mode 100644 index 006086050f..0000000000 Binary files a/Documentation/UsersGuide/images/ResInsightUIFullSize.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/ResInsightUIFullSizeWindows.png b/Documentation/UsersGuide/images/ResInsightUIFullSizeWindows.png deleted file mode 100644 index 6b14f74160..0000000000 Binary files a/Documentation/UsersGuide/images/ResInsightUIFullSizeWindows.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/ResInsightUIMediumSize.png b/Documentation/UsersGuide/images/ResInsightUIMediumSize.png deleted file mode 100644 index 6ad520ccbe..0000000000 Binary files a/Documentation/UsersGuide/images/ResInsightUIMediumSize.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/ResInsightUISmallSizeWindows.png b/Documentation/UsersGuide/images/ResInsightUISmallSizeWindows.png deleted file mode 100644 index 543640c45e..0000000000 Binary files a/Documentation/UsersGuide/images/ResInsightUISmallSizeWindows.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/ReservoirView.png b/Documentation/UsersGuide/images/ReservoirView.png deleted file mode 100644 index 42e19dbbe8..0000000000 Binary files a/Documentation/UsersGuide/images/ReservoirView.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/RestoreDown.PNG b/Documentation/UsersGuide/images/RestoreDown.PNG deleted file mode 100644 index afa5277146..0000000000 Binary files a/Documentation/UsersGuide/images/RestoreDown.PNG and /dev/null differ diff --git a/Documentation/UsersGuide/images/SimulationWellsProperties.png b/Documentation/UsersGuide/images/SimulationWellsProperties.png deleted file mode 100644 index 9d47cc4963..0000000000 Binary files a/Documentation/UsersGuide/images/SimulationWellsProperties.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/SnapShot.png b/Documentation/UsersGuide/images/SnapShot.png deleted file mode 100644 index ad94cdef02..0000000000 Binary files a/Documentation/UsersGuide/images/SnapShot.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/SnapShotSave.png b/Documentation/UsersGuide/images/SnapShotSave.png deleted file mode 100644 index f0536c39b9..0000000000 Binary files a/Documentation/UsersGuide/images/SnapShotSave.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/SnapShotSaveViews.png b/Documentation/UsersGuide/images/SnapShotSaveViews.png deleted file mode 100644 index ee526bc6ee..0000000000 Binary files a/Documentation/UsersGuide/images/SnapShotSaveViews.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/StatisticsCaseProperties.png b/Documentation/UsersGuide/images/StatisticsCaseProperties.png deleted file mode 100644 index e31f00dd80..0000000000 Binary files a/Documentation/UsersGuide/images/StatisticsCaseProperties.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/StatisticsCasePropertiesCalculated.png b/Documentation/UsersGuide/images/StatisticsCasePropertiesCalculated.png deleted file mode 100644 index db72e512cf..0000000000 Binary files a/Documentation/UsersGuide/images/StatisticsCasePropertiesCalculated.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/TopLink.png b/Documentation/UsersGuide/images/TopLink.png deleted file mode 100644 index be404c4ffd..0000000000 Binary files a/Documentation/UsersGuide/images/TopLink.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/TreeViewToggle.png b/Documentation/UsersGuide/images/TreeViewToggle.png deleted file mode 100644 index 27713e326f..0000000000 Binary files a/Documentation/UsersGuide/images/TreeViewToggle.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/WellCollection.png b/Documentation/UsersGuide/images/WellCollection.png deleted file mode 100644 index 38dcffa4e3..0000000000 Binary files a/Documentation/UsersGuide/images/WellCollection.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/WellPathCollectionProperties.png b/Documentation/UsersGuide/images/WellPathCollectionProperties.png deleted file mode 100644 index a8626cbf75..0000000000 Binary files a/Documentation/UsersGuide/images/WellPathCollectionProperties.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/WellProperties.png b/Documentation/UsersGuide/images/WellProperties.png deleted file mode 100644 index 2af593ad16..0000000000 Binary files a/Documentation/UsersGuide/images/WellProperties.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/WellsInTree.png b/Documentation/UsersGuide/images/WellsInTree.png deleted file mode 100644 index 68bf5cdfed..0000000000 Binary files a/Documentation/UsersGuide/images/WellsInTree.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/draw_style_faults_24x24.png b/Documentation/UsersGuide/images/draw_style_faults_24x24.png deleted file mode 100644 index a1c901888c..0000000000 Binary files a/Documentation/UsersGuide/images/draw_style_faults_24x24.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/draw_style_faults_label_24x24.png b/Documentation/UsersGuide/images/draw_style_faults_label_24x24.png deleted file mode 100644 index 03617816d0..0000000000 Binary files a/Documentation/UsersGuide/images/draw_style_faults_label_24x24.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/draw_style_surface_24x24.png b/Documentation/UsersGuide/images/draw_style_surface_24x24.png deleted file mode 100644 index 012adb6b72..0000000000 Binary files a/Documentation/UsersGuide/images/draw_style_surface_24x24.png and /dev/null differ diff --git a/Documentation/UsersGuide/images/draw_style_surface_w_fault_mesh_24x24.png b/Documentation/UsersGuide/images/draw_style_surface_w_fault_mesh_24x24.png deleted file mode 100644 index 7a005b897e..0000000000 Binary files a/Documentation/UsersGuide/images/draw_style_surface_w_fault_mesh_24x24.png and /dev/null differ diff --git a/Fwk/AppFwk/CommonCode/cvfStructGrid.cpp b/Fwk/AppFwk/CommonCode/cvfStructGrid.cpp index 3c2c240986..708e3ad558 100644 --- a/Fwk/AppFwk/CommonCode/cvfStructGrid.cpp +++ b/Fwk/AppFwk/CommonCode/cvfStructGrid.cpp @@ -44,12 +44,12 @@ namespace caf template<> void cvf::StructGridInterface::FaceEnum::setUp() { - addItem(cvf::StructGridInterface::POS_I, "X", ""); - addItem(cvf::StructGridInterface::NEG_I, "X-", ""); - addItem(cvf::StructGridInterface::POS_J, "Y", ""); - addItem(cvf::StructGridInterface::NEG_J, "Y-", ""); - addItem(cvf::StructGridInterface::POS_K, "Z", ""); - addItem(cvf::StructGridInterface::NEG_K, "Z-", ""); + addItem(cvf::StructGridInterface::POS_I, "POS I", ""); + addItem(cvf::StructGridInterface::NEG_I, "NEG I", ""); + addItem(cvf::StructGridInterface::POS_J, "POS J", ""); + addItem(cvf::StructGridInterface::NEG_J, "NEG J", ""); + addItem(cvf::StructGridInterface::POS_K, "POS K", ""); + addItem(cvf::StructGridInterface::NEG_K, "NEG K", ""); addItem(cvf::StructGridInterface::NO_FACE, "UnDef", ""); } } @@ -220,7 +220,7 @@ cvf::Vec3d StructGridInterface::displayModelOffset() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void StructGridInterface::characteristicCellSizes(double* iSize, double* jSize, double* kSize) +void StructGridInterface::characteristicCellSizes(double* iSize, double* jSize, double* kSize) const { CVF_ASSERT(iSize && jSize && kSize); diff --git a/Fwk/AppFwk/CommonCode/cvfStructGrid.h b/Fwk/AppFwk/CommonCode/cvfStructGrid.h index 8f6019bdc9..0ed191f09a 100644 --- a/Fwk/AppFwk/CommonCode/cvfStructGrid.h +++ b/Fwk/AppFwk/CommonCode/cvfStructGrid.h @@ -84,7 +84,7 @@ class StructGridInterface : public Object virtual cvf::Vec3d minCoordinate() const = 0; virtual cvf::Vec3d maxCoordinate() const = 0; - void characteristicCellSizes(double* iSize, double* jSize, double* kSize); + void characteristicCellSizes(double* iSize, double* jSize, double* kSize) const; virtual cvf::Vec3d displayModelOffset() const; @@ -109,9 +109,9 @@ class StructGridInterface : public Object static void neighborIJKAtCellFace(size_t i, size_t j, size_t k, StructGridInterface::FaceType face, size_t* ni, size_t* nj, size_t* nk); private: - double m_characteristicCellSizeI; - double m_characteristicCellSizeJ; - double m_characteristicCellSizeK; + mutable double m_characteristicCellSizeI; + mutable double m_characteristicCellSizeJ; + mutable double m_characteristicCellSizeK; }; } // namespace cvf diff --git a/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.cpp b/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.cpp index 977b451e63..3af8efd688 100644 --- a/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.cpp +++ b/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.cpp @@ -159,6 +159,8 @@ StructGridGeometryGenerator::StructGridGeometryGenerator(const StructGridInterfa : m_grid(grid) { CVF_ASSERT(grid); + m_quadMapper = new StructGridQuadToCellFaceMapper; + m_triangleMapper = new StuctGridTriangleToCellFaceMapper(m_quadMapper.p()); } @@ -309,8 +311,8 @@ bool StructGridGeometryGenerator::isCellFaceVisible(size_t i, size_t j, size_t k void StructGridGeometryGenerator::computeArrays() { std::vector vertices; - m_quadsToGridCells.clear(); - m_quadsToFace.clear(); + m_quadMapper->quadToCellIndexMap().clear(); + m_quadMapper->quadToCellFaceMap().clear(); cvf::Vec3d offset = m_grid->displayModelOffset(); @@ -362,8 +364,8 @@ void StructGridGeometryGenerator::computeArrays() } // Keep track of the source cell index per quad - m_quadsToGridCells.push_back(cellIndex); - m_quadsToFace.push_back(face); + m_quadMapper->quadToCellIndexMap().push_back(cellIndex); + m_quadMapper->quadToCellFaceMap().push_back(face); } } } @@ -381,11 +383,11 @@ void StructGridGeometryGenerator::computeArrays() /// Calculates the texture coordinates in a "nearly" one dimentional texture. /// Undefined values are coded with a y-texturecoordinate value of 1.0 instead of the normal 0.5 //-------------------------------------------------------------------------------------------------- -void StructGridGeometryGenerator::textureCoordinates(Vec2fArray* textureCoords, const StructGridScalarDataAccess* dataAccessObject, const ScalarMapper* mapper) const +void StructGridGeometryGenerator::textureCoordinates(Vec2fArray* textureCoords, const StructGridScalarDataAccess* resultAccessor, const ScalarMapper* mapper) const { - if (!dataAccessObject) return; + if (!resultAccessor) return; - size_t numVertices = m_quadsToGridCells.size()*4; + size_t numVertices = m_quadMapper->quadCount()*4; textureCoords->resize(numVertices); cvf::Vec2f* rawPtr = textureCoords->ptr(); @@ -394,9 +396,9 @@ void StructGridGeometryGenerator::textureCoordinates(Vec2fArray* textureCoords, cvf::Vec2f texCoord; #pragma omp parallel for private(texCoord, cellScalarValue) - for (int i = 0; i < static_cast(m_quadsToGridCells.size()); i++) + for (int i = 0; i < static_cast(m_quadMapper->quadCount()); i++) { - cellScalarValue = dataAccessObject->cellScalar(m_quadsToGridCells[i]); + cellScalarValue = resultAccessor->cellScalar(m_quadMapper->cellIndex(i)); texCoord = mapper->mapToTextureCoord(cellScalarValue); if (cellScalarValue == HUGE_VAL || cellScalarValue != cellScalarValue) // a != a is true for NAN's { @@ -411,37 +413,43 @@ void StructGridGeometryGenerator::textureCoordinates(Vec2fArray* textureCoords, } } +#if 0 //-------------------------------------------------------------------------------------------------- /// +/// //-------------------------------------------------------------------------------------------------- -ref > StructGridGeometryGenerator::triangleToSourceGridCellMap() const +void StructGridGeometryGenerator::textureCoordinatesFromSingleFaceValues(Vec2fArray* textureCoords, const ScalarMapper* mapper, const CellFaceValueCalculator* resultAccessor) const { - ref > triangles = new Array(2*m_quadsToGridCells.size()); -#pragma omp parallel for - for (int i = 0; i < static_cast(m_quadsToGridCells.size()); i++) - { - triangles->set(i*2, m_quadsToGridCells[i]); - triangles->set(i*2+1, m_quadsToGridCells[i]); - } + if (!resultAccessor) return; - return triangles; -} + textureCoords->resize(m_quadMapper->quadCount()*4); -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref > StructGridGeometryGenerator::triangleToFaceTypes() const -{ - ref > triangles = new Array(2*m_quadsToFace.size()); -#pragma omp parallel for - for (int i = 0; i < static_cast(m_quadsToFace.size()); i++) + cvf::Vec2f* rawPtr = textureCoords->ptr(); + + double cellFaceValue; + cvf::Vec2f texCoord; + int quadCount = static_cast(m_quadMapper->quadCount()); + +#pragma omp parallel for private(texCoord, cellFaceValue) + for (int qIdx = 0; qIdx < quadCount; qIdx++) { - triangles->set(i*2, m_quadsToFace[i]); - triangles->set(i*2+1, m_quadsToFace[i]); - } + cellFaceValue = resultAccessor->cellFaceScalar(m_quadMapper->cellIndex(qIdx), m_quadMapper->faceType(qIdx)); + + texCoord = mapper->mapToTextureCoord(cellFaceValue); + + if (cellFaceValue == HUGE_VAL || cellFaceValue != cellFaceValue) // a != a is true for NAN's + { + texCoord[1] = 1.0f; + } - return triangles; + size_t j; + for (j = 0; j < 4; j++) + { + rawPtr[qIdx*4 + j] = texCoord; + } + } } +#endif //-------------------------------------------------------------------------------------------------- /// @@ -451,21 +459,5 @@ void StructGridGeometryGenerator::setCellVisibility(const UByteArray* cellVisibi m_cellVisibility = cellVisibility; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const std::vector& StructGridGeometryGenerator::quadToGridCellIndices() const -{ - return m_quadsToGridCells; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const std::vector& StructGridGeometryGenerator::quadToFace() const -{ - return m_quadsToFace; -} - } // namespace cvf diff --git a/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.h b/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.h index 9b95797a1d..cced178fe9 100644 --- a/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.h +++ b/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.h @@ -121,6 +121,37 @@ class CellFaceVisibilityFilter }; +class StructGridQuadToCellFaceMapper : public Object +{ +public: + size_t quadCount() const { return m_quadsToCells.size();} + + size_t cellIndex(size_t quadIdx) const {return m_quadsToCells[quadIdx]; } + StructGridInterface::FaceType cellFace(size_t quadIdx) const {return m_quadsToFace[quadIdx]; } + + // Interface for building the mappings + std::vector& quadToCellIndexMap() { return m_quadsToCells; } + std::vector& quadToCellFaceMap() { return m_quadsToFace; } + +private: + std::vector m_quadsToCells; + std::vector m_quadsToFace; +}; + + +class StuctGridTriangleToCellFaceMapper : public Object +{ +public: + StuctGridTriangleToCellFaceMapper(const StructGridQuadToCellFaceMapper* quadMapper) { m_quadMapper = quadMapper; } + size_t triangleCount() const { return 2* m_quadMapper->quadCount();} + + size_t cellIndex(size_t triangleIdx) const {return m_quadMapper->cellIndex(triangleIdx/2); } + StructGridInterface::FaceType cellFace(size_t triangleIdx) const {return m_quadMapper->cellFace(triangleIdx/2); } + +private: + cref m_quadMapper; +}; + //================================================================================================== // @@ -142,19 +173,12 @@ class StructGridGeometryGenerator : public Object const StructGridInterface* activeGrid() { return m_grid.p(); } - void textureCoordinates(Vec2fArray* textureCoords, const StructGridScalarDataAccess* dataAccessObject, const ScalarMapper* mapper) const; + void textureCoordinates(Vec2fArray* textureCoords, const StructGridScalarDataAccess* resultAccessor, const ScalarMapper* mapper) const; // Mapping between cells and geometry - ref > - triangleToSourceGridCellMap() const; - - cvf::ref > - triangleToFaceTypes() const; - const std::vector& - quadToGridCellIndices() const; - const std::vector& - quadToFace() const; + const StructGridQuadToCellFaceMapper * quadToCellFaceMapper() { return m_quadMapper.p(); } + const StuctGridTriangleToCellFaceMapper * triangleToCellFaceMapper() { return m_triangleMapper.p(); } // Generated geometry ref generateSurface(); @@ -176,11 +200,10 @@ class StructGridGeometryGenerator : public Object // Created arrays cvf::ref m_vertices; + // Mappings - std::vector m_triangleIndexToGridCellIndex; - std::vector m_quadsToGridCells; - std::vector m_quadsToFace; - + ref m_quadMapper; + ref m_triangleMapper; }; } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafFixedArray.h b/Fwk/AppFwk/cafProjectDataModel/cafFixedArray.h index 56a8c83393..6602c333cb 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafFixedArray.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafFixedArray.h @@ -55,8 +55,8 @@ class FixedArray FixedArray& operator=(const T* ptr) { for (size_t i = 0; i < size ; ++i) m_array[i] = ptr[i]; return *this;} - template T& operator[](const IndexType& index) { CVF_TIGHT_ASSERT(static_cast(index) < size); return m_array[index]; } - template const T& operator[](const IndexType& index) const { CVF_TIGHT_ASSERT(static_cast(index) < size); return m_array[index]; } + template T& operator[](const IndexType& index) { return m_array[index]; } + template const T& operator[](const IndexType& index) const { return m_array[index]; } }; typedef FixedArray IntArray3; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp index d6c3c5504b..0dec597148 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp @@ -89,31 +89,6 @@ void PdmObjectGroup::addObject(PdmObject * obj) objects.push_back(obj); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObjectGroup::initAfterReadTraversal(PdmObject* object) -{ - if (object == NULL) return; - - std::vector fields; - object->fields(fields); - - std::vector children; - size_t fIdx; - for (fIdx = 0; fIdx < fields.size(); ++fIdx) - { - if (fields[fIdx]) fields[fIdx]->childObjects(&children); - } - - size_t cIdx; - for (cIdx = 0; cIdx < children.size(); ++cIdx) - { - PdmObjectGroup::initAfterReadTraversal(children[cIdx]); - } - - object->initAfterRead(); -} @@ -166,6 +141,7 @@ void PdmDocument::readFile(QIODevice* xmlFile) // after everything is read from file PdmDocument::initAfterReadTraversal(this); + PdmDocument::updateUiIconStateRecursively(this); } //-------------------------------------------------------------------------------------------------- @@ -201,7 +177,9 @@ void PdmDocument::writeFile(QIODevice* xmlFile) xmlStream.writeEndDocument(); } - +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- void PdmDocument::setupBeforeSaveTraversal(PdmObject * object) { if (object == NULL) return; @@ -225,5 +203,57 @@ void PdmDocument::setupBeforeSaveTraversal(PdmObject * object) object->setupBeforeSave(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmDocument::initAfterReadTraversal(PdmObject* object) +{ + if (object == NULL) return; + + std::vector fields; + object->fields(fields); + + std::vector children; + size_t fIdx; + for (fIdx = 0; fIdx < fields.size(); ++fIdx) + { + if (fields[fIdx]) fields[fIdx]->childObjects(&children); + } + + size_t cIdx; + for (cIdx = 0; cIdx < children.size(); ++cIdx) + { + PdmDocument::initAfterReadTraversal(children[cIdx]); + } + + object->initAfterRead(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmDocument::updateUiIconStateRecursively(PdmObject* object) +{ + if (object == NULL) return; + + std::vector fields; + object->fields(fields); + + std::vector children; + size_t fIdx; + for (fIdx = 0; fIdx < fields.size(); ++fIdx) + { + if (fields[fIdx]) fields[fIdx]->childObjects(&children); + } + + size_t cIdx; + for (cIdx = 0; cIdx < children.size(); ++cIdx) + { + PdmDocument::updateUiIconStateRecursively(children[cIdx]); + } + + object->updateUiIconFromToggleField(); +} + } //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.h index bdd8ff8e4e..1b9a200c0a 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.h @@ -62,8 +62,6 @@ class PdmObjectGroup : public PdmObject void removeNullPtrs(); void addObject(PdmObject * obj); - static void initAfterReadTraversal(PdmObject * root); - template void objectsByType(std::vector >* typedObjects ) const { @@ -128,8 +126,12 @@ class PdmDocument: public PdmObjectGroup void readFile(QIODevice* device); void writeFile(QIODevice* device); + static void updateUiIconStateRecursively(PdmObject * root); + static void initAfterReadTraversal(PdmObject * root); + private: static void setupBeforeSaveTraversal(PdmObject * root); + }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.cpp index d752765d8e..d32c20c4fa 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.cpp @@ -464,5 +464,17 @@ void PdmObject::addUiTreeChildren(PdmUiTreeOrdering* root, QString uiConfigName } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObject::updateUiIconFromToggleField() +{ + if (objectToggleField()) + { + bool active = objectToggleField()->uiValue().toBool(); + updateUiIconFromState(active); + } +} + } //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h index 94eb759c48..8bb9410b87 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h @@ -174,6 +174,8 @@ class PdmObject : public PdmUiItem /// Return object editor specific parameters used to customize the editor behavior. void objectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute* attribute); + void updateUiIconFromToggleField(); + // Virtual interface to override in subclasses to support special behaviour if needed public: // Virtual virtual PdmFieldHandle* userDescriptionField() { return NULL; } @@ -197,6 +199,7 @@ class PdmObject : public PdmUiItem /// Method gets called from PdmDocument after all objects are read. /// Re-implement to set up internal pointers etc. in your data structure virtual void initAfterRead() {}; + /// Method gets called from PdmDocument before saving document. /// Re-implement to make sure your fields have correct data before saving virtual void setupBeforeSave() {}; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.cpp index 748cf69a9a..7a8ac5dc30 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.cpp @@ -63,14 +63,24 @@ void PdmUiCheckBoxEditor::configureAndUpdateUi(const QString& uiConfigName) assert(!m_checkBox.isNull()); assert(!m_label.isNull()); - QIcon ic = field()->uiIcon(uiConfigName); - if (!ic.isNull()) + PdmUiCheckBoxEditorAttribute attributes; + field()->ownerObject()->editorAttribute(field(), uiConfigName, &attributes); + + if (attributes.m_useNativeCheckBoxLabel) { - m_label->setPixmap(ic.pixmap(ic.actualSize(QSize(64, 64)))); + m_checkBox->setText(field()->uiName(uiConfigName)); } else { - m_label->setText(field()->uiName(uiConfigName)); + QIcon ic = field()->uiIcon(uiConfigName); + if (!ic.isNull()) + { + m_label->setPixmap(ic.pixmap(ic.actualSize(QSize(64, 64)))); + } + else + { + m_label->setText(field()->uiName(uiConfigName)); + } } m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); @@ -79,9 +89,6 @@ void PdmUiCheckBoxEditor::configureAndUpdateUi(const QString& uiConfigName) m_checkBox->setEnabled(!field()->isUiReadOnly(uiConfigName)); m_checkBox->setToolTip(field()->uiToolTip(uiConfigName)); - PdmUiCheckBoxEditorAttribute attributes; - field()->ownerObject()->editorAttribute(field(), uiConfigName, &attributes); - m_checkBox->setChecked(field()->uiValue().toBool()); } diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.h index 6b01f50e5a..bf67da9809 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.h @@ -52,7 +52,14 @@ namespace caf class PdmUiCheckBoxEditorAttribute : public PdmUiEditorAttribute { +public: + PdmUiCheckBoxEditorAttribute() + { + m_useNativeCheckBoxLabel = false; + } +public: + bool m_useNativeCheckBoxLabel; }; diff --git a/Fwk/AppFwk/cafUserInterface/cafUiTreeModelPdm.cpp b/Fwk/AppFwk/cafUserInterface/cafUiTreeModelPdm.cpp index 5c5718e878..4e5832b608 100644 --- a/Fwk/AppFwk/cafUserInterface/cafUiTreeModelPdm.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafUiTreeModelPdm.cpp @@ -392,6 +392,7 @@ void UiTreeModelPdm::updateUiSubTree(PdmObject* pdmRoot) // Build the new "Correct" Tree PdmUiTreeItem* tempUpdatedPdmTree = UiTreeItemBuilderPdm::buildViewItems(NULL, -1, pdmRoot); + if (!tempUpdatedPdmTree) return; // Find the corresponding entry for "root" in the existing Ui tree diff --git a/OctavePlugin/MinGWBuildConfigurationForOctave.txt b/OctavePlugin/MinGWBuildConfigurationForOctave.txt new file mode 100644 index 0000000000..f74b37cda3 --- /dev/null +++ b/OctavePlugin/MinGWBuildConfigurationForOctave.txt @@ -0,0 +1,17 @@ +Build configuration MinGW +================================== + +http://wiki.octave.org/Windows_Installer + +To be able to build with 64-bit indexing, run the following + +./configure --enable-64 + + + +// To get changes from server +hg pull +hg update + +http://hgbook.red-bean.com/read/a-tour-of-mercurial-the-basics.html + diff --git a/OctavePlugin/OctaveScripts/OctaveInterfaceTest.m b/OctavePlugin/OctaveScripts/OctaveInterfaceTest.m index 63ddcb9753..0dfa441bc8 100644 --- a/OctavePlugin/OctaveScripts/OctaveInterfaceTest.m +++ b/OctavePlugin/OctaveScripts/OctaveInterfaceTest.m @@ -1,6 +1,7 @@ ### The case with caseid 1 has to be selected/active in ResInsight when running this test-script ### Coarsening and Dual porosity is not exercised by this tes yet. We need models + ### CaseInfo riGetCurrentCase() %!test %! printf ("===== Testing ====> riGetCurrentCase\n"); @@ -113,7 +114,6 @@ %! PropertyInfos2 = riGetPropertyNames(1); %! PropertyInfos3 = riGetPropertyNames("Matrix"); %! PropertyInfos4 = riGetPropertyNames(1, "Matrix"); -%! assert(rows(PropertyInfos1) == 26) %! assert(PropertyInfos1(1).PropName == "PRESSURE"); %! assert(PropertyInfos1(1).PropType == "DynamicNative"); %! assert(PropertyInfos1(26).PropType == "StaticNative"); @@ -121,29 +121,29 @@ ### Matrix[numActiveCells][numTimestepsRequested] riGetActiveCellProperty([CaseId], PropertyName, [RequestedTimeSteps], [PorosityModel = "Matrix"|"Fracture"]) %!test %! printf ("===== Testing ====> riGetActiveCellProperty\n"); -%! ActivePropData1 = riGetActiveCellProperty("SOIL"); +%! ActivePropData1 = riGetActiveCellProperty("SWAT"); %! assert (rows(ActivePropData1) == rows(riGetActiveCellInfo())); %! assert (columns(ActivePropData1) == rows(riGetTimeStepDays())); -%! ActivePropData2 = riGetActiveCellProperty("SOIL", "Matrix"); +%! ActivePropData2 = riGetActiveCellProperty("SWAT", "Matrix"); %! assert (ActivePropData2 == ActivePropData1); -%! ActivePropData3 = riGetActiveCellProperty("SOIL", [1,3]); +%! ActivePropData3 = riGetActiveCellProperty("SWAT", [1,3]); %! assert (columns(ActivePropData3) == 2); %! assert (ActivePropData3(:,2) == ActivePropData1(:,3)); -%! ActivePropData4 = riGetActiveCellProperty("SOIL", [1,3], "Matrix"); +%! ActivePropData4 = riGetActiveCellProperty("SWAT", [1,3], "Matrix"); %! assert (ActivePropData3 == ActivePropData4); -%! ActivePropData5 = riGetActiveCellProperty(1, "SOIL"); +%! ActivePropData5 = riGetActiveCellProperty(1, "SWAT"); %! assert (ActivePropData5 == ActivePropData1); -%! ActivePropData6 = riGetActiveCellProperty(1, "SOIL", [1,3]); +%! ActivePropData6 = riGetActiveCellProperty(1, "SWAT", [1,3]); %! assert (ActivePropData6 == ActivePropData3); -%! ActivePropData7 = riGetActiveCellProperty(1, "SOIL", [1,3], "Matrix"); +%! ActivePropData7 = riGetActiveCellProperty(1, "SWAT", [1,3], "Matrix"); %! assert (ActivePropData7 == ActivePropData3); -%! ActivePropData8 = riGetActiveCellProperty(1, "SOIL", "Matrix"); +%! ActivePropData8 = riGetActiveCellProperty(1, "SWAT", "Matrix"); %! assert (ActivePropData8 == ActivePropData1); ### Matrix[numI][numJ][numK][numTimestepsRequested] riGetGridProperty([CaseId], GridIndex , PropertyName, [RequestedTimeSteps], [PorosityModel = "Matrix"|"Fracture"]) %!test %! printf ("===== Testing ====> riGetGridProperty\n"); -%! GridProps1 = riGetGridProperty( 0 , "SOIL" ); +%! GridProps1 = riGetGridProperty( 0 , "SWAT" ); %! assert( ndims (GridProps1) == 4); %! [ni, nj, nk, nts ] = size(GridProps1); %! disp(nts); @@ -151,23 +151,23 @@ %! assert(ni == 139); %! assert(nj == 48); %! assert(nk == 9); -%! assert(GridProps1(62,30,1,3), 0.59058, 0.00001); +%! assert(GridProps1(62,30,1,3), 0.40942, 0.00001); -%! GridProps2 = riGetGridProperty( 0 , "SOIL", [1,3]); +%! GridProps2 = riGetGridProperty( 0 , "SWAT", [1,3]); %! assert( ndims (GridProps2) == 4); %! [ni, nj, nk, nts ] = size(GridProps2); %! assert(nts == 2); %! assert(ni == 139); %! assert(nj == 48); %! assert(nk == 9); -%! assert(GridProps2(62,30,1,2), 0.59058, 0.00001); +%! assert(GridProps2(62,30,1,2), 0.40942, 0.00001); -%! GridProps3 = riGetGridProperty( 0 , "SOIL", [1,3], "Matrix"); -%! GridProps4 = riGetGridProperty( 0 , "SOIL", "Matrix"); -%! GridProps5 = riGetGridProperty(1, 0 , "SOIL" ); -%! GridProps6 = riGetGridProperty(1, 0 , "SOIL", [1,3]); -%! GridProps7 = riGetGridProperty(1, 0 , "SOIL", [1,3], "Matrix"); -%! GridProps8 = riGetGridProperty(1, 0 , "SOIL", "Matrix"); +%! GridProps3 = riGetGridProperty( 0 , "SWAT", [1,3], "Matrix"); +%! GridProps4 = riGetGridProperty( 0 , "SWAT", "Matrix"); +%! GridProps5 = riGetGridProperty(1, 0 , "SWAT" ); +%! GridProps6 = riGetGridProperty(1, 0 , "SWAT", [1,3]); +%! GridProps7 = riGetGridProperty(1, 0 , "SWAT", [1,3], "Matrix"); +%! GridProps8 = riGetGridProperty(1, 0 , "SWAT", "Matrix"); %! assert(GridProps3 == GridProps2); %! assert(GridProps4 == GridProps1); @@ -180,8 +180,8 @@ ### riSetActiveCellProperty( Matrix[numActiveCells][numTimeSteps], [CaseId], PropertyName, [TimeStepIndices], [PorosityModel = "Matrix"|"Fracture"]) %!test %! printf ("===== Testing ====> riSetActiveCellProperty\n"); -%! ActivePropData1 = riGetActiveCellProperty("SOIL"); -%! ActivePropData3 = riGetActiveCellProperty("SOIL", [1,3]); +%! ActivePropData1 = riGetActiveCellProperty("SWAT"); +%! ActivePropData3 = riGetActiveCellProperty("SWAT", [1,3]); %! riSetActiveCellProperty( ActivePropData1, "PropertyName1" ); %! riSetActiveCellProperty( ActivePropData3, "PropertyName2", [1,3]); @@ -204,8 +204,8 @@ ### riSetGridProperty( Matrix[numI][numJ][numK][numTimeSteps], [CaseId], GridIndex, PropertyName, [TimeStepIndices], [PorosityModel = "Matrix"|"Fracture"]) %!test %! printf ("===== Testing ====> riSetGridProperty\n"); -%! GridProps1 = riGetGridProperty( 0 , "SOIL" ); -%! GridProps2 = riGetGridProperty( 0 , "SOIL", [1,3]); +%! GridProps1 = riGetGridProperty( 0 , "SWAT" ); +%! GridProps2 = riGetGridProperty( 0 , "SWAT", [1,3]); %! riSetGridProperty( GridProps1, 0, "PropertyName11" ); %! riSetGridProperty( GridProps2, 0, "PropertyName12", [1,3]); @@ -309,7 +309,7 @@ %! assert (WellNames2{113}, "P20-03"); ### Vector[WellCellInfo] riGetWellCells([CaseId], WellName, TimeStep) -%!xtest +%!test %! printf ("===== Testing ====> riGetWellCells\n"); %! WellNames1 = riGetWellNames(); %! WellCellInfos1 = riGetWellCells(1, WellNames1{1}, 3); @@ -317,7 +317,7 @@ ### Vector[WellStatus] riGetWellStatus ([CaseId], WellName, [RequestedTimeSteps]) -%!xtest +%!test %! printf ("===== Testing ====> riGetWellStatus\n"); %! WellNames1 = riGetWellNames(); %! WellStatuses1 = riGetWellStatus(1, WellNames1{1}, [1,3]); diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index 69e4286f37..59bddbc2c0 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -1,8 +1,9 @@ set(CMAKE_MAJOR_VERSION 1) -set(CMAKE_MINOR_VERSION 2) +set(CMAKE_MINOR_VERSION 3) set(CMAKE_PATCH_VERSION 0) +# set(DEV_VERSION "-dev") set(PRODUCTVER ${CMAKE_MAJOR_VERSION},${CMAKE_MINOR_VERSION},0,${CMAKE_PATCH_VERSION}) -set(STRPRODUCTVER ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}) +set(STRPRODUCTVER ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}${DEV_VERSION})