diff --git a/ApplicationCode/Commands/RicImportElementPropertyFeature.cpp b/ApplicationCode/Commands/RicImportElementPropertyFeature.cpp index 9064e42abf..1c1c59bbc4 100644 --- a/ApplicationCode/Commands/RicImportElementPropertyFeature.cpp +++ b/ApplicationCode/Commands/RicImportElementPropertyFeature.cpp @@ -20,13 +20,19 @@ #include "RiaApplication.h" +#include "RigFemPartResultsCollection.h" +#include "RigGeoMechCaseData.h" + +#include "RimGeoMechCase.h" +#include "RimGeoMechView.h" + #include #include CAF_CMD_SOURCE_INIT(RicImportElementPropertyFeature, "RicImportElementPropertyFeature"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RicImportElementPropertyFeature::isCommandEnabled() { @@ -34,32 +40,43 @@ bool RicImportElementPropertyFeature::isCommandEnabled() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicImportElementPropertyFeature::onActionTriggered(bool isChecked) { RiaApplication* app = RiaApplication::instance(); - QString defaultDir = app->lastUsedDialogDirectory("ELM_PROPS"); - QStringList fileNames = QFileDialog::getOpenFileNames(NULL, "Import Element Property Table", defaultDir, "Property Table (*.inp)"); - + QString defaultDir = app->lastUsedDialogDirectory("ELM_PROPS"); + QStringList fileNames = + QFileDialog::getOpenFileNames(NULL, "Import Element Property Table", defaultDir, "Property Table (*.inp)"); + if (fileNames.size()) { defaultDir = QFileInfo(fileNames.last()).absolutePath(); } + std::vector fileNamesStd; + for (QString filename : fileNames) + { + fileNamesStd.push_back(filename); + } + app->setLastUsedDialogDirectory("ELM_PROPS", defaultDir); - for (int i = 0; i < fileNames.size(); i++) - { - QString fileName = fileNames[i]; + Rim3dView* activeView = RiaApplication::instance()->activeReservoirView(); + if (!activeView) return; + + RimGeoMechView* activeGmv = dynamic_cast(activeView); + if (!activeGmv) return; - //TODO + if (activeGmv->geoMechCase()) + { + activeGmv->geoMechCase()->addElementPropertyFiles(fileNamesStd); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicImportElementPropertyFeature::setupActionLook(QAction* actionToSetup) { diff --git a/ApplicationCode/FileInterface/CMakeLists_files.cmake b/ApplicationCode/FileInterface/CMakeLists_files.cmake index 96f3ba89cd..3f2483b921 100644 --- a/ApplicationCode/FileInterface/CMakeLists_files.cmake +++ b/ApplicationCode/FileInterface/CMakeLists_files.cmake @@ -41,6 +41,8 @@ ${CEE_CURRENT_LIST_DIR}RifCsvUserDataParser.h ${CEE_CURRENT_LIST_DIR}RifWellPathFormationReader.h ${CEE_CURRENT_LIST_DIR}RifWellPathFormationsImporter.h ${CEE_CURRENT_LIST_DIR}RifElementPropertyTableReader.h +${CEE_CURRENT_LIST_DIR}RifElementPropertyReader.h + # HDF5 file reader is directly included in ResInsight main CmakeList.txt #${CEE_CURRENT_LIST_DIR}RifHdf5Reader.h ) @@ -86,6 +88,7 @@ ${CEE_CURRENT_LIST_DIR}RifCsvUserDataParser.cpp ${CEE_CURRENT_LIST_DIR}RifWellPathFormationReader.cpp ${CEE_CURRENT_LIST_DIR}RifWellPathFormationsImporter.cpp ${CEE_CURRENT_LIST_DIR}RifElementPropertyTableReader.cpp +${CEE_CURRENT_LIST_DIR}RifElementPropertyReader.cpp # HDF5 file reader is directly included in ResInsight main CmakeList.txt #${CEE_CURRENT_LIST_DIR}RifHdf5Reader.cpp diff --git a/ApplicationCode/FileInterface/RifElementPropertyReader.cpp b/ApplicationCode/FileInterface/RifElementPropertyReader.cpp new file mode 100644 index 0000000000..31954b93a5 --- /dev/null +++ b/ApplicationCode/FileInterface/RifElementPropertyReader.cpp @@ -0,0 +1,81 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RifElementPropertyReader.h" + +#include "cvfAssert.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifElementPropertyReader::RifElementPropertyReader() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifElementPropertyReader::~RifElementPropertyReader() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifElementPropertyReader::addFile(const std::string& fileName) +{ + RifElementPropertyMetadata metaData = RifElementPropertyTableReader::readMetadata(QString::fromStdString(fileName)); + for (QString field : metaData.dataColumns) + { + m_fields[field.toStdString()] = metaData; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map> RifElementPropertyReader::scalarElementFields() +{ + std::map> fields; + + for (std::map::iterator field = m_fields.begin(); field != m_fields.end(); field++) + { + fields[field->first]; + } + + return fields; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map> + RifElementPropertyReader::readAllElementPropertiesInFileContainingField(const std::string& fieldName) +{ + RifElementPropertyTable table; + RifElementPropertyTableReader::readData(&m_fields[fieldName], &table); + + CVF_ASSERT(m_fields[fieldName].dataColumns.size() == table.data.size()); + + std::map> fieldAndData; + + for (size_t i = 0; i < table.data.size(); i++) + { + fieldAndData[m_fields[fieldName].dataColumns[i].toStdString()].swap(table.data[i]); + } + + return fieldAndData; +} diff --git a/ApplicationCode/FileInterface/RifElementPropertyReader.h b/ApplicationCode/FileInterface/RifElementPropertyReader.h new file mode 100644 index 0000000000..3a84471f52 --- /dev/null +++ b/ApplicationCode/FileInterface/RifElementPropertyReader.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RifElementPropertyTableReader.h" + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfVector3.h" + +#include +#include +#include + +//================================================================================================== +// +// +//================================================================================================== +class RifElementPropertyReader : public cvf::Object +{ +public: + RifElementPropertyReader(); + virtual ~RifElementPropertyReader(); + + void addFile(const std::string& fileName); + + std::map> scalarElementFields(); + + std::map> readAllElementPropertiesInFileContainingField(const std::string& fieldName); + +private: + std::map m_fields; +}; diff --git a/ApplicationCode/FileInterface/RifElementPropertyTableReader.h b/ApplicationCode/FileInterface/RifElementPropertyTableReader.h index f6765212de..2de6289d7e 100644 --- a/ApplicationCode/FileInterface/RifElementPropertyTableReader.h +++ b/ApplicationCode/FileInterface/RifElementPropertyTableReader.h @@ -18,8 +18,6 @@ #pragma once -#include "RigWellPathFormations.h" - #include #include #include diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp index 45a5088a6f..1801ece7fa 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp @@ -19,6 +19,7 @@ #include "RigFemPartResultsCollection.h" +#include "RifElementPropertyReader.h" #include "RifGeoMechReaderInterface.h" #ifdef USE_ODB_API @@ -57,10 +58,12 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigFemPartResultsCollection::RigFemPartResultsCollection(RifGeoMechReaderInterface* readerInterface, const RigFemPartCollection * femPartCollection) +RigFemPartResultsCollection::RigFemPartResultsCollection(RifGeoMechReaderInterface* readerInterface, RifElementPropertyReader* elementPropertyReader, const RigFemPartCollection* femPartCollection) { CVF_ASSERT(readerInterface); + CVF_ASSERT(elementPropertyReader); m_readerInterface = readerInterface; + m_elementPropertyReader = elementPropertyReader; m_femParts = femPartCollection; m_femPartResults.resize(m_femParts->partCount()); @@ -118,6 +121,17 @@ RigFormationNames* RigFemPartResultsCollection::activeFormationNames() return m_activeFormationNamesData.p(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFemPartResultsCollection::addElementPropertyFiles(const std::vector& filenames) +{ + for (const QString filename : filenames) + { + m_elementPropertyReader->addFile(filename.toStdString()); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -133,7 +147,6 @@ void RigFemPartResultsCollection::setCalculationParameters(double cohesion, doub this->deleteResult(RigFemResultAddress(RIG_INTEGRATION_POINT, "SE", "DSM", RigFemResultAddress::ALL_TIME_LAPSES)); this->deleteResult(RigFemResultAddress(RIG_ELEMENT_NODAL, "SE", "FOS", RigFemResultAddress::ALL_TIME_LAPSES)); this->deleteResult(RigFemResultAddress(RIG_INTEGRATION_POINT, "SE", "FOS", RigFemResultAddress::ALL_TIME_LAPSES)); - } //-------------------------------------------------------------------------------------------------- @@ -155,6 +168,20 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::findOrLoadScalarResult(in frames = calculateDerivedResult(partIndex, resVarAddr); if (frames) return frames; + if (resVarAddr.resultPosType == RIG_ELEMENT) + { + std::map> elementProperties = m_elementPropertyReader->readAllElementPropertiesInFileContainingField(resVarAddr.fieldName); + + std::vector resultsForEachComponent; + for (auto elem : elementProperties) + { + RigFemScalarResultFrames* currentFrames = m_femPartResults[partIndex]->createScalarResult(resVarAddr); + currentFrames->frameData(0).swap(elem.second); + } + + return m_femPartResults[partIndex]->findScalarResult(resVarAddr); + } + // We need to read the data as bulk fields, and populate the correct scalar caches std::vector< RigFemResultAddress> resultAddressOfComponents = this->getResAddrToComponentsToRead(resVarAddr); @@ -384,7 +411,10 @@ std::map > RigFemPartResultsCollection::sc fieldCompNames["ST"].push_back("TPQV"); fieldCompNames["ST"].push_back("FAULTMOB"); fieldCompNames["ST"].push_back("PCRIT"); - + } + else if (resPos == RIG_ELEMENT) + { + fieldCompNames = m_elementPropertyReader->scalarElementFields(); } } diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h index cf6e82620e..1489413cfb 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h @@ -23,16 +23,21 @@ #include "cvfCollection.h" #include "cvfObject.h" + +#include + #include #include class RifGeoMechReaderInterface; +class RifElementPropertyReader; class RigFemScalarResultFrames; class RigFemPartResultsCollection; class RigFemPartResults; class RigStatisticsDataCache; class RigFemPartCollection; class RigFormationNames; + namespace caf { class ProgressInfo; @@ -41,11 +46,14 @@ namespace caf class RigFemPartResultsCollection: public cvf::Object { public: - RigFemPartResultsCollection(RifGeoMechReaderInterface* readerInterface, const RigFemPartCollection * femPartCollection); + RigFemPartResultsCollection(RifGeoMechReaderInterface* readerInterface, RifElementPropertyReader* elementPropertyReader, const RigFemPartCollection * femPartCollection); ~RigFemPartResultsCollection(); void setActiveFormationNames(RigFormationNames* activeFormationNames); RigFormationNames* activeFormationNames(); + + void addElementPropertyFiles(const std::vector& filename); + void setCalculationParameters(double cohesion, double frictionAngleRad); double parameterCohesion() const { return m_cohesion;} double parameterFrictionAngleRad() const { return m_frictionAngleRad; } @@ -104,6 +112,7 @@ private: cvf::Collection m_femPartResults; cvf::ref m_readerInterface; + cvf::ref m_elementPropertyReader; cvf::cref m_femParts; cvf::ref m_activeFormationNamesData; diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp index 6cc6ef6f70..c40b469430 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp @@ -19,20 +19,24 @@ #include +#include "RifElementPropertyReader.h" +#include "RifGeoMechReaderInterface.h" +#include "RigFemPartCollection.h" #include "RigFemPartResultsCollection.h" #include "RigGeoMechCaseData.h" -#include "RigFemPartCollection.h" -#include "RifGeoMechReaderInterface.h" #ifdef USE_ODB_API #include "RifOdbReader.h" #endif + #include "RigFemScalarResultFrames.h" #include "RigStatisticsDataCache.h" -#include -#include "cvfBoundingBox.h" + #include "cafProgressInfo.h" +#include "cvfBoundingBox.h" + #include +#include //-------------------------------------------------------------------------------------------------- /// @@ -93,6 +97,8 @@ bool RigGeoMechCaseData::openAndReadFemParts(std::string* errorMessage) m_readerInterface = new RifOdbReader; #endif + m_elementPropertyReader = new RifElementPropertyReader; + if (m_readerInterface.notNull() && m_readerInterface->openFile(m_geoMechCaseFileName, errorMessage)) { m_femParts = new RigFemPartCollection(); @@ -105,7 +111,7 @@ bool RigGeoMechCaseData::openAndReadFemParts(std::string* errorMessage) progress.setProgressDescription("Calculating element neighbors"); // Initialize results containers - m_femPartResultsColl = new RigFemPartResultsCollection(m_readerInterface.p(), m_femParts.p()); + m_femPartResultsColl = new RigFemPartResultsCollection(m_readerInterface.p(), m_elementPropertyReader.p(), m_femParts.p()); // Calculate derived Fem data for (int pIdx = 0; pIdx < m_femParts->partCount(); ++pIdx) diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h index 52f23a37ff..c76749e029 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h @@ -31,6 +31,7 @@ class RifGeoMechReaderInterface; class RigFemPartCollection; class RigFemScalarResultFrames; class RigFemPartResultsCollection; +class RifElementPropertyReader; class RigGeoMechCaseData: public cvf::Object { @@ -47,8 +48,9 @@ public: const RigFemPartResultsCollection* femPartResults() const; private: - std::string m_geoMechCaseFileName; - cvf::ref m_femParts; - cvf::ref m_femPartResultsColl; - cvf::ref m_readerInterface; + std::string m_geoMechCaseFileName; + cvf::ref m_femParts; + cvf::ref m_femPartResultsColl; + cvf::ref m_readerInterface; + cvf::ref m_elementPropertyReader; }; diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp index 890a4f7e24..3c327985d7 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp @@ -259,7 +259,9 @@ void RivFemPartPartMgr::updateCellResultColor(size_t timeStepIndex, RimGeoMechCe { vxToResultMapping = &(m_surfaceGenerator.quadVerticesToGlobalElmFaceNodeIdx()); } - + + if (!vxToResultMapping) return; + vxCount = static_cast(vxToResultMapping->size()); m_surfaceFacesTextureCoords->resize(vxCount); diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp index f63ee6faeb..5048af466c 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp @@ -317,6 +317,22 @@ void RimGeoMechCase::setFormationNames(RimFormationNames* formationNames) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechCase::addElementPropertyFiles(const std::vector& fileNames) +{ + for (const QString& fileName : fileNames) + { + m_elementPropertyFileNames.v().push_back(fileName); + } + this->updateConnectedEditors(); + if (m_geoMechCaseData.notNull()) + { + geoMechData()->femPartResults()->addElementPropertyFiles(fileNames); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCase.h b/ApplicationCode/ProjectDataModel/RimGeoMechCase.h index 030d09cf0a..278cd32bf5 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCase.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCase.h @@ -56,7 +56,7 @@ public: RimGeoMechView* createAndAddReservoirView(); virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath); - virtual std::vector views(); + virtual std::vector views(); virtual std::vector timeStepDates() const override; virtual QStringList timeStepStrings() const override; @@ -69,6 +69,8 @@ public: virtual void setFormationNames(RimFormationNames* formationNames) override; + void addElementPropertyFiles(const std::vector& filenames); + // Fields: caf::PdmChildArrayField geoMechViews;