diff --git a/ApplicationCode/Adm/RIBaseDefs.h b/ApplicationCode/Adm/RiaBaseDefs.h similarity index 100% rename from ApplicationCode/Adm/RIBaseDefs.h rename to ApplicationCode/Adm/RiaBaseDefs.h diff --git a/ApplicationCode/Adm/RIVersionInfo.h.cmake b/ApplicationCode/Adm/RiaVersionInfo.h.cmake similarity index 100% rename from ApplicationCode/Adm/RIVersionInfo.h.cmake rename to ApplicationCode/Adm/RiaVersionInfo.h.cmake diff --git a/ApplicationCode/Application/RIApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp similarity index 78% rename from ApplicationCode/Application/RIApplication.cpp rename to ApplicationCode/Application/RiaApplication.cpp index 4222dfd27e..95accf3985 100644 --- a/ApplicationCode/Application/RIApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cafLog.h" #include "cafEffectCache.h" @@ -26,20 +26,20 @@ #include "cvfStructGridGeometryGenerator.h" -#include "RIVersionInfo.h" -#include "RIBaseDefs.h" +#include "RiaVersionInfo.h" +#include "RiaBaseDefs.h" -#include "RIApplication.h" -#include "RIMainWindow.h" -#include "RIViewer.h" -#include "RIProcessMonitor.h" -#include "RIPreferences.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" +#include "RiuViewer.h" +#include "RiuProcessMonitor.h" +#include "RiaPreferences.h" -#include "RimResultReservoir.h" -#include "RimInputReservoir.h" +#include "RimResultCase.h" +#include "RimInputCase.h" #include "RimReservoirView.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "RigCell.h" #include "RigReservoirBuilderMock.h" @@ -55,15 +55,17 @@ #include "RimUiTreeModelPdm.h" #include "RiaImageCompareReporter.h" #include "RiaImageFileCompare.h" +#include "cafProgressInfo.h" +#include "RigGridManager.h" namespace caf { template<> -void AppEnum< RIApplication::RINavigationPolicy >::setUp() +void AppEnum< RiaApplication::RINavigationPolicy >::setUp() { - addItem(RIApplication::NAVIGATION_POLICY_CEETRON, "NAVIGATION_POLICY_CEETRON", "Ceetron"); - addItem(RIApplication::NAVIGATION_POLICY_CAD, "NAVIGATION_POLICY_CAD", "CAD"); - setDefault(RIApplication::NAVIGATION_POLICY_CAD); + addItem(RiaApplication::NAVIGATION_POLICY_CEETRON, "NAVIGATION_POLICY_CEETRON", "Ceetron"); + addItem(RiaApplication::NAVIGATION_POLICY_CAD, "NAVIGATION_POLICY_CAD", "CAD"); + setDefault(RiaApplication::NAVIGATION_POLICY_CAD); } } @@ -82,7 +84,7 @@ namespace RegTestNames //================================================================================================== /// -/// \class RIApplication +/// \class RiaApplication /// /// Application class /// @@ -92,7 +94,7 @@ namespace RegTestNames //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIApplication::RIApplication(int& argc, char** argv) +RiaApplication::RiaApplication(int& argc, char** argv) : QApplication(argc, argv) { // USed to get registry settings in the right place @@ -105,7 +107,7 @@ RIApplication::RIApplication(int& argc, char** argv) //cvf::Trace::enable(false); - m_preferences = new RIPreferences; + m_preferences = new RiaPreferences; readPreferences(); applyPreferences(); @@ -132,14 +134,14 @@ RIApplication::RIApplication(int& argc, char** argv) #ifdef WIN32 //m_startupDefaultDirectory += "/My Documents/"; #endif - + setDefaultFileDialogDirectory("MULTICASEIMPORT", "/"); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIApplication::~RIApplication() +RiaApplication::~RiaApplication() { delete m_preferences; } @@ -148,18 +150,18 @@ RIApplication::~RIApplication() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIApplication* RIApplication::instance() +RiaApplication* RiaApplication::instance() { - return static_castqApp; + return static_castqApp; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::setWindowCaptionFromAppState() +void RiaApplication::setWindowCaptionFromAppState() { - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); if (!mainWnd) return; // The stuff being done here should really be handled by Qt automatically as a result of @@ -185,7 +187,7 @@ void RIApplication::setWindowCaptionFromAppState() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::processNonGuiEvents() +void RiaApplication::processNonGuiEvents() { processEvents(QEventLoop::ExcludeUserInputEvents); } @@ -194,7 +196,7 @@ void RIApplication::processNonGuiEvents() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const char* RIApplication::getVersionStringApp(bool includeCrtInfo) +const char* RiaApplication::getVersionStringApp(bool includeCrtInfo) { // Use static buf so we can return ptr static char szBuf[1024]; @@ -220,15 +222,25 @@ const char* RIApplication::getVersionStringApp(bool includeCrtInfo) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::loadProject(const QString& projectFileName) +bool RiaApplication::loadProject(const QString& projectFileName) { + // First Close the current project + if (!closeProject(true)) return false; + // Open the project file and read the serialized data. + // Will initialize itself. + if (!QFile::exists(projectFileName)) return false; m_project->fileName = projectFileName; m_project->readFile(); - m_project->fileName = projectFileName; // Make sure we overwrite the old filename read from the project file + + // Propagate possible new location of project + + m_project->setProjectFileNameAndUpdateDependencies(projectFileName); + + // On error, delete everything, and bail out. if (m_project->projectFileVersionString().isEmpty()) { @@ -237,37 +249,84 @@ bool RIApplication::loadProject(const QString& projectFileName) QString tmp = QString("Unknown project file version detected in file \n%1\n\nCould not open project.").arg(projectFileName); QMessageBox::warning(NULL, "Error when opening project file", tmp); - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); mainWnd->setPdmRoot(NULL); // Delete all object possibly generated by readFile() delete m_project; m_project = new RimProject; + + onProjectOpenedOrClosed(); + + return true; } - else + + /////// + // Load the external data, and initialize stuff that needs specific ordering + + m_preferences->lastUsedProjectFileName = projectFileName; + writePreferences(); + + for (size_t cgIdx = 0; cgIdx < m_project->caseGroups.size(); ++cgIdx) { - m_preferences->lastUsedProjectFileName = projectFileName; - writePreferences(); + // Load the Main case of each IdenticalGridCaseGroup - size_t i; - for (i = 0; i < m_project->reservoirs().size(); ++i) + RimIdenticalGridCaseGroup* igcg = m_project->caseGroups[cgIdx]; + igcg->loadMainCaseAndActiveCellInfo(); + } + + // Now load the ReservoirViews for the cases + + std::vector casesToLoad; + + // Add all "native" cases in the project + for (size_t cIdx = 0; cIdx < m_project->reservoirs().size(); ++cIdx) + { + casesToLoad.push_back(m_project->reservoirs()[cIdx]); + } + + // Add all statistics cases as well + for (size_t cgIdx = 0; cgIdx < m_project->caseGroups().size(); ++cgIdx) + { + if (m_project->caseGroups[cgIdx]->statisticsCaseCollection()) { - RimReservoir* ri = m_project->reservoirs()[i]; - CVF_ASSERT(ri); - - size_t j; - for (j = 0; j < ri->reservoirViews().size(); j++) + caf::PdmPointersField & statCases = m_project->caseGroups[cgIdx]->statisticsCaseCollection()->reservoirs(); + for (size_t scIdx = 0; scIdx < statCases.size(); ++scIdx) { - RimReservoirView* riv = ri->reservoirViews()[j]; - CVF_ASSERT(riv); - - riv->loadDataAndUpdate(); + casesToLoad.push_back(statCases[scIdx]); } } } + caf::ProgressInfo caseProgress(casesToLoad.size() , "Reading Cases"); + + for (size_t cIdx = 0; cIdx < casesToLoad.size(); ++cIdx) + { + RimCase* ri = casesToLoad[cIdx]; + CVF_ASSERT(ri); + + caseProgress.setProgressDescription(ri->caseUserDescription()); + + caf::ProgressInfo viewProgress(ri->reservoirViews().size() , "Creating Views"); + + size_t j; + for (j = 0; j < ri->reservoirViews().size(); j++) + { + RimReservoirView* riv = ri->reservoirViews[j]; + CVF_ASSERT(riv); + + viewProgress.setProgressDescription(riv->name()); + + riv->loadDataAndUpdate(); + + viewProgress.incrementProgress(); + } + + caseProgress.incrementProgress(); + } + onProjectOpenedOrClosed(); - + return true; } @@ -275,7 +334,7 @@ bool RIApplication::loadProject(const QString& projectFileName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::loadLastUsedProject() +bool RiaApplication::loadLastUsedProject() { return loadProject(m_preferences->lastUsedProjectFileName); } @@ -284,7 +343,7 @@ bool RIApplication::loadLastUsedProject() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::saveProject() +bool RiaApplication::saveProject() { CVF_ASSERT(m_project.notNull()); @@ -302,11 +361,11 @@ bool RIApplication::saveProject() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::saveProjectPromptForFileName() +bool RiaApplication::saveProjectPromptForFileName() { //if (m_project.isNull()) return true; - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString startPath; if (!m_project->fileName().isEmpty()) @@ -341,7 +400,7 @@ bool RIApplication::saveProjectPromptForFileName() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::saveProjectAs(const QString& fileName) +bool RiaApplication::saveProjectAs(const QString& fileName) { m_project->fileName = fileName; m_project->writeFile(); @@ -356,9 +415,9 @@ bool RIApplication::saveProjectAs(const QString& fileName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::closeProject(bool askToSaveIfDirty) +bool RiaApplication::closeProject(bool askToSaveIfDirty) { - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); terminateProcess(); @@ -396,9 +455,9 @@ bool RIApplication::closeProject(bool askToSaveIfDirty) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::onProjectOpenedOrClosed() +void RiaApplication::onProjectOpenedOrClosed() { - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); if (!mainWnd) return; mainWnd->initializeGuiNewProjectLoaded(); @@ -411,7 +470,7 @@ void RIApplication::onProjectOpenedOrClosed() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RIApplication::currentProjectFileName() const +QString RiaApplication::currentProjectFileName() const { return m_project->fileName(); } @@ -420,7 +479,7 @@ QString RIApplication::currentProjectFileName() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::openEclipseCaseFromFile(const QString& fileName) +bool RiaApplication::openEclipseCaseFromFile(const QString& fileName) { if (!QFile::exists(fileName)) return false; @@ -434,27 +493,19 @@ bool RIApplication::openEclipseCaseFromFile(const QString& fileName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::openEclipseCase(const QString& caseName, const QString& caseFileName) +bool RiaApplication::openEclipseCase(const QString& caseName, const QString& caseFileName) { - QFileInfo gridFileName(caseFileName); - QString casePath = gridFileName.absolutePath(); - - RimResultReservoir* rimResultReservoir = new RimResultReservoir(); - rimResultReservoir->caseName = caseName; - rimResultReservoir->caseFileName = caseFileName; - rimResultReservoir->caseDirectory = casePath; + RimResultCase* rimResultReservoir = new RimResultCase(); + rimResultReservoir->setCaseInfo(caseName, caseFileName); m_project->reservoirs.push_back(rimResultReservoir); RimReservoirView* riv = rimResultReservoir->createAndAddReservoirView(); - if (m_preferences->autocomputeSOIL) - { - // Select SOIL as default result variable - riv->cellResult()->resultType = RimDefines::DYNAMIC_NATIVE; - riv->cellResult()->resultVariable = "SOIL"; - riv->animationMode = true; - } + // Select SOIL as default result variable + riv->cellResult()->resultType = RimDefines::DYNAMIC_NATIVE; + riv->cellResult()->resultVariable = "SOIL"; + riv->animationMode = true; riv->loadDataAndUpdate(); @@ -472,10 +523,10 @@ bool RIApplication::openEclipseCase(const QString& caseName, const QString& case //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::openInputEclipseCase(const QString& caseName, const QStringList& caseFileNames) +bool RiaApplication::openInputEclipseCase(const QString& caseName, const QStringList& caseFileNames) { - RimInputReservoir* rimInputReservoir = new RimInputReservoir(); - rimInputReservoir->caseName = caseName; + RimInputCase* rimInputReservoir = new RimInputCase(); + rimInputReservoir->caseUserDescription = caseName; rimInputReservoir->openDataFileSet(caseFileNames); m_project->reservoirs.push_back(rimInputReservoir); @@ -502,7 +553,7 @@ bool RIApplication::openInputEclipseCase(const QString& caseName, const QStringL //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::createMockModel() +void RiaApplication::createMockModel() { openEclipseCase("Result Mock Debug Model Simple", "Result Mock Debug Model Simple"); } @@ -510,7 +561,7 @@ void RIApplication::createMockModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::createResultsMockModel() +void RiaApplication::createResultsMockModel() { openEclipseCase("Result Mock Debug Model With Results", "Result Mock Debug Model With Results"); } @@ -519,7 +570,7 @@ void RIApplication::createResultsMockModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::createLargeResultsMockModel() +void RiaApplication::createLargeResultsMockModel() { openEclipseCase("Result Mock Debug Model Large With Results", "Result Mock Debug Model Large With Results"); } @@ -527,7 +578,7 @@ void RIApplication::createLargeResultsMockModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::createInputMockModel() +void RiaApplication::createInputMockModel() { openInputEclipseCase("Input Mock Debug Model Simple", QStringList("Input Mock Debug Model Simple")); } @@ -535,7 +586,7 @@ void RIApplication::createInputMockModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const RimReservoirView* RIApplication::activeReservoirView() const +const RimReservoirView* RiaApplication::activeReservoirView() const { return m_activeReservoirView; } @@ -543,7 +594,7 @@ const RimReservoirView* RIApplication::activeReservoirView() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimReservoirView* RIApplication::activeReservoirView() +RimReservoirView* RiaApplication::activeReservoirView() { return m_activeReservoirView; } @@ -551,7 +602,7 @@ RimReservoirView* RIApplication::activeReservoirView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::setActiveReservoirView(RimReservoirView* rv) +void RiaApplication::setActiveReservoirView(RimReservoirView* rv) { m_activeReservoirView = rv; } @@ -559,7 +610,7 @@ void RIApplication::setActiveReservoirView(RimReservoirView* rv) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::setUseShaders(bool enable) +void RiaApplication::setUseShaders(bool enable) { m_preferences->useShaders = enable; writePreferences(); @@ -568,7 +619,7 @@ void RIApplication::setUseShaders(bool enable) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::useShaders() const +bool RiaApplication::useShaders() const { if (!m_preferences->useShaders) return false; @@ -582,7 +633,7 @@ bool RIApplication::useShaders() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIApplication::RINavigationPolicy RIApplication::navigationPolicy() const +RiaApplication::RINavigationPolicy RiaApplication::navigationPolicy() const { return m_preferences->navigationPolicy(); } @@ -591,7 +642,7 @@ RIApplication::RINavigationPolicy RIApplication::navigationPolicy() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::setShowPerformanceInfo(bool enable) +void RiaApplication::setShowPerformanceInfo(bool enable) { m_preferences->showHud = enable; writePreferences(); @@ -601,7 +652,7 @@ void RIApplication::setShowPerformanceInfo(bool enable) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::showPerformanceInfo() const +bool RiaApplication::showPerformanceInfo() const { return m_preferences->showHud; } @@ -610,7 +661,7 @@ bool RIApplication::showPerformanceInfo() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::parseArguments() +bool RiaApplication::parseArguments() { QStringList arguments = QCoreApplication::arguments(); @@ -765,7 +816,7 @@ bool RIApplication::parseArguments() if (isRunRegressionTest) { - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); if (mainWnd) { mainWnd->hideAllDockWindows(); @@ -830,7 +881,7 @@ bool RIApplication::parseArguments() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RIApplication::scriptDirectory() const +QString RiaApplication::scriptDirectory() const { return m_preferences->scriptDirectory(); } @@ -838,7 +889,7 @@ QString RIApplication::scriptDirectory() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RIApplication::scriptEditorPath() const +QString RiaApplication::scriptEditorPath() const { return m_preferences->scriptEditorExecutable(); } @@ -846,7 +897,7 @@ QString RIApplication::scriptEditorPath() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RIApplication::octavePath() const +QString RiaApplication::octavePath() const { return m_preferences->octaveExecutable(); } @@ -854,9 +905,9 @@ QString RIApplication::octavePath() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +void RiaApplication::slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) { - RIMainWindow::instance()->processMonitor()->stopMonitorWorkProcess(); + RiuMainWindow::instance()->processMonitor()->stopMonitorWorkProcess(); // Execute delete later so that other slots that are hooked up // get a chance to run before we delete the object @@ -888,14 +939,14 @@ void RIApplication::slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::launchProcess(const QString& program, const QStringList& arguments) +bool RiaApplication::launchProcess(const QString& program, const QStringList& arguments) { if (m_workerProcess == NULL) { m_workerProcess = new caf::UiProcess(this); connect(m_workerProcess, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(slotWorkerProcessFinished(int, QProcess::ExitStatus))); - RIMainWindow::instance()->processMonitor()->startMonitorWorkProcess(m_workerProcess); + RiuMainWindow::instance()->processMonitor()->startMonitorWorkProcess(m_workerProcess); m_workerProcess->start(program, arguments); if (!m_workerProcess->waitForStarted(1000)) @@ -903,9 +954,9 @@ bool RIApplication::launchProcess(const QString& program, const QStringList& arg m_workerProcess->close(); m_workerProcess = NULL; - RIMainWindow::instance()->processMonitor()->stopMonitorWorkProcess(); + RiuMainWindow::instance()->processMonitor()->stopMonitorWorkProcess(); - QMessageBox::warning(RIMainWindow::instance(), "Script execution", "Failed to start script executable located at\n" + program); + QMessageBox::warning(RiuMainWindow::instance(), "Script execution", "Failed to start script executable located at\n" + program); return false; } @@ -922,7 +973,7 @@ bool RIApplication::launchProcess(const QString& program, const QStringList& arg //-------------------------------------------------------------------------------------------------- /// Read fields of a Pdm object using QSettings //-------------------------------------------------------------------------------------------------- -void RIApplication::readPreferences() +void RiaApplication::readPreferences() { QSettings settings; std::vector fields; @@ -944,7 +995,7 @@ void RIApplication::readPreferences() //-------------------------------------------------------------------------------------------------- /// Write fields of a Pdm object using QSettings //-------------------------------------------------------------------------------------------------- -void RIApplication::writePreferences() +void RiaApplication::writePreferences() { QSettings settings; @@ -963,7 +1014,7 @@ void RIApplication::writePreferences() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIPreferences* RIApplication::preferences() +RiaPreferences* RiaApplication::preferences() { return m_preferences; } @@ -971,7 +1022,7 @@ RIPreferences* RIApplication::preferences() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::applyPreferences() +void RiaApplication::applyPreferences() { if (m_activeReservoirView && m_activeReservoirView->viewer()) { @@ -999,7 +1050,7 @@ void RIApplication::applyPreferences() if (this->project()) { this->project()->setUserScriptPath(m_preferences->scriptDirectory()); - RimUiTreeModelPdm* treeModel = RIMainWindow::instance()->uiPdmModel(); + RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); if (treeModel) treeModel->rebuildUiSubTree(this->project()->scriptCollection()); } @@ -1008,7 +1059,7 @@ void RIApplication::applyPreferences() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::terminateProcess() +void RiaApplication::terminateProcess() { if (m_workerProcess) { @@ -1021,7 +1072,7 @@ void RIApplication::terminateProcess() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RIApplication::defaultFileDialogDirectory(const QString& dialogName) +QString RiaApplication::defaultFileDialogDirectory(const QString& dialogName) { QString defaultDirectory = m_startupDefaultDirectory; std::map::iterator it; @@ -1038,7 +1089,7 @@ QString RIApplication::defaultFileDialogDirectory(const QString& dialogName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::setDefaultFileDialogDirectory(const QString& dialogName, const QString& defaultDirectory) +void RiaApplication::setDefaultFileDialogDirectory(const QString& dialogName, const QString& defaultDirectory) { m_fileDialogDefaultDirectories[dialogName] = defaultDirectory; } @@ -1046,7 +1097,7 @@ void RIApplication::setDefaultFileDialogDirectory(const QString& dialogName, con //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::saveSnapshotPromtpForFilename() +void RiaApplication::saveSnapshotPromtpForFilename() { QString startPath; if (!m_project->fileName().isEmpty()) @@ -1076,7 +1127,7 @@ void RIApplication::saveSnapshotPromtpForFilename() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::saveSnapshotAs(const QString& fileName) +void RiaApplication::saveSnapshotAs(const QString& fileName) { if (m_activeReservoirView && m_activeReservoirView->viewer()) { @@ -1095,7 +1146,7 @@ void RIApplication::saveSnapshotAs(const QString& fileName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::copySnapshotToClipboard() +void RiaApplication::copySnapshotToClipboard() { if (m_activeReservoirView && m_activeReservoirView->viewer()) { @@ -1112,9 +1163,9 @@ void RIApplication::copySnapshotToClipboard() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::saveSnapshotForAllViews(const QString& snapshotFolderName) +void RiaApplication::saveSnapshotForAllViews(const QString& snapshotFolderName) { - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); if (!mainWnd) return; if (m_project.isNull()) return; @@ -1134,7 +1185,7 @@ void RIApplication::saveSnapshotForAllViews(const QString& snapshotFolderName) for (size_t i = 0; i < m_project->reservoirs().size(); ++i) { - RimReservoir* ri = m_project->reservoirs()[i]; + RimCase* ri = m_project->reservoirs()[i]; if (!ri) continue; for (size_t j = 0; j < ri->reservoirViews().size(); j++) @@ -1145,13 +1196,13 @@ void RIApplication::saveSnapshotForAllViews(const QString& snapshotFolderName) { setActiveReservoirView(riv); - RIViewer* viewer = riv->viewer(); + RiuViewer* viewer = riv->viewer(); mainWnd->setActiveViewer(viewer); // Process all events to avoid a black image when grabbing frame buffer QCoreApplication::processEvents(); - QString fileName = ri->caseName() + "-" + riv->name(); + QString fileName = ri->caseUserDescription() + "-" + riv->name(); QString absoluteFileName = caf::Utils::constructFullFileName(snapshotPath, fileName, ".png"); saveSnapshotAs(absoluteFileName); @@ -1174,7 +1225,7 @@ void removeDirectoryWithContent(QDir dirToDelete ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::runRegressionTest(const QString& testRootPath) +void RiaApplication::runRegressionTest(const QString& testRootPath) { QString generatedFolderName = RegTestNames::generatedFolderName; QString diffFolderName = RegTestNames::diffFolderName; @@ -1227,6 +1278,7 @@ void RIApplication::runRegressionTest(const QString& testRootPath) imageCompareReporter.generateHTMLReport(testDir.filePath(RegTestNames::reportFileName).toStdString()); // Generate diff images + this->preferences()->resetToDefaults(); for (int dirIdx = 0; dirIdx < folderList.size(); ++dirIdx) { @@ -1253,6 +1305,8 @@ void RIApplication::runRegressionTest(const QString& testRootPath) qDebug() << "Error comparing :" << imgComparator.errorMessage() << "\n" << imgComparator.errorDetails(); } } + + closeProject(false); } } } @@ -1260,7 +1314,7 @@ void RIApplication::runRegressionTest(const QString& testRootPath) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::updateRegressionTest(const QString& testRootPath) +void RiaApplication::updateRegressionTest(const QString& testRootPath) { // Find all sub folders @@ -1291,3 +1345,80 @@ void RIApplication::updateRegressionTest(const QString& testRootPath) } } } + +//-------------------------------------------------------------------------------------------------- +/// Make sure changes in this functions is validated to RimIdenticalGridCaseGroup::initAfterRead() +//-------------------------------------------------------------------------------------------------- +bool RiaApplication::addEclipseCases(const QStringList& fileNames) +{ + if (fileNames.size() == 0) return true; + + // First file is read completely including grid. + // The main grid from the first case is reused directly in for the other cases. + // When reading active cell info, only the total cell count is tested for consistency + RimResultCase* mainResultCase = NULL; + std::vector< std::vector > mainCaseGridDimensions; + + { + QString firstFileName = fileNames[0]; + QFileInfo gridFileName(firstFileName); + + QString caseName = gridFileName.completeBaseName(); + + RimResultCase* rimResultReservoir = new RimResultCase(); + rimResultReservoir->setCaseInfo(caseName, firstFileName); + if (!rimResultReservoir->openEclipseGridFile()) + { + delete rimResultReservoir; + + return false; + } + + rimResultReservoir->readGridDimensions(mainCaseGridDimensions); + + m_project->reservoirs.push_back(rimResultReservoir); + m_project->moveEclipseCaseIntoCaseGroup(rimResultReservoir); + + mainResultCase = rimResultReservoir; + } + + caf::ProgressInfo info(fileNames.size(), "Reading Active Cell data"); + + for (int i = 1; i < fileNames.size(); i++) + { + QString caseFileName = fileNames[i]; + QFileInfo gridFileName(caseFileName); + + QString caseName = gridFileName.completeBaseName(); + + RimResultCase* rimResultReservoir = new RimResultCase(); + rimResultReservoir->setCaseInfo(caseName, caseFileName); + + std::vector< std::vector > caseGridDimensions; + rimResultReservoir->readGridDimensions(caseGridDimensions); + + bool identicalGrid = RigGridManager::isGridDimensionsEqual(mainCaseGridDimensions, caseGridDimensions); + if (identicalGrid) + { + if (rimResultReservoir->openAndReadActiveCellData(mainResultCase->reservoirData())) + { + m_project->reservoirs.push_back(rimResultReservoir); + m_project->moveEclipseCaseIntoCaseGroup(rimResultReservoir); + } + else + { + delete rimResultReservoir; + } + } + else + { + delete rimResultReservoir; + } + + info.setProgress(i); + } + + onProjectOpenedOrClosed(); + + return true; +} diff --git a/ApplicationCode/Application/RIApplication.h b/ApplicationCode/Application/RiaApplication.h similarity index 92% rename from ApplicationCode/Application/RIApplication.h rename to ApplicationCode/Application/RiaApplication.h index f8f7d65eea..00b984a186 100644 --- a/ApplicationCode/Application/RIApplication.h +++ b/ApplicationCode/Application/RiaApplication.h @@ -30,11 +30,11 @@ #include "RimProject.h" class RIProcess; -class RigReservoir; -class RimReservoir; +class RigCaseData; +class RimCase; class Drawable; class RiaSocketServer; -class RIPreferences; +class RiaPreferences; namespace caf { @@ -46,7 +46,7 @@ namespace caf // // //================================================================================================== -class RIApplication : public QApplication +class RiaApplication : public QApplication { Q_OBJECT @@ -58,9 +58,9 @@ public: }; public: - RIApplication(int& argc, char** argv); - ~RIApplication(); - static RIApplication* instance(); + RiaApplication(int& argc, char** argv); + ~RiaApplication(); + static RiaApplication* instance(); bool parseArguments(); @@ -80,6 +80,7 @@ public: bool openEclipseCaseFromFile(const QString& fileName); bool openEclipseCase(const QString& caseName, const QString& caseFileName); + bool addEclipseCases(const QStringList& fileNames); bool openInputEclipseCase(const QString& caseName, const QStringList& caseFileNames); bool loadLastUsedProject(); @@ -115,7 +116,7 @@ public: bool launchProcess(const QString& program, const QStringList& arguments); void terminateProcess(); - RIPreferences* preferences(); + RiaPreferences* preferences(); void readPreferences(); void writePreferences(); void applyPreferences(); @@ -138,7 +139,7 @@ private: caf::UiProcess* m_workerProcess; - RIPreferences* m_preferences; + RiaPreferences* m_preferences; std::map m_fileDialogDefaultDirectories; QString m_startupDefaultDirectory; diff --git a/ApplicationCode/Application/RIPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp similarity index 74% rename from ApplicationCode/Application/RIPreferences.cpp rename to ApplicationCode/Application/RiaPreferences.cpp index 57aeee9a06..37014083a6 100644 --- a/ApplicationCode/Application/RIPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -16,17 +16,17 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RIPreferences.h" +#include "RiaStdInclude.h" +#include "RiaPreferences.h" #include "cafPdmUiFilePathEditor.h" -CAF_PDM_SOURCE_INIT(RIPreferences, "RIPreferences"); +CAF_PDM_SOURCE_INIT(RiaPreferences, "RiaPreferences"); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIPreferences::RIPreferences(void) +RiaPreferences::RiaPreferences(void) { - CAF_PDM_InitField(&navigationPolicy, "navigationPolicy", caf::AppEnum(RIApplication::NAVIGATION_POLICY_CAD), "Navigation mode", "", "", ""); + CAF_PDM_InitField(&navigationPolicy, "navigationPolicy", caf::AppEnum(RiaApplication::NAVIGATION_POLICY_CAD), "Navigation mode", "", "", ""); CAF_PDM_InitFieldNoDefault(&scriptDirectory, "scriptDirectory", "Shared Script Folder", "", "", ""); scriptDirectory.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); @@ -38,6 +38,9 @@ RIPreferences::RIPreferences(void) octaveExecutable.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); CAF_PDM_InitField(&defaultGridLines, "defaultGridLines", true, "Gridlines", "", "", ""); + CAF_PDM_InitField(&defaultGridLineColors, "defaultGridLineColors", cvf::Color3f(0.92f, 0.92f, 0.92f), "Mesh color", "", "", ""); + CAF_PDM_InitField(&defaultFaultGridLineColors, "defaultFaultGridLineColors", cvf::Color3f(0.08f, 0.08f, 0.08f), "Mesh color along faults", "", "", ""); + CAF_PDM_InitField(&defaultScaleFactorZ, "defaultScaleFactorZ", 5, "Z scale factor", "", "", ""); CAF_PDM_InitField(&useShaders, "useShaders", true, "Use Shaders", "", "", ""); @@ -53,7 +56,7 @@ RIPreferences::RIPreferences(void) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIPreferences::~RIPreferences(void) +RiaPreferences::~RiaPreferences(void) { } @@ -61,7 +64,7 @@ RIPreferences::~RIPreferences(void) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) +void RiaPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) { if (field == &scriptDirectory) { @@ -76,7 +79,7 @@ void RIPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QStr //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) const +void RiaPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { uiOrdering.add(&navigationPolicy); @@ -88,9 +91,26 @@ void RIPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& u caf::PdmUiGroup* defaultSettingsGroup = uiOrdering.addNewGroup("Default settings"); defaultSettingsGroup->add(&defaultScaleFactorZ); defaultSettingsGroup->add(&defaultGridLines); + defaultSettingsGroup->add(&defaultGridLineColors); + defaultSettingsGroup->add(&defaultFaultGridLineColors); + caf::PdmUiGroup* autoComputeGroup = uiOrdering.addNewGroup("Compute when loading new case"); autoComputeGroup->add(&autocomputeSOIL); autoComputeGroup->add(&autocomputeDepthRelatedProperties); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaPreferences::resetToDefaults() +{ + std::vector fields; + this->fields(fields); + + for (size_t i = 0; i < fields.size(); ++i) + { + fields[i]->resetToDefaultValue(); + } +} + diff --git a/ApplicationCode/Application/RIPreferences.h b/ApplicationCode/Application/RiaPreferences.h similarity index 80% rename from ApplicationCode/Application/RIPreferences.h rename to ApplicationCode/Application/RiaPreferences.h index a35ba41997..50cc1b3e09 100644 --- a/ApplicationCode/Application/RIPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -19,18 +19,20 @@ #pragma once #include "cafPdmObject.h" -#include "RIApplication.h" +#include "RiaApplication.h" -class RIPreferences : public caf::PdmObject +class RiaPreferences : public caf::PdmObject { CAF_PDM_HEADER_INIT; public: - RIPreferences(void); - virtual ~RIPreferences(void); + RiaPreferences(void); + virtual ~RiaPreferences(void); + + void resetToDefaults(); public: // Pdm Fields - caf::PdmField > navigationPolicy; + caf::PdmField > navigationPolicy; caf::PdmField scriptDirectory; caf::PdmField scriptEditorExecutable; @@ -38,6 +40,8 @@ public: // Pdm Fields caf::PdmField defaultScaleFactorZ; caf::PdmField defaultGridLines; + caf::PdmField defaultGridLineColors; + caf::PdmField defaultFaultGridLineColors; caf::PdmField useShaders; caf::PdmField showHud; @@ -51,5 +55,5 @@ public: // Pdm Fields protected: virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) const; + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) ; }; diff --git a/ApplicationCode/CMakeLists.txt b/ApplicationCode/CMakeLists.txt index 7995ceb2e2..4a854557d5 100644 --- a/ApplicationCode/CMakeLists.txt +++ b/ApplicationCode/CMakeLists.txt @@ -4,8 +4,8 @@ project (ApplicationCode) # NB: The generated file is written to Cmake binary folder to avoid source tree pollution # This folder is added to include_directories -CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/ApplicationCode/Adm/RIVersionInfo.h.cmake - ${CMAKE_BINARY_DIR}/Generated/RIVersionInfo.h +CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/ApplicationCode/Adm/RiaVersionInfo.h.cmake + ${CMAKE_BINARY_DIR}/Generated/RiaVersionInfo.h ) @@ -20,20 +20,21 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel ${CMAKE_CURRENT_SOURCE_DIR}/ReservoirDataModel ${CMAKE_BINARY_DIR}/Generated + ${CMAKE_CURRENT_BINARY_DIR} ) -# Use all cpp and h files in the subdirectories +# Use all h files in the subdirectories to make them available in the project file( GLOB_RECURSE HEADER_FILES *.h ) list( APPEND CPP_SOURCES - RIMain.cpp - RIStdInclude.cpp + RiaMain.cpp + RiaStdInclude.cpp ) list( APPEND CPP_SOURCES - Application/RIApplication.cpp - Application/RIPreferences.cpp + Application/RiaApplication.cpp + Application/RiaPreferences.cpp Application/RiaImageFileCompare.cpp Application/RiaImageCompareReporter.cpp ) @@ -49,22 +50,12 @@ list( APPEND CPP_SOURCES ModelVisualization/RivWellHeadPartMgr.cpp ) -list( APPEND CPP_SOURCES - FileInterface/RifEclipseInputFileTools.cpp - FileInterface/RifEclipseOutputFileTools.cpp - FileInterface/RifEclipseRestartFilesetAccess.cpp - FileInterface/RifEclipseRestartDataAccess.cpp - FileInterface/RifEclipseUnifiedRestartFileAccess.cpp - FileInterface/RifReaderEclipseInput.cpp - FileInterface/RifReaderEclipseOutput.cpp - FileInterface/RifReaderMockModel.cpp -) - list( APPEND CPP_SOURCES SocketInterface/RiaSocketServer.cpp ) list( APPEND CPP_SOURCES + ProjectDataModel/RimCaseCollection.cpp ProjectDataModel/RimCellFilter.cpp ProjectDataModel/RimCellPropertyFilter.cpp ProjectDataModel/RimCellPropertyFilterCollection.cpp @@ -73,11 +64,12 @@ list( APPEND CPP_SOURCES ProjectDataModel/RimDefines.cpp ProjectDataModel/RimLegendConfig.cpp ProjectDataModel/RimProject.cpp - ProjectDataModel/RimReservoir.cpp + ProjectDataModel/RimCase.cpp + ProjectDataModel/RimIdenticalGridCaseGroup.cpp ProjectDataModel/RimInputProperty.cpp ProjectDataModel/RimInputPropertyCollection.cpp - ProjectDataModel/RimInputReservoir.cpp - ProjectDataModel/RimResultReservoir.cpp + ProjectDataModel/RimInputCase.cpp + ProjectDataModel/RimResultCase.cpp ProjectDataModel/RimReservoirView.cpp ProjectDataModel/RimResultDefinition.cpp ProjectDataModel/RimResultSlot.cpp @@ -85,55 +77,62 @@ list( APPEND CPP_SOURCES ProjectDataModel/RimWell.cpp ProjectDataModel/RimWellCollection.cpp ProjectDataModel/RimScriptCollection.cpp + ProjectDataModel/RimStatisticsCase.cpp + ProjectDataModel/RimStatisticsCaseCollection.cpp ProjectDataModel/RimCalcScript.cpp ProjectDataModel/RimExportInputPropertySettings.cpp ProjectDataModel/RimBinaryExportSettings.cpp ProjectDataModel/Rim3dOverlayInfoConfig.cpp ProjectDataModel/RimUiTreeModelPdm.cpp ProjectDataModel/RimUiTreeView.cpp + ProjectDataModel/RimReservoirCellResultsCacher.cpp + ProjectDataModel/RimStatisticsCaseEvaluator.cpp +) + +# Populate the filenames into variable lists +include ("ReservoirDataModel/CMakeLists_files.cmake") +include ("FileInterface/CMakeLists_files.cmake") +list( APPEND CPP_SOURCES + ${CODE_SOURCE_FILES} ) list( APPEND CPP_SOURCES - ReservoirDataModel/RigCell.cpp - ReservoirDataModel/RigGridBase.cpp - ReservoirDataModel/RigReservoirCellResults.cpp - ReservoirDataModel/RigLocalGrid.cpp - ReservoirDataModel/RigMainGrid.cpp - ReservoirDataModel/RigReservoir.cpp - ReservoirDataModel/RigReservoirBuilderMock.cpp - ReservoirDataModel/RigWellResults.cpp - ReservoirDataModel/RigGridScalarDataAccess.cpp -) - -list( APPEND CPP_SOURCES - UserInterface/RICursors.cpp - UserInterface/RIMainWindow.cpp - UserInterface/RIPreferencesDialog.cpp - UserInterface/RIResultInfoPanel.cpp - UserInterface/RIViewer.cpp + UserInterface/RiuCursors.cpp + UserInterface/RiuMainWindow.cpp + UserInterface/RiuPreferencesDialog.cpp + UserInterface/RiuResultInfoPanel.cpp + UserInterface/RiuViewer.cpp UserInterface/RiuSimpleHistogramWidget.cpp - - UserInterface/RIProcessMonitor.cpp + UserInterface/RiuMultiCaseImportDialog.cpp + UserInterface/RiuProcessMonitor.cpp ) # Define files for MOC-ing set ( QT_MOC_HEADERS - Application/RIApplication.h + Application/RiaApplication.h ProjectDataModel/RimUiTreeModelPdm.h ProjectDataModel/RimUiTreeView.h - UserInterface/RIMainWindow.h - UserInterface/RIPreferencesDialog.h - UserInterface/RIResultInfoPanel.h - UserInterface/RIViewer.h - UserInterface/RIProcessMonitor.h + UserInterface/RiuMainWindow.h + UserInterface/RiuPreferencesDialog.h + UserInterface/RiuResultInfoPanel.h + UserInterface/RiuViewer.h + UserInterface/RiuProcessMonitor.h SocketInterface/RiaSocketServer.h + UserInterface/RiuMultiCaseImportDialog.h ) qt4_wrap_cpp( MOC_FILES_CPP ${QT_MOC_HEADERS} ) +# Define files for the uic compiler +set ( QT_UI_FILES + UserInterface/RiuMultiCaseImportDialog.ui +) + +qt4_wrap_ui( FORM_FILES_CPP ${QT_UI_FILES} ) + # NOTE! Resources in subfolders must append to QRC_FILES using the following statement # set( QRC_FILES # ${QRC_FILES} @@ -149,25 +148,30 @@ set( QRC_FILES # Runs RCC on specified files qt4_add_resources( QRC_FILES_CPP ${QRC_FILES} ) +# Adding resource (RC) files for Windows +if ( MSVC ) + set( WIN_RESOURCE Resources/ResInsight.rc ) +endif() ############################################################################# # creating PCH's for MSVC and GCC on Linux ############################################################################# set( RAW_SOURCES ${CPP_SOURCES} ) -list( REMOVE_ITEM RAW_SOURCES RIStdInclude.cpp) -list( REMOVE_ITEM RAW_SOURCES ReservoirDataModel/RigReaderInterfaceECL.cpp) -list( REMOVE_ITEM RAW_SOURCES ReservoirDataModel/RigGridScalarDataAccess.cpp) -list( REMOVE_ITEM RAW_SOURCES ModelVisualization/RivCellEdgeEffectGenerator.cpp) -list( REMOVE_ITEM RAW_SOURCES ModelVisualization/RivPipeGeometryGenerator.cpp) -list( REMOVE_ITEM RAW_SOURCES ModelVisualization/RivWellPipesPartMgr.cpp) -list( REMOVE_ITEM RAW_SOURCES ModelVisualization/RivWellHeadPartMgr.cpp) -list( REMOVE_ITEM RAW_SOURCES Application/RiaImageFileCompare.cpp) -list( REMOVE_ITEM RAW_SOURCES Application/RiaImageCompareReporter.cpp) +list( REMOVE_ITEM RAW_SOURCES + RiaStdInclude.cpp + ${CODE_SOURCE_FILES} -list( REMOVE_ITEM RAW_SOURCES + ModelVisualization/RivCellEdgeEffectGenerator.cpp + ModelVisualization/RivPipeGeometryGenerator.cpp + ModelVisualization/RivWellPipesPartMgr.cpp + ModelVisualization/RivWellHeadPartMgr.cpp + + Application/RiaImageFileCompare.cpp + Application/RiaImageCompareReporter.cpp + FileInterface/RifEclipseInputFileTools.cpp FileInterface/RifEclipseOutputFileTools.cpp FileInterface/RifEclipseRestartFilesetAccess.cpp @@ -175,8 +179,9 @@ list( REMOVE_ITEM RAW_SOURCES FileInterface/RifEclipseUnifiedRestartFileAccess.cpp FileInterface/RifReaderEclipseInput.cpp FileInterface/RifReaderEclipseOutput.cpp - UserInterface/RiuSimpleHistogramWidget.cpp + UserInterface/RiuSimpleHistogramWidget.cpp + UserInterface/RiuMultiCaseImportDialog.cpp ) include( CustomPCH.cmake ) @@ -189,7 +194,7 @@ set( ALL_INCLUDES ${QT_INCLUDES} ) -set( PCH_NAME RIStdInclude ) +set( PCH_NAME RiaStdInclude ) set( GCC_PCH_TARGET gccPCH ) set( PCH_COMPILER_DEFINE EMPTY ) IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -205,7 +210,9 @@ precompiled_header( RAW_SOURCES ALL_INCLUDES ${GCC_PCH_TARGET} ${PCH_NAME} ${PCH add_executable(ResInsight ${CPP_SOURCES} ${MOC_FILES_CPP} + ${FORM_FILES_CPP} ${QRC_FILES_CPP} + ${WIN_RESOURCE} ${HEADER_FILES} ) diff --git a/ApplicationCode/FileInterface/CMakeLists_files.cmake b/ApplicationCode/FileInterface/CMakeLists_files.cmake new file mode 100644 index 0000000000..7e80dd49d8 --- /dev/null +++ b/ApplicationCode/FileInterface/CMakeLists_files.cmake @@ -0,0 +1,31 @@ + +# Use this workaround until we're on 2.8.3 on all platforms and can use CMAKE_CURRENT_LIST_DIR directly +if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") + set(CEE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}/) +endif() + + +list(APPEND CODE_HEADER_FILES +${CEE_CURRENT_LIST_DIR}RifEclipseInputFileTools.h +${CEE_CURRENT_LIST_DIR}RifEclipseOutputFileTools.h +${CEE_CURRENT_LIST_DIR}RifEclipseRestartDataAccess.h +${CEE_CURRENT_LIST_DIR}RifEclipseRestartFilesetAccess.h +${CEE_CURRENT_LIST_DIR}RifEclipseUnifiedRestartFileAccess.h +${CEE_CURRENT_LIST_DIR}RifReaderEclipseInput.h +${CEE_CURRENT_LIST_DIR}RifReaderEclipseOutput.h +${CEE_CURRENT_LIST_DIR}RifReaderInterface.h +${CEE_CURRENT_LIST_DIR}RifReaderMockModel.h +) + +list(APPEND CODE_SOURCE_FILES +${CEE_CURRENT_LIST_DIR}RifEclipseInputFileTools.cpp +${CEE_CURRENT_LIST_DIR}RifEclipseOutputFileTools.cpp +${CEE_CURRENT_LIST_DIR}RifEclipseRestartDataAccess.cpp +${CEE_CURRENT_LIST_DIR}RifEclipseRestartFilesetAccess.cpp +${CEE_CURRENT_LIST_DIR}RifEclipseUnifiedRestartFileAccess.cpp +${CEE_CURRENT_LIST_DIR}RifReaderEclipseInput.cpp +${CEE_CURRENT_LIST_DIR}RifReaderEclipseOutput.cpp +${CEE_CURRENT_LIST_DIR}RifReaderMockModel.cpp +) + + diff --git a/ApplicationCode/FileInterface/FileInterface_UnitTests/CMakeLists.txt b/ApplicationCode/FileInterface/FileInterface_UnitTests/CMakeLists.txt index 7ae8924546..e66fbc896c 100644 --- a/ApplicationCode/FileInterface/FileInterface_UnitTests/CMakeLists.txt +++ b/ApplicationCode/FileInterface/FileInterface_UnitTests/CMakeLists.txt @@ -18,39 +18,39 @@ include_directories( ${ResInsight_SOURCE_DIR}/cafProjectDataModel ${ResInsight_SOURCE_DIR}/CommonCode + + #Remove when RigStatistics is out + ${ResInsight_SOURCE_DIR}/ApplicationCode/ModelVisualization ) -set( FILEINTERFACE_CPP_SOURCES - ../RifEclipseInputFileTools.cpp - ../RifEclipseOutputFileTools.cpp - ../RifEclipseRestartFilesetAccess.cpp - ../RifEclipseRestartDataAccess.cpp - ../RifEclipseUnifiedRestartFileAccess.cpp - ../RifReaderEclipseOutput.cpp - ../RifReaderEclipseInput.cpp - ../RifReaderMockModel.cpp -) -set( RESERVOIRDATAMODEL_CPP_SOURCES - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigCell.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigGridBase.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigReservoir.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigReservoirCellResults.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigWellResults.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp +# Populate variables from read from CMakeLists_files.cmake +set (CODE_SOURCE_FILES ) +include ("${ResInsight_SOURCE_DIR}/ApplicationCode/FileInterface/CMakeLists_files.cmake") +set( CPP_SOURCES + ${CPP_SOURCES} + ${CODE_SOURCE_FILES} +) +source_group( "FileInterface" FILES ${CODE_SOURCE_FILES} ) + + +# Populate variables from read from CMakeLists_files.cmake +set (CODE_SOURCE_FILES ) +include ("${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake") +set( CPP_SOURCES + ${CPP_SOURCES} + ${CODE_SOURCE_FILES} +) +source_group( "ReservoirDataModel" FILES ${CODE_SOURCE_FILES} ) + + +set( CPP_SOURCES + ${CPP_SOURCES} + ${ResInsight_SOURCE_DIR}/cafUserInterface/cafProgressInfo.cpp ) -set( CPP_SOURCES - ${FILEINTERFACE_CPP_SOURCES} - ${RESERVOIRDATAMODEL_CPP_SOURCES} -) - -source_group( "FileInterface" FILES ${FILEINTERFACE_CPP_SOURCES} ) -source_group( "ReservoirDataModel" FILES ${RESERVOIRDATAMODEL_CPP_SOURCES} ) +source_group( "Headers" FILES ${CODE_HEADER_FILES} ) set( UNIT_TEST_CPP_SOURCES main.cpp @@ -58,7 +58,6 @@ set( UNIT_TEST_CPP_SOURCES Ert-Test.cpp ) - set( LINK_LIBRARIES CommonCode @@ -75,20 +74,22 @@ set( LINK_LIBRARIES ${QT_LIBRARIES} ) - - add_executable( ${ProjectName} + ${CODE_HEADER_FILES} + ${CPP_SOURCES} ${UNIT_TEST_CPP_SOURCES} ${ResInsight_SOURCE_DIR}/ThirdParty/gtest/gtest-all.cc + + ${ResInsight_SOURCE_DIR}/ApplicationCode/FileInterface/CMakeLists_files.cmake + ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake ) set( EXTERNAL_LINK_LIBRARIES ${ERT_LIBRARY_LIST} ) target_link_libraries( ${ProjectName} ${LINK_LIBRARIES} ${EXTERNAL_LINK_LIBRARIES}) - # Copy Dlls if (MSVC) @@ -101,21 +102,4 @@ if (MSVC) ${CMAKE_CURRENT_BINARY_DIR}/$) endforeach( qtlib ) - - # DLLs ERT depends on -# add_custom_command(TARGET ${ProjectName} POST_BUILD -# COMMAND ${CMAKE_COMMAND} -E copy_directory -# "${PROJECT_SOURCE_DIR}/../../../ThirdParty/Ert-windows/bin/" -# ${CMAKE_CURRENT_BINARY_DIR}/$) - - - # ERT DLLs - # set (ERT_MODULES ecl geometry util well) - # foreach (ert_module ${ERT_MODULES}) - # add_custom_command(TARGET ${ProjectName} POST_BUILD - # COMMAND ${CMAKE_COMMAND} -E copy_if_different - # "${CMAKE_CURRENT_SOURCE_DIR}/../../../ThirdParty/Ert-windows/${ert_module}/lib/lib${ert_module}.dll" - # ${CMAKE_CURRENT_BINARY_DIR}/$) - # endforeach() - endif(MSVC) diff --git a/ApplicationCode/FileInterface/FileInterface_UnitTests/Ert-Test.cpp b/ApplicationCode/FileInterface/FileInterface_UnitTests/Ert-Test.cpp index 7a2aef0cfd..4041d3884f 100644 --- a/ApplicationCode/FileInterface/FileInterface_UnitTests/Ert-Test.cpp +++ b/ApplicationCode/FileInterface/FileInterface_UnitTests/Ert-Test.cpp @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -37,7 +36,7 @@ #include "gtest/gtest.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "RifReaderEclipseInput.h" #if 0 diff --git a/ApplicationCode/FileInterface/FileInterface_UnitTests/RifReaderEclipseOutput-Test.cpp b/ApplicationCode/FileInterface/FileInterface_UnitTests/RifReaderEclipseOutput-Test.cpp index d61fdb185d..d1fbe43b49 100644 --- a/ApplicationCode/FileInterface/FileInterface_UnitTests/RifReaderEclipseOutput-Test.cpp +++ b/ApplicationCode/FileInterface/FileInterface_UnitTests/RifReaderEclipseOutput-Test.cpp @@ -18,15 +18,15 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "gtest/gtest.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "RifReaderEclipseOutput.h" #include "ecl_file.h" #include "RifEclipseOutputFileTools.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" @@ -68,7 +68,7 @@ TEST(RigReservoirTest, FileOutputToolsTest) void buildResultInfoString(RigReservoir* reservoir, RifReaderInterface::PorosityModelResultType porosityModel, RimDefines::ResultCatType resultType) { - RigReservoirCellResults* matrixResults = reservoir->mainGrid()->results(porosityModel); + RigCaseCellResultsData* matrixResults = reservoir->results(porosityModel); { QStringList resultNames = matrixResults->resultNames(resultType); @@ -247,7 +247,7 @@ TEST(RigReservoirTest, BasicTest) TEST(RigReservoirTest, WellTest) { cvf::ref readerInterfaceEcl = new RifReaderEclipseOutput; - cvf::ref reservoir = new RigReservoir; + cvf::ref reservoir = new RigCaseData; // Location of test dataset received from Håkon Høgstøl in July 2011 with 10k active cells #ifdef WIN32 diff --git a/ApplicationCode/FileInterface/FileInterface_UnitTests/main.cpp b/ApplicationCode/FileInterface/FileInterface_UnitTests/main.cpp index a28cfcc87f..03d89c0085 100644 --- a/ApplicationCode/FileInterface/FileInterface_UnitTests/main.cpp +++ b/ApplicationCode/FileInterface/FileInterface_UnitTests/main.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cvfBase.h" diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp index 11a7335234..0fcbadf854 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp @@ -18,9 +18,9 @@ #include "RifEclipseInputFileTools.h" #include "RifReaderEclipseOutput.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "cafProgressInfo.h" #include @@ -61,9 +61,9 @@ RifEclipseInputFileTools::~RifEclipseInputFileTools() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigReservoir* reservoir) +bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigCaseData* eclipseCase) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); qint64 coordPos = -1; qint64 zcornPos = -1; @@ -154,7 +154,7 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigReservoi progress.setProgress(6); - RifReaderEclipseOutput::transferGeometry(inputGrid, reservoir); + RifReaderEclipseOutput::transferGeometry(inputGrid, eclipseCase); progress.setProgress(7); progress.setProgressDescription("Cleaning up ..."); @@ -176,7 +176,7 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigReservoi //-------------------------------------------------------------------------------------------------- /// Read known properties from the input file //-------------------------------------------------------------------------------------------------- -std::map RifEclipseInputFileTools::readProperties(const QString &fileName, RigReservoir *reservoir) +std::map RifEclipseInputFileTools::readProperties(const QString &fileName, RigCaseData *reservoir) { CVF_ASSERT(reservoir); @@ -212,11 +212,11 @@ std::map RifEclipseInputFileTools::readProperties(const QStri ecl_kw_type* eclKeyWordData = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ECL_FLOAT_TYPE); if (eclKeyWordData) { - QString newResultName = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(fileKeywords[i].keyword); + QString newResultName = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(fileKeywords[i].keyword); - size_t resultIndex = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName); // Should really merge with inputProperty object information because we need to use PropertyName, and not keyword + size_t resultIndex = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false); // Should really merge with inputProperty object information because we need to use PropertyName, and not keyword - std::vector< std::vector >& newPropertyData = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); + std::vector< std::vector >& newPropertyData = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); 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()); @@ -282,9 +282,9 @@ std::vector< RifKeywordAndFilePos > RifEclipseInputFileTools::findKeywordsOnFile /// Reads the property data requested into the \a reservoir, overwriting any previous /// propeties with the same name. //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::readProperty(const QString& fileName, RigReservoir* reservoir, const QString& eclipseKeyWord, const QString& resultName) +bool RifEclipseInputFileTools::readProperty(const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, const QString& resultName) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); FILE* filePointer = util_fopen(fileName.toLatin1().data(), "r"); if (!filePointer) return false; @@ -294,13 +294,13 @@ bool RifEclipseInputFileTools::readProperty(const QString& fileName, RigReservoi if (eclKeyWordData) { QString newResultName = resultName; - size_t resultIndex = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName); + size_t resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName); if (resultIndex == cvf::UNDEFINED_SIZE_T) { - resultIndex = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName); + resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false); } - std::vector< std::vector >& newPropertyData = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); + std::vector< std::vector >& newPropertyData = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); newPropertyData.resize(1); newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL); ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data()); @@ -370,11 +370,11 @@ const std::vector& RifEclipseInputFileTools::knownPropertyKeywords() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::writePropertyToTextFile(const QString& fileName, RigReservoir* reservoir, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord) +bool RifEclipseInputFileTools::writePropertyToTextFile(const QString& fileName, RigCaseData* eclipseCase, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); - size_t resultIndex = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(resultName); + size_t resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(resultName); if (resultIndex == cvf::UNDEFINED_SIZE_T) { return false; @@ -386,7 +386,7 @@ bool RifEclipseInputFileTools::writePropertyToTextFile(const QString& fileName, return false; } - std::vector< std::vector >& resultData = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); + std::vector< std::vector >& resultData = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); if (resultData.size() == 0) { return false; @@ -402,11 +402,11 @@ bool RifEclipseInputFileTools::writePropertyToTextFile(const QString& fileName, /// Create and write a result vector with values for all cells. /// undefinedValue is used for cells with no result //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileName, RigReservoir* reservoir, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord, const double undefinedValue) +bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileName, RigCaseData* eclipseCase, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord, const double undefinedValue) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); - size_t resultIndex = reservoir->mainGrid()->results(porosityModel)->findScalarResultIndex(resultName); + size_t resultIndex = eclipseCase->results(porosityModel)->findScalarResultIndex(resultName); if (resultIndex == cvf::UNDEFINED_SIZE_T) { return false; @@ -418,7 +418,7 @@ bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileNa return false; } - cvf::ref dataAccessObject = reservoir->mainGrid()->dataAccessObject(porosityModel, timeStep, resultIndex); + cvf::ref dataAccessObject = eclipseCase->dataAccessObject(eclipseCase->mainGrid(), porosityModel, timeStep, resultIndex); if (dataAccessObject.isNull()) { return false; @@ -426,13 +426,13 @@ bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileNa std::vector resultData; size_t i, j, k; - for (k = 0; k < reservoir->mainGrid()->cellCountK(); k++) + for (k = 0; k < eclipseCase->mainGrid()->cellCountK(); k++) { - for (j = 0; j < reservoir->mainGrid()->cellCountJ(); j++) + for (j = 0; j < eclipseCase->mainGrid()->cellCountJ(); j++) { - for (i = 0; i < reservoir->mainGrid()->cellCountI(); i++) + for (i = 0; i < eclipseCase->mainGrid()->cellCountI(); i++) { - double resultValue = dataAccessObject->cellScalar(i, j, k); + double resultValue = dataAccessObject->cellScalar(eclipseCase->mainGrid()->cellIndexFromIJK(i, j, k)); if (resultValue == HUGE_VAL) { resultValue = undefinedValue; @@ -519,9 +519,9 @@ void RifEclipseInputFileTools::findGridKeywordPositions(const QString& filename, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::readPropertyAtFilePosition(const QString& fileName, RigReservoir* reservoir, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName) +bool RifEclipseInputFileTools::readPropertyAtFilePosition(const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); FILE* filePointer = util_fopen(fileName.toLatin1().data(), "r"); if (!filePointer) return false; @@ -532,13 +532,13 @@ bool RifEclipseInputFileTools::readPropertyAtFilePosition(const QString& fileNam if (eclKeyWordData) { QString newResultName = resultName; - size_t resultIndex = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName); + size_t resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName); if (resultIndex == cvf::UNDEFINED_SIZE_T) { - resultIndex = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName); + resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false); } - std::vector< std::vector >& newPropertyData = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); + std::vector< std::vector >& newPropertyData = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); newPropertyData.resize(1); newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL); ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data()); diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.h b/ApplicationCode/FileInterface/RifEclipseInputFileTools.h index 220454ee6d..7d0116a29b 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.h +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.h @@ -27,7 +27,7 @@ #include "RifReaderInterface.h" -class RigReservoir; +class RigCaseData; class QFile; @@ -52,19 +52,19 @@ public: RifEclipseInputFileTools(); virtual ~RifEclipseInputFileTools(); - static bool openGridFile(const QString& fileName, RigReservoir* reservoir); + static bool openGridFile(const QString& fileName, RigCaseData* eclipseCase); // Returns map of assigned resultName and Eclipse Keyword. - static std::map readProperties(const QString& fileName, RigReservoir* reservoir); - static bool readProperty (const QString& fileName, RigReservoir* reservoir, const QString& eclipseKeyWord, const QString& resultName ); - static bool readPropertyAtFilePosition (const QString& fileName, RigReservoir* reservoir, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName ); + static std::map readProperties(const QString& fileName, RigCaseData* eclipseCase); + static bool readProperty (const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, const QString& resultName ); + static bool readPropertyAtFilePosition (const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName ); static std::vector< RifKeywordAndFilePos > findKeywordsOnFile(const QString &fileName); static const std::vector& knownPropertyKeywords(); - static bool writePropertyToTextFile(const QString& fileName, RigReservoir* reservoir, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord); - static bool writeBinaryResultToTextFile(const QString& fileName, RigReservoir* reservoir, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord, const double undefinedValue); + static bool writePropertyToTextFile(const QString& fileName, RigCaseData* eclipseCase, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord); + static bool writeBinaryResultToTextFile(const QString& fileName, RigCaseData* eclipseCase, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord, const double undefinedValue); private: static void writeDataToTextFile(QFile* file, const QString& eclipseKeyWord, const std::vector& resultData); diff --git a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp index 2c77fd6355..416f7a6513 100644 --- a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp @@ -20,8 +20,8 @@ #include "util.h" #include "ecl_file.h" -#include "ecl_intehead.h" #include "ecl_kw_magic.h" +#include "ecl_grid.h" #include #include @@ -46,7 +46,7 @@ RifEclipseOutputFileTools::~RifEclipseOutputFileTools() //-------------------------------------------------------------------------------------------------- /// Get list of time step texts (dates) //-------------------------------------------------------------------------------------------------- -void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, QList* timeSteps, bool* detectedFractionOfDay ) +void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, std::vector* timeSteps, bool* detectedFractionOfDay ) { CVF_ASSERT(timeSteps); CVF_ASSERT(ecl_file); @@ -84,7 +84,7 @@ void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, QList timeStepsFound; + std::vector timeStepsFound; if (hasFractionOfDay) { @@ -102,15 +102,15 @@ void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, QList(dayFraction * 24.0 * 60.0 * 60.0); QTime time(0, 0); time = time.addSecs(seconds); QDate reportDate = simulationStart; - reportDate = reportDate.addDays(floorDayValue); + reportDate = reportDate.addDays(static_cast(floorDayValue)); QDateTime reportDateTime(reportDate, time); - if (timeStepsFound.indexOf(reportDateTime) < 0) + if (std::find(timeStepsFound.begin(), timeStepsFound.end(), reportDateTime) == timeStepsFound.end()) { timeStepsFound.push_back(reportDateTime); } @@ -132,7 +132,7 @@ void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, QList* values) +{ + ecl_kw_type* kwData = ecl_file_iget_named_kw(ecl_file, keyword.toAscii().data(), static_cast(fileKeywordOccurrence)); + if (kwData) + { + size_t numValues = ecl_kw_get_size(kwData); + + std::vector integerData; + integerData.resize(numValues); + + ecl_kw_get_memcpy_int_data(kwData, integerData.data()); + values->insert(values->end(), integerData.begin(), integerData.end()); + + return true; + } + + return false; +} + //-------------------------------------------------------------------------------------------------- /// Get first occurrence of file of given type in given list of filenames, as filename or NULL if not found //-------------------------------------------------------------------------------------------------- -QString RifEclipseOutputFileTools::fileNameByType(const QStringList& fileSet, ecl_file_enum fileType) +QString RifEclipseOutputFileTools::firstFileNameOfType(const QStringList& fileSet, ecl_file_enum fileType) { int i; for (i = 0; i < fileSet.count(); i++) @@ -194,9 +216,9 @@ QString RifEclipseOutputFileTools::fileNameByType(const QStringList& fileSet, ec //-------------------------------------------------------------------------------------------------- -/// Get all files of file of given type in given list of filenames, as filename or NULL if not found +/// Get all files of the given type from the provided list of filenames //-------------------------------------------------------------------------------------------------- -QStringList RifEclipseOutputFileTools::fileNamesByType(const QStringList& fileSet, ecl_file_enum fileType) +QStringList RifEclipseOutputFileTools::filterFileNamesOfType(const QStringList& fileSet, ecl_file_enum fileType) { QStringList fileNames; @@ -218,14 +240,14 @@ QStringList RifEclipseOutputFileTools::fileNamesByType(const QStringList& fileSe //-------------------------------------------------------------------------------------------------- /// Get set of Eclipse files based on an input file and its path //-------------------------------------------------------------------------------------------------- -bool RifEclipseOutputFileTools::fileSet(const QString& fileName, QStringList* fileSet) +bool RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(const QString& fullPathFileName, QStringList* baseNameFiles) { - CVF_ASSERT(fileSet); - fileSet->clear(); + CVF_ASSERT(baseNameFiles); + baseNameFiles->clear(); - QString filePath = QFileInfo(fileName).absoluteFilePath(); + QString filePath = QFileInfo(fullPathFileName).absoluteFilePath(); filePath = QFileInfo(filePath).path(); - QString fileNameBase = QFileInfo(fileName).baseName(); + QString fileNameBase = QFileInfo(fullPathFileName).baseName(); stringlist_type* eclipseFiles = stringlist_alloc_new(); ecl_util_select_filelist(filePath.toAscii().data(), fileNameBase.toAscii().data(), ECL_OTHER_FILE, false, eclipseFiles); @@ -233,12 +255,12 @@ bool RifEclipseOutputFileTools::fileSet(const QString& fileName, QStringList* fi int i; for (i = 0; i < stringlist_get_size(eclipseFiles); i++) { - fileSet->append(stringlist_safe_iget(eclipseFiles, i)); + baseNameFiles->append(stringlist_safe_iget(eclipseFiles, i)); } stringlist_free(eclipseFiles); - return fileSet->count() > 0; + return baseNameFiles->count() > 0; } @@ -280,3 +302,20 @@ void RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(ecl_file_type* ecl info.setProgress(i); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseOutputFileTools::readGridDimensions(const QString& gridFileName, std::vector< std::vector >& gridDimensions) +{ + int gridDims[3]; + + bool ret = ecl_grid_file_dims(gridFileName.toAscii().data(), NULL, gridDims); + if (ret) + { + gridDimensions.resize(1); + gridDimensions[0].push_back(gridDims[0]); + gridDimensions[0].push_back(gridDims[1]); + gridDimensions[0].push_back(gridDims[2]); + } +} diff --git a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h index b4644289de..a46c83e4b9 100644 --- a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h +++ b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h @@ -45,12 +45,15 @@ public: static void findKeywordsAndDataItemCounts(ecl_file_type* ecl_file, QStringList* keywords, std::vector* keywordDataItemCounts); static bool keywordData(ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector* values); + static bool keywordData(ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector* values); // static void timeStepsText(ecl_file_type* ecl_file, QStringList* timeSteps); - static void timeSteps(ecl_file_type* ecl_file, QList* timeSteps, bool* detectedFractionOfDay = NULL); + static void timeSteps(ecl_file_type* ecl_file, std::vector* timeSteps, bool* detectedFractionOfDay = NULL); - static bool fileSet(const QString& fileName, QStringList* fileSet); + static bool findSiblingFilesWithSameBaseName(const QString& fileName, QStringList* fileSet); - static QString fileNameByType(const QStringList& fileSet, ecl_file_enum fileType); - static QStringList fileNamesByType(const QStringList& fileSet, ecl_file_enum fileType); + static QString firstFileNameOfType(const QStringList& fileSet, ecl_file_enum fileType); + static QStringList filterFileNamesOfType(const QStringList& fileSet, ecl_file_enum fileType); + + static void readGridDimensions(const QString& gridFileName, std::vector< std::vector >& gridDimensions); }; diff --git a/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h b/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h index 25cf515ee0..757e324e02 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h +++ b/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h @@ -42,11 +42,13 @@ public: RifEclipseRestartDataAccess(); virtual ~RifEclipseRestartDataAccess(); - virtual bool open(const QStringList& fileSet) = 0; + virtual bool open() = 0; + virtual void setRestartFiles(const QStringList& fileSet) = 0; virtual void close() = 0; + virtual void setTimeSteps(const std::vector& timeSteps) {}; virtual size_t timeStepCount() = 0; - virtual QList timeSteps() = 0; + virtual std::vector timeSteps() = 0; virtual void resultNames(QStringList* resultNames, std::vector* resultDataItemCounts) = 0; virtual bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values) = 0; diff --git a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp index 40b3e7a631..fe28ec07be 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp +++ b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp @@ -40,30 +40,45 @@ RifEclipseRestartFilesetAccess::~RifEclipseRestartFilesetAccess() //-------------------------------------------------------------------------------------------------- /// Open files //-------------------------------------------------------------------------------------------------- -bool RifEclipseRestartFilesetAccess::open(const QStringList& fileSet) +bool RifEclipseRestartFilesetAccess::open() { - close(); - - int numFiles = fileSet.size(); - - caf::ProgressInfo progInfo(numFiles,""); - - int i; - for (i = 0; i < numFiles; i++) + if (m_fileNames.size() > 0) { - progInfo.setProgressDescription(fileSet[i]); + caf::ProgressInfo progInfo(m_fileNames.size(), ""); - ecl_file_type* ecl_file = ecl_file_open(fileSet[i].toAscii().data()); - if (!ecl_file) return false; + int i; + for (i = 0; i < m_fileNames.size(); i++) + { + progInfo.setProgressDescription(m_fileNames[i]); - m_ecl_files.push_back(ecl_file); + openTimeStep(i); - progInfo.incrementProgress(); + progInfo.incrementProgress(); + } } return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseRestartFilesetAccess::setRestartFiles(const QStringList& fileSet) +{ + close(); + m_ecl_files.clear(); + + m_fileNames = fileSet; + m_fileNames.sort(); // To make sure they are sorted in increasing *.X000N order. Hack. Should probably be actual time stored on file. + + for (int i = 0; i < m_fileNames.size(); i++) + { + m_ecl_files.push_back(NULL); + } + + CVF_ASSERT(m_fileNames.size() == static_cast(m_ecl_files.size())); +} + //-------------------------------------------------------------------------------------------------- /// Close files //-------------------------------------------------------------------------------------------------- @@ -71,10 +86,22 @@ void RifEclipseRestartFilesetAccess::close() { for (size_t i = 0; i < m_ecl_files.size(); i++) { - ecl_file_close(m_ecl_files[i]); - } - m_ecl_files.clear(); + if (m_ecl_files[i]) + { + ecl_file_close(m_ecl_files[i]); + } + m_ecl_files[i] = NULL; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseRestartFilesetAccess::setTimeSteps(const std::vector& timeSteps) +{ + CVF_ASSERT((size_t)m_fileNames.size() == timeSteps.size()); + m_timeSteps = timeSteps; } //-------------------------------------------------------------------------------------------------- @@ -82,35 +109,39 @@ void RifEclipseRestartFilesetAccess::close() //-------------------------------------------------------------------------------------------------- size_t RifEclipseRestartFilesetAccess::timeStepCount() { - return m_ecl_files.size(); + return m_timeSteps.size(); } //-------------------------------------------------------------------------------------------------- /// Get the time steps //-------------------------------------------------------------------------------------------------- -QList RifEclipseRestartFilesetAccess::timeSteps() +std::vector RifEclipseRestartFilesetAccess::timeSteps() { - QList timeSteps; - - size_t numSteps = timeStepCount(); - size_t i; - for (i = 0; i < numSteps; i++) + if (m_timeSteps.size() == 0) { - QList stepTime; + size_t numSteps = m_fileNames.size(); + size_t i; + for (i = 0; i < numSteps; i++) + { + std::vector stepTime; - RifEclipseOutputFileTools::timeSteps(m_ecl_files[i], &stepTime); + openTimeStep(i); + + RifEclipseOutputFileTools::timeSteps(m_ecl_files[i], &stepTime); - if (stepTime.size() == 1) - { - timeSteps.push_back(stepTime[0]); - } - else - { - timeSteps.push_back(QDateTime()); + if (stepTime.size() == 1) + { + m_timeSteps.push_back(stepTime[0]); + } + else + { + m_timeSteps.push_back(QDateTime()); + } } + } - return timeSteps; + return m_timeSteps; } //-------------------------------------------------------------------------------------------------- @@ -120,6 +151,8 @@ void RifEclipseRestartFilesetAccess::resultNames(QStringList* resultNames, std:: { CVF_ASSERT(timeStepCount() > 0); + openTimeStep(0); + std::vector valueCountForOneFile; RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(m_ecl_files[0], resultNames, &valueCountForOneFile); @@ -134,28 +167,35 @@ void RifEclipseRestartFilesetAccess::resultNames(QStringList* resultNames, std:: //-------------------------------------------------------------------------------------------------- bool RifEclipseRestartFilesetAccess::results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values) { - size_t numOccurrences = ecl_file_get_num_named_kw(m_ecl_files[timeStep], resultName.toAscii().data()); + if (timeStep >= timeStepCount()) + { + return false; + } + + openTimeStep(timeStep); + + size_t fileGridCount = ecl_file_get_num_named_kw(m_ecl_files[timeStep], resultName.toAscii().data()); // No results for this result variable for current time step found - if (numOccurrences == 0) return true; + if (fileGridCount == 0) return true; // Result handling depends on presents of result values for all grids - if (gridCount != numOccurrences) + if (gridCount != fileGridCount) { return false; } size_t i; - for (i = 0; i < numOccurrences; i++) + for (i = 0; i < fileGridCount; i++) { - std::vector partValues; + std::vector gridValues; - if (!RifEclipseOutputFileTools::keywordData(m_ecl_files[timeStep], resultName, i, &partValues)) + if (!RifEclipseOutputFileTools::keywordData(m_ecl_files[timeStep], resultName, i, &gridValues)) { return false; } - values->insert(values->end(), partValues.begin(), partValues.end()); + values->insert(values->end(), gridValues.begin(), gridValues.end()); } return true; @@ -171,6 +211,8 @@ void RifEclipseRestartFilesetAccess::readWellData(well_info_type* well_info) for (size_t i = 0; i < m_ecl_files.size(); i++) { + openTimeStep(i); + const char* fileName = ecl_file_get_src_file(m_ecl_files[i]); int reportNumber = ecl_util_filename_report_nr(fileName); if(reportNumber != -1) @@ -179,3 +221,20 @@ void RifEclipseRestartFilesetAccess::readWellData(well_info_type* well_info) } } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseRestartFilesetAccess::openTimeStep(size_t timeStep) +{ + CVF_ASSERT(timeStep < m_ecl_files.size()); + + if (m_ecl_files[timeStep] == NULL) + { + int index = static_cast(timeStep); + ecl_file_type* ecl_file = ecl_file_open(m_fileNames[index].toAscii().data()); + + m_ecl_files[timeStep] = ecl_file; + } +} + diff --git a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h index 7e0b181a44..645f641fc4 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h +++ b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h @@ -35,11 +35,13 @@ public: RifEclipseRestartFilesetAccess(); virtual ~RifEclipseRestartFilesetAccess(); - bool open(const QStringList& fileSet); + bool open(); + void setRestartFiles(const QStringList& fileSet); void close(); + void setTimeSteps(const std::vector& timeSteps); size_t timeStepCount(); - QList timeSteps(); + std::vector timeSteps(); void resultNames(QStringList* resultNames, std::vector* resultDataItemCounts); bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values); @@ -47,5 +49,11 @@ public: virtual void readWellData(well_info_type* well_info); private: - std::vector< ecl_file_type* > m_ecl_files; + void openTimeStep(size_t timeStep); + +private: + QStringList m_fileNames; + std::vector m_timeSteps; + + std::vector< ecl_file_type* > m_ecl_files; }; diff --git a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.cpp b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.cpp index 8fecb280e2..0586ef8d1e 100644 --- a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.cpp +++ b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.cpp @@ -38,22 +38,23 @@ RifEclipseUnifiedRestartFileAccess::RifEclipseUnifiedRestartFileAccess() //-------------------------------------------------------------------------------------------------- RifEclipseUnifiedRestartFileAccess::~RifEclipseUnifiedRestartFileAccess() { - if (m_ecl_file) - { - ecl_file_close(m_ecl_file); - } - - m_ecl_file = NULL; + close(); } //-------------------------------------------------------------------------------------------------- /// Open file //-------------------------------------------------------------------------------------------------- -bool RifEclipseUnifiedRestartFileAccess::open(const QStringList& fileSet) +bool RifEclipseUnifiedRestartFileAccess::open() { - QString fileName = fileSet[0]; + return true; +} - m_ecl_file = ecl_file_open(fileName.toAscii().data()); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifEclipseUnifiedRestartFileAccess::openFile() +{ + m_ecl_file = ecl_file_open(m_filename.toAscii().data()); if (!m_ecl_file) return false; return true; @@ -64,6 +65,12 @@ bool RifEclipseUnifiedRestartFileAccess::open(const QStringList& fileSet) //-------------------------------------------------------------------------------------------------- void RifEclipseUnifiedRestartFileAccess::close() { + if (m_ecl_file) + { + ecl_file_close(m_ecl_file); + } + + m_ecl_file = NULL; } //-------------------------------------------------------------------------------------------------- @@ -71,18 +78,25 @@ void RifEclipseUnifiedRestartFileAccess::close() //-------------------------------------------------------------------------------------------------- size_t RifEclipseUnifiedRestartFileAccess::timeStepCount() { + if (!openFile()) + { + return 0; + } + return timeSteps().size(); } //-------------------------------------------------------------------------------------------------- /// Get the time steps //-------------------------------------------------------------------------------------------------- -QList RifEclipseUnifiedRestartFileAccess::timeSteps() +std::vector RifEclipseUnifiedRestartFileAccess::timeSteps() { - CVF_ASSERT(m_ecl_file != NULL); + std::vector timeSteps; - QList timeSteps; - RifEclipseOutputFileTools::timeSteps(m_ecl_file, &timeSteps); + if (openFile()) + { + RifEclipseOutputFileTools::timeSteps(m_ecl_file, &timeSteps); + } return timeSteps; } @@ -92,7 +106,10 @@ QList RifEclipseUnifiedRestartFileAccess::timeSteps() //-------------------------------------------------------------------------------------------------- void RifEclipseUnifiedRestartFileAccess::resultNames(QStringList* resultNames, std::vector* resultDataItemCounts) { - RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(m_ecl_file, resultNames, resultDataItemCounts); + if (openFile()) + { + RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(m_ecl_file, resultNames, resultDataItemCounts); + } } //-------------------------------------------------------------------------------------------------- @@ -100,6 +117,11 @@ void RifEclipseUnifiedRestartFileAccess::resultNames(QStringList* resultNames, s //-------------------------------------------------------------------------------------------------- bool RifEclipseUnifiedRestartFileAccess::results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values) { + if (!openFile()) + { + return false; + } + size_t numOccurrences = ecl_file_get_num_named_kw(m_ecl_file, resultName.toAscii().data()); size_t startIndex = timeStep * gridCount; @@ -124,8 +146,19 @@ bool RifEclipseUnifiedRestartFileAccess::results(const QString& resultName, size void RifEclipseUnifiedRestartFileAccess::readWellData(well_info_type* well_info) { if (!well_info) return; - CVF_ASSERT(m_ecl_file); - well_info_add_UNRST_wells(well_info, m_ecl_file); + if (openFile()) + { + well_info_add_UNRST_wells(well_info, m_ecl_file); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseUnifiedRestartFileAccess::setRestartFiles(const QStringList& fileSet) +{ + m_filename = fileSet[0]; + } diff --git a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h index f8188db60e..066f685153 100644 --- a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h +++ b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h @@ -37,11 +37,12 @@ public: RifEclipseUnifiedRestartFileAccess(); virtual ~RifEclipseUnifiedRestartFileAccess(); - bool open(const QStringList& fileSet); + void setRestartFiles(const QStringList& fileSet); + bool open(); void close(); size_t timeStepCount(); - QList timeSteps(); + std::vector timeSteps(); void resultNames(QStringList* resultNames, std::vector* resultDataItemCounts); bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values); @@ -49,5 +50,9 @@ public: virtual void readWellData(well_info_type * well_info); private: + bool openFile(); + +private: + QString m_filename; ecl_file_type* m_ecl_file; }; diff --git a/ApplicationCode/FileInterface/RifReaderEclipseInput.cpp b/ApplicationCode/FileInterface/RifReaderEclipseInput.cpp index 6a21dbeb51..3836f514b8 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseInput.cpp +++ b/ApplicationCode/FileInterface/RifReaderEclipseInput.cpp @@ -19,8 +19,8 @@ #include "cvfBase.h" #include "RigMainGrid.h" -#include "RigReservoir.h" -#include "RigReservoirCellResults.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" #include "RifReaderEclipseInput.h" #include "RifReaderEclipseOutput.h" @@ -57,9 +57,9 @@ RifReaderEclipseInput::~RifReaderEclipseInput() //-------------------------------------------------------------------------------------------------- /// Open file and read geometry into given reservoir object //-------------------------------------------------------------------------------------------------- -bool RifReaderEclipseInput::open(const QString& fileName, RigReservoir* reservoir) +bool RifReaderEclipseInput::open(const QString& fileName, RigCaseData* eclipseCase) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); // Make sure everything's closed close(); @@ -84,9 +84,9 @@ bool RifReaderEclipseInput::open(const QString& fileName, RigReservoir* reservoi // create InputProperty object bool isOk = false; - if (reservoir->mainGrid()->gridPointDimensions() == cvf::Vec3st(0,0,0)) + if (eclipseCase->mainGrid()->gridPointDimensions() == cvf::Vec3st(0,0,0)) { - isOk = RifEclipseInputFileTools::openGridFile(fileName, reservoir); + isOk = RifEclipseInputFileTools::openGridFile(fileName, eclipseCase); } return isOk; diff --git a/ApplicationCode/FileInterface/RifReaderEclipseInput.h b/ApplicationCode/FileInterface/RifReaderEclipseInput.h index 94abe84af2..32499507e4 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseInput.h +++ b/ApplicationCode/FileInterface/RifReaderEclipseInput.h @@ -32,7 +32,7 @@ public: virtual ~RifReaderEclipseInput(); // Virtual interface implementation - virtual bool open(const QString& fileName, RigReservoir* reservoir); + virtual bool open(const QString& fileName, RigCaseData* eclipseCase); diff --git a/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp b/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp index bd2ec9b0b6..9b066e68e3 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp +++ b/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp @@ -19,8 +19,8 @@ #include "cvfBase.h" #include "RigMainGrid.h" -#include "RigReservoir.h" -#include "RigReservoirCellResults.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" #include "RifReaderEclipseOutput.h" #include "RifEclipseOutputFileTools.h" @@ -32,6 +32,8 @@ #include "ecl_grid.h" #include "well_state.h" +#include "ecl_kw_magic.h" + #include "cafProgressInfo.h" //-------------------------------------------------------------------------------------------------- @@ -84,8 +86,10 @@ static const size_t cellMappingECLRi[8] = { 0, 1, 3, 2, 4, 5, 7, 6 }; // Static functions //************************************************************************************************** -bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const ecl_grid_type* localEclGrid, size_t matrixActiveStartIndex, size_t fractureActiveStartIndex) +bool transferGridCellData(RigMainGrid* mainGrid, RigActiveCellInfo* activeCellInfo, RigActiveCellInfo* fractureActiveCellInfo, RigGridBase* localGrid, const ecl_grid_type* localEclGrid, size_t matrixActiveStartIndex, size_t fractureActiveStartIndex) { + CVF_ASSERT(activeCellInfo && fractureActiveCellInfo); + int cellCount = ecl_grid_get_global_size(localEclGrid); size_t cellStartIndex = mainGrid->cells().size(); size_t nodeStartIndex = mainGrid->nodes().size(); @@ -103,39 +107,31 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const e // Loop over cells and fill them with data #pragma omp parallel for - for (int gIdx = 0; gIdx < cellCount; ++gIdx) + for (int localCellIdx = 0; localCellIdx < cellCount; ++localCellIdx) { - RigCell& cell = mainGrid->cells()[cellStartIndex + gIdx]; + RigCell& cell = mainGrid->cells()[cellStartIndex + localCellIdx]; - bool invalid = ecl_grid_cell_invalid1(localEclGrid, gIdx); + bool invalid = ecl_grid_cell_invalid1(localEclGrid, localCellIdx); cell.setInvalid(invalid); - cell.setCellIndex(gIdx); + cell.setCellIndex(localCellIdx); // Active cell index - int matrixActiveIndex = ecl_grid_get_active_index1(localEclGrid, gIdx); + int matrixActiveIndex = ecl_grid_get_active_index1(localEclGrid, localCellIdx); if (matrixActiveIndex != -1) { - cell.setActiveIndexInMatrixModel(matrixActiveStartIndex + matrixActiveIndex); - } - else - { - cell.setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); + activeCellInfo->setCellResultIndex(cellStartIndex + localCellIdx, matrixActiveStartIndex + matrixActiveIndex); } - int fractureActiveIndex = ecl_grid_get_active_fracture_index1(localEclGrid, gIdx); + int fractureActiveIndex = ecl_grid_get_active_fracture_index1(localEclGrid, localCellIdx); if (fractureActiveIndex != -1) { - cell.setActiveIndexInFractureModel(fractureActiveStartIndex + fractureActiveIndex); - } - else - { - cell.setActiveIndexInFractureModel(cvf::UNDEFINED_SIZE_T); + fractureActiveCellInfo->setCellResultIndex(cellStartIndex + localCellIdx, fractureActiveStartIndex + fractureActiveIndex); } // Parent cell index - int parentCellIndex = ecl_grid_get_parent_cell1(localEclGrid, gIdx); + int parentCellIndex = ecl_grid_get_parent_cell1(localEclGrid, localCellIdx); if (parentCellIndex == -1) { cell.setParentCellIndex(cvf::UNDEFINED_SIZE_T); @@ -146,21 +142,21 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const e } // Coarse cell info - ecl_coarse_cell_type * coarseCellData = ecl_grid_get_cell_coarse_group1( localEclGrid , gIdx); + ecl_coarse_cell_type * coarseCellData = ecl_grid_get_cell_coarse_group1( localEclGrid , localCellIdx); cell.setInCoarseCell(coarseCellData != NULL); // Corner coordinates int cIdx; for (cIdx = 0; cIdx < 8; ++cIdx) { - double * point = mainGrid->nodes()[nodeStartIndex + gIdx * 8 + cellMappingECLRi[cIdx]].ptr(); - ecl_grid_get_corner_xyz1(localEclGrid, gIdx, cIdx, &(point[0]), &(point[1]), &(point[2])); + double * point = mainGrid->nodes()[nodeStartIndex + localCellIdx * 8 + cellMappingECLRi[cIdx]].ptr(); + ecl_grid_get_corner_xyz1(localEclGrid, localCellIdx, cIdx, &(point[0]), &(point[1]), &(point[2])); point[2] = -point[2]; - cell.cornerIndices()[cIdx] = nodeStartIndex + gIdx*8 + cIdx; + cell.cornerIndices()[cIdx] = nodeStartIndex + localCellIdx*8 + cIdx; } // Sub grid in cell - const ecl_grid_type* subGrid = ecl_grid_get_cell_lgr1(localEclGrid, gIdx); + const ecl_grid_type* subGrid = ecl_grid_get_cell_lgr1(localEclGrid, localCellIdx); if (subGrid != NULL) { int subGridFileIndex = ecl_grid_get_grid_nr(subGrid); @@ -169,7 +165,9 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const e } // Mark inactive long pyramid looking cells as invalid - if (!invalid && (cell.isInCoarseCell() || (!cell.isActiveInMatrixModel() && !cell.isActiveInFractureModel()) ) ) + // Forslag + //if (!invalid && (cell.isInCoarseCell() || (!cell.isActiveInMatrixModel() && !cell.isActiveInFractureModel()) ) ) + if (!invalid) { cell.setInvalid(cell.isLongPyramidCell()); } @@ -193,7 +191,15 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const e //-------------------------------------------------------------------------------------------------- RifReaderEclipseOutput::RifReaderEclipseOutput() { - ground(); + m_fileName.clear(); + m_filesWithSameBaseName.clear(); + + m_timeSteps.clear(); + + m_eclipseCase = NULL; + + m_ecl_init_file = NULL; + m_dynamicResultsAccess = NULL; } //-------------------------------------------------------------------------------------------------- @@ -201,37 +207,33 @@ RifReaderEclipseOutput::RifReaderEclipseOutput() //-------------------------------------------------------------------------------------------------- RifReaderEclipseOutput::~RifReaderEclipseOutput() { + close(); } -//-------------------------------------------------------------------------------------------------- -/// Ground members -//-------------------------------------------------------------------------------------------------- -void RifReaderEclipseOutput::ground() -{ - m_fileName.clear(); - m_fileSet.clear(); - - m_timeSteps.clear(); - m_mainGrid = NULL; -} //-------------------------------------------------------------------------------------------------- /// Close interface (for now, no files are kept open after calling methods, so just clear members) //-------------------------------------------------------------------------------------------------- void RifReaderEclipseOutput::close() { - m_ecl_file = NULL; - m_dynamicResultsAccess = NULL; + if (m_ecl_init_file) + { + ecl_file_close(m_ecl_init_file); + } + m_ecl_init_file = NULL; - ground(); + if (m_dynamicResultsAccess.notNull()) + { + m_dynamicResultsAccess->close(); + } } //-------------------------------------------------------------------------------------------------- /// Read geometry from file given by name into given reservoir object //-------------------------------------------------------------------------------------------------- -bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, RigReservoir* reservoir) +bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, RigCaseData* eclipseCase) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); if (!mainEclGrid) { @@ -239,7 +241,12 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, return false; } - RigMainGrid* mainGrid = reservoir->mainGrid(); + RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); + RigActiveCellInfo* fractureActiveCellInfo = eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS); + + CVF_ASSERT(activeCellInfo && fractureActiveCellInfo); + + RigMainGrid* mainGrid = eclipseCase->mainGrid(); { cvf::Vec3st gridPointDim(0,0,0); gridPointDim.x() = ecl_grid_get_nx(mainEclGrid) + 1; @@ -273,6 +280,9 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, totalCellCount += ecl_grid_get_global_size(localEclGrid); } + + activeCellInfo->setGlobalCellCount(totalCellCount); + fractureActiveCellInfo->setGlobalCellCount(totalCellCount); // Reserve room for the cells and nodes and fill them with data @@ -283,15 +293,20 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, progInfo.setProgressDescription("Main Grid"); progInfo.setNextProgressIncrement(3); - transferGridCellData(mainGrid, mainGrid, mainEclGrid, 0, 0); + transferGridCellData(mainGrid, activeCellInfo, fractureActiveCellInfo, mainGrid, mainEclGrid, 0, 0); progInfo.setProgress(3); size_t globalMatrixActiveSize = ecl_grid_get_nactive(mainEclGrid); size_t globalFractureActiveSize = ecl_grid_get_nactive_fracture(mainEclGrid); - mainGrid->setMatrixModelActiveCellCount(globalMatrixActiveSize); - mainGrid->setFractureModelActiveCellCount(globalFractureActiveSize); + activeCellInfo->setGridCount(1 + numLGRs); + fractureActiveCellInfo->setGridCount(1 + numLGRs); + + activeCellInfo->setGridActiveCellCounts(0, globalMatrixActiveSize); + fractureActiveCellInfo->setGridActiveCellCounts(0, globalFractureActiveSize); + + for (lgrIdx = 0; lgrIdx < numLGRs; ++lgrIdx) { @@ -300,22 +315,21 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, ecl_grid_type* localEclGrid = ecl_grid_iget_lgr(mainEclGrid, lgrIdx); RigLocalGrid* localGrid = static_cast(mainGrid->gridByIndex(lgrIdx+1)); - transferGridCellData(mainGrid, localGrid, localEclGrid, globalMatrixActiveSize, globalFractureActiveSize); + transferGridCellData(mainGrid, activeCellInfo, fractureActiveCellInfo, localGrid, localEclGrid, globalMatrixActiveSize, globalFractureActiveSize); - int activeCellCount = ecl_grid_get_nactive(localEclGrid); - localGrid->setMatrixModelActiveCellCount(activeCellCount); - globalMatrixActiveSize += activeCellCount; + int matrixActiveCellCount = ecl_grid_get_nactive(localEclGrid); + globalMatrixActiveSize += matrixActiveCellCount; - activeCellCount = ecl_grid_get_nactive_fracture(localEclGrid); - localGrid->setFractureModelActiveCellCount(activeCellCount); - globalFractureActiveSize += activeCellCount; + int fractureActiveCellCount = ecl_grid_get_nactive_fracture(localEclGrid); + globalFractureActiveSize += fractureActiveCellCount; + activeCellInfo->setGridActiveCellCounts(lgrIdx + 1, matrixActiveCellCount); + fractureActiveCellInfo->setGridActiveCellCounts(lgrIdx + 1, fractureActiveCellCount); progInfo.setProgress(3 + lgrIdx); } - - mainGrid->setGlobalMatrixModelActiveCellCount(globalMatrixActiveSize); - mainGrid->setGlobalFractureModelActiveCellCount(globalFractureActiveSize); + activeCellInfo->computeDerivedData(); + fractureActiveCellInfo->computeDerivedData(); return true; } @@ -323,9 +337,9 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, //-------------------------------------------------------------------------------------------------- /// Open file and read geometry into given reservoir object //-------------------------------------------------------------------------------------------------- -bool RifReaderEclipseOutput::open(const QString& fileName, RigReservoir* reservoir) +bool RifReaderEclipseOutput::open(const QString& fileName, RigCaseData* eclipseCase) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); caf::ProgressInfo progInfo(100, ""); progInfo.setProgressDescription("Reading Grid"); @@ -335,13 +349,13 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigReservoir* reservo // Get set of files QStringList fileSet; - if (!RifEclipseOutputFileTools::fileSet(fileName, &fileSet)) return false; + if (!RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(fileName, &fileSet)) return false; progInfo.incrementProgress(); progInfo.setNextProgressIncrement(20); // Keep the set of files of interest - m_fileSet = fileSet; + m_filesWithSameBaseName = fileSet; // Read geometry ecl_grid_type * mainEclGrid = ecl_grid_alloc( fileName.toAscii().data() ); @@ -351,7 +365,7 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigReservoir* reservo progInfo.setNextProgressIncrement(10); progInfo.setProgressDescription("Transferring grid geometry"); - if (!transferGeometry(mainEclGrid, reservoir)) return false; + if (!transferGeometry(mainEclGrid, eclipseCase)) return false; progInfo.incrementProgress(); progInfo.setProgressDescription("Releasing reader memory"); @@ -361,47 +375,177 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigReservoir* reservo progInfo.setProgressDescription("Reading Result index"); progInfo.setNextProgressIncrement(60); - m_mainGrid = reservoir->mainGrid(); - - reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(this); - reservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(this); + m_eclipseCase = eclipseCase; // Build results meta data - if (!buildMetaData(reservoir)) return false; + if (!buildMetaData()) return false; progInfo.incrementProgress(); progInfo.setNextProgressIncrement(8); progInfo.setProgressDescription("Reading Well information"); - readWellCells(reservoir); + readWellCells(); return true; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifReaderEclipseOutput::openAndReadActiveCellData(const QString& fileName, const std::vector& mainCaseTimeSteps, RigCaseData* eclipseCase) +{ + CVF_ASSERT(eclipseCase); + + // It is required to have a main grid before reading active cell data + if (!eclipseCase->mainGrid()) + { + return false; + } + + close(); + + // Get set of files + QStringList fileSet; + if (!RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(fileName, &fileSet)) return false; + + // Keep the set of files of interest + m_filesWithSameBaseName = fileSet; + m_eclipseCase = eclipseCase; + + + if (!readActiveCellInfo()) + { + return false; + } + + + // Reading of metadata and well cells is not performed here + //if (!buildMetaData()) return false; + // readWellCells(); + + m_dynamicResultsAccess = createDynamicResultsAccess(); + + m_dynamicResultsAccess->setTimeSteps(mainCaseTimeSteps); + + return true; +} + + +//-------------------------------------------------------------------------------------------------- +/// +/// See also RigStatistics::computeActiveCellUnion() +//-------------------------------------------------------------------------------------------------- +bool RifReaderEclipseOutput::readActiveCellInfo() +{ + CVF_ASSERT(m_eclipseCase); + CVF_ASSERT(m_eclipseCase->mainGrid()); + + QString egridFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_EGRID_FILE); + if (egridFileName.size() > 0) + { + ecl_file_type* ecl_file = ecl_file_open(egridFileName.toAscii().data()); + if (!ecl_file) return false; + + int actnumKeywordCount = ecl_file_get_num_named_kw(ecl_file, ACTNUM_KW); + if (actnumKeywordCount > 0) + { + std::vector > actnumValuesPerGrid; + actnumValuesPerGrid.resize(actnumKeywordCount); + + size_t globalCellCount = 0; + for (size_t gridIdx = 0; gridIdx < static_cast(actnumKeywordCount); gridIdx++) + { + RifEclipseOutputFileTools::keywordData(ecl_file, ACTNUM_KW, gridIdx, &actnumValuesPerGrid[gridIdx]); + + globalCellCount += actnumValuesPerGrid[gridIdx].size(); + } + + // Check if number of cells is matching + if (m_eclipseCase->mainGrid()->cells().size() != globalCellCount) + { + return false; + } + + RigActiveCellInfo* activeCellInfo = m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); + RigActiveCellInfo* fractureActiveCellInfo = m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS); + + activeCellInfo->setGlobalCellCount(globalCellCount); + fractureActiveCellInfo->setGlobalCellCount(globalCellCount); + activeCellInfo->setGridCount(actnumKeywordCount); + fractureActiveCellInfo->setGridCount(actnumKeywordCount); + + size_t cellIdx = 0; + size_t globalActiveMatrixIndex = 0; + size_t globalActiveFractureIndex = 0; + for (size_t gridIdx = 0; gridIdx < static_cast(actnumKeywordCount); gridIdx++) + { + size_t activeMatrixIndex = 0; + size_t activeFractureIndex = 0; + + std::vector& actnumValues = actnumValuesPerGrid[gridIdx]; + + for (size_t i = 0; i < actnumValues.size(); i++) + { + if (actnumValues[i] == 1 || actnumValues[i] == 3) + { + activeCellInfo->setCellResultIndex(cellIdx, globalActiveMatrixIndex++); + activeMatrixIndex++; + } + + if (actnumValues[i] == 2 || actnumValues[i] == 3) + { + fractureActiveCellInfo->setCellResultIndex(cellIdx, globalActiveFractureIndex++); + activeFractureIndex++; + } + + cellIdx++; + } + + activeCellInfo->setGridActiveCellCounts(gridIdx, activeMatrixIndex); + fractureActiveCellInfo->setGridActiveCellCounts(gridIdx, activeFractureIndex); + } + + activeCellInfo->computeDerivedData(); + fractureActiveCellInfo->computeDerivedData(); + } + + ecl_file_close(ecl_file); + + return true; + } + + return false; +} + + //-------------------------------------------------------------------------------------------------- /// Build meta data - get states and results info //-------------------------------------------------------------------------------------------------- -bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) +bool RifReaderEclipseOutput::buildMetaData() { - CVF_ASSERT(reservoir); - CVF_ASSERT(m_fileSet.size() > 0); + CVF_ASSERT(m_eclipseCase); + CVF_ASSERT(m_filesWithSameBaseName.size() > 0); - caf::ProgressInfo progInfo(m_fileSet.size() + 3,""); + caf::ProgressInfo progInfo(m_filesWithSameBaseName.size() + 3,""); - progInfo.setNextProgressIncrement(m_fileSet.size()); + progInfo.setNextProgressIncrement(m_filesWithSameBaseName.size()); // Create access object for dynamic results - m_dynamicResultsAccess = dynamicResultsAccess(m_fileSet); + m_dynamicResultsAccess = createDynamicResultsAccess(); if (m_dynamicResultsAccess.isNull()) { return false; } + m_dynamicResultsAccess->open(); + + progInfo.incrementProgress(); - RigReservoirCellResults* matrixModelResults = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS); - RigReservoirCellResults* fractureModelResults = reservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS); + RigCaseCellResultsData* matrixModelResults = m_eclipseCase->results(RifReaderInterface::MATRIX_RESULTS); + RigCaseCellResultsData* fractureModelResults = m_eclipseCase->results(RifReaderInterface::FRACTURE_RESULTS); if (m_dynamicResultsAccess.notNull()) { @@ -413,21 +557,27 @@ bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) m_dynamicResultsAccess->resultNames(&resultNames, &resultNamesDataItemCounts); { - QStringList matrixResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, RifReaderInterface::MATRIX_RESULTS, m_dynamicResultsAccess->timeStepCount()); + QStringList matrixResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, + m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS), + m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS), + RifReaderInterface::MATRIX_RESULTS, m_dynamicResultsAccess->timeStepCount()); for (int i = 0; i < matrixResultNames.size(); ++i) { - size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, matrixResultNames[i]); + size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, matrixResultNames[i], false); matrixModelResults->setTimeStepDates(resIndex, m_timeSteps); } } { - QStringList fractureResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, RifReaderInterface::FRACTURE_RESULTS, m_dynamicResultsAccess->timeStepCount()); + QStringList fractureResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, + m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS), + m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS), + RifReaderInterface::FRACTURE_RESULTS, m_dynamicResultsAccess->timeStepCount()); for (int i = 0; i < fractureResultNames.size(); ++i) { - size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, fractureResultNames[i]); + size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, fractureResultNames[i], false); fractureModelResults->setTimeStepDates(resIndex, m_timeSteps); } } @@ -436,22 +586,23 @@ bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) progInfo.incrementProgress(); - QString initFileName = RifEclipseOutputFileTools::fileNameByType(m_fileSet, ECL_INIT_FILE); - if (initFileName.size() > 0) + openInitFile(); + + progInfo.incrementProgress(); + + if (m_ecl_init_file) { - ecl_file_type* ecl_file = ecl_file_open(initFileName.toAscii().data()); - if (!ecl_file) return false; - - progInfo.incrementProgress(); - QStringList resultNames; std::vector resultNamesDataItemCounts; - RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(ecl_file, &resultNames, &resultNamesDataItemCounts); + RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(m_ecl_init_file, &resultNames, &resultNamesDataItemCounts); { - QStringList matrixResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, RifReaderInterface::MATRIX_RESULTS, 1); + QStringList matrixResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, + m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS), + m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS), + RifReaderInterface::MATRIX_RESULTS, 1); - QList staticDate; + std::vector staticDate; if (m_timeSteps.size() > 0) { staticDate.push_back(m_timeSteps.front()); @@ -459,15 +610,18 @@ bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) for (int i = 0; i < matrixResultNames.size(); ++i) { - size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, matrixResultNames[i]); + size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, matrixResultNames[i], false); matrixModelResults->setTimeStepDates(resIndex, staticDate); } } { - QStringList fractureResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, RifReaderInterface::FRACTURE_RESULTS, 1); + QStringList fractureResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, + m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS), + m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS), + RifReaderInterface::FRACTURE_RESULTS, 1); - QList staticDate; + std::vector staticDate; if (m_timeSteps.size() > 0) { staticDate.push_back(m_timeSteps.front()); @@ -475,12 +629,10 @@ bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) for (int i = 0; i < fractureResultNames.size(); ++i) { - size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, fractureResultNames[i]); + size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, fractureResultNames[i], false); fractureModelResults->setTimeStepDates(resIndex, staticDate); } } - - m_ecl_file = ecl_file; } return true; @@ -489,39 +641,28 @@ bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) //-------------------------------------------------------------------------------------------------- /// Create results access object (.UNRST or .X0001 ... .XNNNN) //-------------------------------------------------------------------------------------------------- -RifEclipseRestartDataAccess* RifReaderEclipseOutput::dynamicResultsAccess(const QStringList& fileSet) +RifEclipseRestartDataAccess* RifReaderEclipseOutput::createDynamicResultsAccess() { RifEclipseRestartDataAccess* resultsAccess = NULL; // Look for unified restart file - QString unrstFileName = RifEclipseOutputFileTools::fileNameByType(fileSet, ECL_UNIFIED_RESTART_FILE); + QString unrstFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_UNIFIED_RESTART_FILE); if (unrstFileName.size() > 0) { resultsAccess = new RifEclipseUnifiedRestartFileAccess(); - if (!resultsAccess->open(QStringList(unrstFileName))) - { - delete resultsAccess; - return NULL; - } + resultsAccess->setRestartFiles(QStringList(unrstFileName)); } else { // Look for set of restart files (one file per time step) - QStringList restartFiles = RifEclipseOutputFileTools::fileNamesByType(fileSet, ECL_RESTART_FILE); + QStringList restartFiles = RifEclipseOutputFileTools::filterFileNamesOfType(m_filesWithSameBaseName, ECL_RESTART_FILE); if (restartFiles.size() > 0) { resultsAccess = new RifEclipseRestartFilesetAccess(); - if (!resultsAccess->open(restartFiles)) - { - delete resultsAccess; - return NULL; - } + resultsAccess->setRestartFiles(restartFiles); } } - // !! could add support for formatted result files - // !! consider priorities in case multiple types exist (.UNRST, .XNNNN, ...) - return resultsAccess; } @@ -531,16 +672,22 @@ RifEclipseRestartDataAccess* RifReaderEclipseOutput::dynamicResultsAccess(const bool RifReaderEclipseOutput::staticResult(const QString& result, PorosityModelResultType matrixOrFracture, std::vector* values) { CVF_ASSERT(values); - CVF_ASSERT(m_ecl_file); + + if (!openInitFile()) + { + return false; + } + + CVF_ASSERT(m_ecl_init_file); std::vector fileValues; - size_t numOccurrences = ecl_file_get_num_named_kw(m_ecl_file, result.toAscii().data()); + size_t numOccurrences = ecl_file_get_num_named_kw(m_ecl_init_file, result.toAscii().data()); size_t i; for (i = 0; i < numOccurrences; i++) { std::vector partValues; - RifEclipseOutputFileTools::keywordData(m_ecl_file, result, i, &partValues); + RifEclipseOutputFileTools::keywordData(m_ecl_init_file, result, i, &partValues); fileValues.insert(fileValues.end(), partValues.begin(), partValues.end()); } @@ -554,10 +701,19 @@ bool RifReaderEclipseOutput::staticResult(const QString& result, PorosityModelRe //-------------------------------------------------------------------------------------------------- bool RifReaderEclipseOutput::dynamicResult(const QString& result, PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector* values) { - CVF_ASSERT(m_dynamicResultsAccess.notNull()); + if (m_dynamicResultsAccess.isNull()) + { + m_dynamicResultsAccess = createDynamicResultsAccess(); + } + + if (m_dynamicResultsAccess.isNull()) + { + CVF_ASSERT(false); + return false; + } std::vector fileValues; - if (!m_dynamicResultsAccess->results(result, stepIndex, m_mainGrid->gridCount(), &fileValues)) + if (!m_dynamicResultsAccess->results(result, stepIndex, m_eclipseCase->mainGrid()->gridCount(), &fileValues)) { return false; } @@ -570,9 +726,9 @@ bool RifReaderEclipseOutput::dynamicResult(const QString& result, PorosityModelR //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifReaderEclipseOutput::readWellCells(RigReservoir* reservoir) +void RifReaderEclipseOutput::readWellCells() { - CVF_ASSERT(reservoir); + CVF_ASSERT(m_eclipseCase); if (m_dynamicResultsAccess.isNull()) return; @@ -581,11 +737,11 @@ void RifReaderEclipseOutput::readWellCells(RigReservoir* reservoir) m_dynamicResultsAccess->readWellData(ert_well_info); - RigMainGrid* mainGrid = reservoir->mainGrid(); + RigMainGrid* mainGrid = m_eclipseCase->mainGrid(); std::vector grids; - reservoir->allGrids(&grids); + m_eclipseCase->allGrids(&grids); - cvf::Collection wells; + cvf::Collection wells; caf::ProgressInfo progress(well_info_get_num_wells(ert_well_info), ""); int wellIdx; @@ -594,7 +750,7 @@ void RifReaderEclipseOutput::readWellCells(RigReservoir* reservoir) const char* wellName = well_info_iget_well_name(ert_well_info, wellIdx); CVF_ASSERT(wellName); - cvf::ref wellResults = new RigWellResults; + cvf::ref wellResults = new RigSingleWellResultsData; wellResults->m_wellName = wellName; well_ts_type* ert_well_time_series = well_info_get_ts(ert_well_info , wellName); @@ -671,7 +827,7 @@ void RifReaderEclipseOutput::readWellCells(RigReservoir* reservoir) // If a well is defined in fracture region, the K-value is from (cellCountK - 1) -> cellCountK*2 - 1 // Adjust K so index is always in valid grid region - if (cellK >= grids[gridNr]->cellCountK()) + if (cellK >= static_cast(grids[gridNr]->cellCountK())) { cellK -= static_cast(grids[gridNr]->cellCountK()); } @@ -716,7 +872,7 @@ void RifReaderEclipseOutput::readWellCells(RigReservoir* reservoir) // If a well is defined in fracture region, the K-value is from (cellCountK - 1) -> cellCountK*2 - 1 // Adjust K so index is always in valid grid region - if (cellK >= grids[gridNr]->cellCountK()) + if (cellK >= static_cast(grids[gridNr]->cellCountK())) { cellK -= static_cast(grids[gridNr]->cellCountK()); } @@ -743,41 +899,27 @@ void RifReaderEclipseOutput::readWellCells(RigReservoir* reservoir) well_info_free(ert_well_info); - reservoir->setWellResults(wells); + m_eclipseCase->setWellResults(wells); } -//-------------------------------------------------------------------------------------------------- -// For case DUALPORO, the well K index is reported outside the grid. If this happens, -// for the given IJ position, search from K=0 and upwards for first active cell. -//-------------------------------------------------------------------------------------------------- -int RifReaderEclipseOutput::findSmallestActiveCellIndexK(const RigGridBase* grid, int cellI, int cellJ) -{ - if (!grid) return -1; - - for (int candidateCellK = 0; candidateCellK < grid->cellCountK(); candidateCellK++ ) - { - if (grid->isCellActive(cellI, cellJ, candidateCellK)) - { - return candidateCellK; - } - } - - return -1; -} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel(const QStringList& keywords, const std::vector& keywordDataItemCounts, PorosityModelResultType matrixOrFracture, size_t timeStepCount) const +QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel(const QStringList& keywords, const std::vector& keywordDataItemCounts, + const RigActiveCellInfo* activeCellInfo, const RigActiveCellInfo* fractureActiveCellInfo, + PorosityModelResultType matrixOrFracture, size_t timeStepCount) const { - if (keywords.size() != keywordDataItemCounts.size()) + CVF_ASSERT(activeCellInfo); + + if (keywords.size() != static_cast(keywordDataItemCounts.size())) { return QStringList(); } if (matrixOrFracture == RifReaderInterface::FRACTURE_RESULTS) { - if (m_mainGrid->globalFractureModelActiveCellCount() == 0) + if (fractureActiveCellInfo->globalActiveCellCount() == 0) { return QStringList(); } @@ -790,17 +932,27 @@ QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel(const QStringL QString keyword = keywords[i]; size_t keywordDataCount = keywordDataItemCounts[i]; - size_t timeStepsMatrix = keywordDataItemCounts[i] / m_mainGrid->globalMatrixModelActiveCellCount(); - size_t timeStepsMatrixRest = keywordDataItemCounts[i] % m_mainGrid->globalMatrixModelActiveCellCount(); - - size_t timeStepsMatrixAndFracture = keywordDataItemCounts[i] / (m_mainGrid->globalMatrixModelActiveCellCount() + m_mainGrid->globalFractureModelActiveCellCount()); - size_t timeStepsMatrixAndFractureRest = keywordDataItemCounts[i] % (m_mainGrid->globalMatrixModelActiveCellCount() + m_mainGrid->globalFractureModelActiveCellCount()); - - if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS) + if (activeCellInfo->globalActiveCellCount() > 0) { - if (timeStepsMatrixRest == 0 || timeStepsMatrixAndFractureRest == 0) + size_t timeStepsMatrix = keywordDataItemCounts[i] / activeCellInfo->globalActiveCellCount(); + size_t timeStepsMatrixRest = keywordDataItemCounts[i] % activeCellInfo->globalActiveCellCount(); + + size_t timeStepsMatrixAndFracture = keywordDataItemCounts[i] / (activeCellInfo->globalActiveCellCount() + fractureActiveCellInfo->globalActiveCellCount()); + size_t timeStepsMatrixAndFractureRest = keywordDataItemCounts[i] % (activeCellInfo->globalActiveCellCount() + fractureActiveCellInfo->globalActiveCellCount()); + + if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS) { - if (timeStepCount == timeStepsMatrix || timeStepCount == timeStepsMatrixAndFracture) + if (timeStepsMatrixRest == 0 || timeStepsMatrixAndFractureRest == 0) + { + if (timeStepCount == timeStepsMatrix || timeStepCount == timeStepsMatrixAndFracture) + { + keywordsWithCorrectNumberOfDataItems.push_back(keywords[i]); + } + } + } + else + { + if (timeStepsMatrixAndFractureRest == 0 && timeStepCount == timeStepsMatrixAndFracture) { keywordsWithCorrectNumberOfDataItems.push_back(keywords[i]); } @@ -808,57 +960,87 @@ QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel(const QStringL } else { - if (timeStepsMatrixAndFractureRest == 0 && timeStepCount == timeStepsMatrixAndFracture) - { - keywordsWithCorrectNumberOfDataItems.push_back(keywords[i]); - } + keywordsWithCorrectNumberOfDataItems.push_back(keywords[i]); } } return keywordsWithCorrectNumberOfDataItems; } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RifReaderEclipseOutput::extractResultValuesBasedOnPorosityModel(PorosityModelResultType matrixOrFracture, std::vector* destinationResultValues, const std::vector& sourceResultValues) { - if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS) + RigActiveCellInfo* fracActCellInfo = m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS); + + + if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS && fracActCellInfo->globalActiveCellCount() == 0) { - if (m_mainGrid->globalFractureModelActiveCellCount() == 0) - { - destinationResultValues->insert(destinationResultValues->end(), sourceResultValues.begin(), sourceResultValues.end()); - } - else - { - size_t dataItemCount = 0; - size_t sourceStartPosition = 0; - - for (size_t i = 0; i < m_mainGrid->gridCount(); i++) - { - size_t matrixActiveCellCount = m_mainGrid->gridByIndex(i)->matrixModelActiveCellCount(); - size_t fractureActiveCellCount = m_mainGrid->gridByIndex(i)->matrixModelActiveCellCount(); - - destinationResultValues->insert(destinationResultValues->end(), sourceResultValues.begin() + sourceStartPosition, sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount); - - sourceStartPosition += (matrixActiveCellCount + fractureActiveCellCount); - } - } + destinationResultValues->insert(destinationResultValues->end(), sourceResultValues.begin(), sourceResultValues.end()); } else { + RigActiveCellInfo* actCellInfo = m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); + size_t dataItemCount = 0; size_t sourceStartPosition = 0; - for (size_t i = 0; i < m_mainGrid->gridCount(); i++) + for (size_t i = 0; i < m_eclipseCase->mainGrid()->gridCount(); i++) { - size_t matrixActiveCellCount = m_mainGrid->gridByIndex(i)->matrixModelActiveCellCount(); - size_t fractureActiveCellCount = m_mainGrid->gridByIndex(i)->matrixModelActiveCellCount(); + size_t matrixActiveCellCount = 0; + size_t fractureActiveCellCount = 0; + + actCellInfo->gridActiveCellCounts(i, matrixActiveCellCount); + fracActCellInfo->gridActiveCellCounts(i, fractureActiveCellCount); - destinationResultValues->insert(destinationResultValues->end(), sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount, sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount + fractureActiveCellCount); + if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS) + { + destinationResultValues->insert(destinationResultValues->end(), + sourceResultValues.begin() + sourceStartPosition, + sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount); + } + else + { + destinationResultValues->insert(destinationResultValues->end(), + sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount, + sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount + fractureActiveCellCount); + } sourceStartPosition += (matrixActiveCellCount + fractureActiveCellCount); } } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifReaderEclipseOutput::openInitFile() +{ + if (m_ecl_init_file) + { + return true; + } + + QString initFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_INIT_FILE); + if (initFileName.size() > 0) + { + m_ecl_init_file = ecl_file_open(initFileName.toAscii().data()); + if (m_ecl_init_file) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifReaderEclipseOutput::timeSteps() +{ + return m_timeSteps; +} + diff --git a/ApplicationCode/FileInterface/RifReaderEclipseOutput.h b/ApplicationCode/FileInterface/RifReaderEclipseOutput.h index 1b961feea1..cfd5f829ce 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseOutput.h +++ b/ApplicationCode/FileInterface/RifReaderEclipseOutput.h @@ -26,6 +26,7 @@ class RifEclipseOutputFileTools; class RifEclipseRestartDataAccess; class RigGridBase; class RigMainGrid; +class RigActiveCellInfo; typedef struct ecl_grid_struct ecl_grid_type; typedef struct ecl_file_struct ecl_file_type; @@ -42,36 +43,38 @@ public: RifReaderEclipseOutput(); virtual ~RifReaderEclipseOutput(); - bool open(const QString& fileName, RigReservoir* reservoir); + bool open(const QString& fileName, RigCaseData* eclipseCase); + virtual bool openAndReadActiveCellData(const QString& fileName, const std::vector& mainCaseTimeSteps, RigCaseData* eclipseCase); void close(); bool staticResult(const QString& result, PorosityModelResultType matrixOrFracture, std::vector* values); bool dynamicResult(const QString& result, PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector* values); - static bool transferGeometry(const ecl_grid_type* mainEclGrid, RigReservoir* reservoir); + static bool transferGeometry(const ecl_grid_type* mainEclGrid, RigCaseData* eclipseCase); private: - void ground(); - bool buildMetaData(RigReservoir* reservoir); - void readWellCells(RigReservoir* reservoir); + bool readActiveCellInfo(); + bool buildMetaData(); + void readWellCells(); + + bool openInitFile(); + bool openDynamicAccess(); void extractResultValuesBasedOnPorosityModel(PorosityModelResultType matrixOrFracture, std::vector* values, const std::vector& fileValues); - int findSmallestActiveCellIndexK( const RigGridBase* grid, int cellI, int cellJ); + RifEclipseRestartDataAccess* createDynamicResultsAccess(); - static RifEclipseRestartDataAccess* staticResultsAccess(const QStringList& fileSet); - static RifEclipseRestartDataAccess* dynamicResultsAccess(const QStringList& fileSet); - - QStringList validKeywordsForPorosityModel(const QStringList& keywords, const std::vector& keywordDataItemCounts, PorosityModelResultType matrixOrFracture, size_t timeStepCount) const; + QStringList validKeywordsForPorosityModel(const QStringList& keywords, const std::vector& keywordDataItemCounts, const RigActiveCellInfo* activeCellInfo, const RigActiveCellInfo* fractureActiveCellInfo, PorosityModelResultType matrixOrFracture, size_t timeStepCount) const; + virtual std::vector timeSteps(); private: QString m_fileName; // Name of file used to start accessing Eclipse output files - QStringList m_fileSet; // Set of files in filename's path with same base name as filename + QStringList m_filesWithSameBaseName; // Set of files in filename's path with same base name as filename - cvf::cref m_mainGrid; + RigCaseData* m_eclipseCase; - QList m_timeSteps; + std::vector m_timeSteps; - ecl_file_type* m_ecl_file; // File access to static results + ecl_file_type* m_ecl_init_file; // File access to static results cvf::ref m_dynamicResultsAccess; // File access to dynamic results }; diff --git a/ApplicationCode/FileInterface/RifReaderInterface.h b/ApplicationCode/FileInterface/RifReaderInterface.h index c03ddfd0f8..7b947f9468 100644 --- a/ApplicationCode/FileInterface/RifReaderInterface.h +++ b/ApplicationCode/FileInterface/RifReaderInterface.h @@ -24,9 +24,10 @@ #include #include +#include -class RigReservoir; +class RigCaseData; //================================================================================================== // @@ -46,10 +47,11 @@ public: RifReaderInterface() {} virtual ~RifReaderInterface() {} - virtual bool open(const QString& fileName, RigReservoir* reservoir) = 0; + virtual bool open(const QString& fileName, RigCaseData* eclipseCase) = 0; virtual void close() = 0; virtual bool staticResult(const QString& result, PorosityModelResultType matrixOrFracture, std::vector* values) = 0; virtual bool dynamicResult(const QString& result, PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector* values) = 0; -}; + virtual std::vector timeSteps() { std::vector timeSteps; return timeSteps; } +}; diff --git a/ApplicationCode/FileInterface/RifReaderMockModel.cpp b/ApplicationCode/FileInterface/RifReaderMockModel.cpp index 0cfb16c02d..f03a79e40f 100644 --- a/ApplicationCode/FileInterface/RifReaderMockModel.cpp +++ b/ApplicationCode/FileInterface/RifReaderMockModel.cpp @@ -16,25 +16,25 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RifReaderMockModel.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "RifReaderInterface.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifReaderMockModel::open(const QString& fileName, RigReservoir* reservoir) +bool RifReaderMockModel::open(const QString& fileName, RigCaseData* eclipseCase) { - m_reservoirBuilder.populateReservoir(reservoir); + m_reservoirBuilder.populateReservoir(eclipseCase); - m_reservoir = reservoir; + m_reservoir = eclipseCase; - RigReservoirCellResults* cellResults = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS); + RigCaseCellResultsData* cellResults = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS); - QList dates; + std::vector dates; for (int i = 0; i < static_cast(m_reservoirBuilder.timeStepCount()); i++) { @@ -43,13 +43,13 @@ bool RifReaderMockModel::open(const QString& fileName, RigReservoir* reservoir) for (size_t i = 0; i < m_reservoirBuilder.resultCount(); i++) { - size_t resIdx = cellResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, QString("Dynamic_Result_%1").arg(i)); + size_t resIdx = cellResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, QString("Dynamic_Result_%1").arg(i), false); cellResults->setTimeStepDates(resIdx, dates); } if (m_reservoirBuilder.timeStepCount() == 0) return true; - QList staticDates; + std::vector staticDates; staticDates.push_back(dates[0]); for (int i = 0; i < static_cast(m_reservoirBuilder.resultCount()); i++) { @@ -59,7 +59,7 @@ bool RifReaderMockModel::open(const QString& fileName, RigReservoir* reservoir) int resIndex = 0; if (i > 1) resIndex = i; - size_t resIdx = cellResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, QString("Static_Result_%1%2").arg(resIndex).arg(varEnd)); + size_t resIdx = cellResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, QString("Static_Result_%1%2").arg(resIndex).arg(varEnd), false); cellResults->setTimeStepDates(resIdx, staticDates); } @@ -68,7 +68,7 @@ bool RifReaderMockModel::open(const QString& fileName, RigReservoir* reservoir) { \ size_t resIdx; \ QString resultName(Name); \ - resIdx = cellResults->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, resultName); \ + resIdx = cellResults->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, resultName, false); \ cellResults->setTimeStepDates(resIdx, staticDates); \ cellResults->cellScalarResults(resIdx).resize(1); \ std::vector& values = cellResults->cellScalarResults(resIdx)[0]; \ @@ -96,7 +96,7 @@ void RifReaderMockModel::close() //-------------------------------------------------------------------------------------------------- bool RifReaderMockModel::inputProperty(const QString& propertyName, std::vector* values) { - return m_reservoirBuilder.inputProperty(m_reservoir.p(), propertyName, values); + return m_reservoirBuilder.inputProperty(m_reservoir, propertyName, values); } //-------------------------------------------------------------------------------------------------- @@ -104,7 +104,7 @@ bool RifReaderMockModel::inputProperty(const QString& propertyName, std::vector< //-------------------------------------------------------------------------------------------------- bool RifReaderMockModel::staticResult(const QString& result, RifReaderInterface::PorosityModelResultType matrixOrFracture, std::vector* values) { - m_reservoirBuilder.staticResult(m_reservoir.p(), result, values); + m_reservoirBuilder.staticResult(m_reservoir, result, values); return true; } @@ -114,7 +114,7 @@ bool RifReaderMockModel::staticResult(const QString& result, RifReaderInterface: //-------------------------------------------------------------------------------------------------- bool RifReaderMockModel::dynamicResult(const QString& result, RifReaderInterface::PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector* values) { - m_reservoirBuilder.dynamicResult(m_reservoir.p(), result, stepIndex, values); + m_reservoirBuilder.dynamicResult(m_reservoir, result, stepIndex, values); return true; } @@ -170,8 +170,8 @@ void RifReaderMockModel::addLocalGridRefinement(const cvf::Vec3st& minCellPositi //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifReaderMockModel::populateReservoir(RigReservoir* reservoir) +void RifReaderMockModel::populateReservoir(RigCaseData* eclipseCase) { - m_reservoirBuilder.populateReservoir(reservoir); + m_reservoirBuilder.populateReservoir(eclipseCase); } diff --git a/ApplicationCode/FileInterface/RifReaderMockModel.h b/ApplicationCode/FileInterface/RifReaderMockModel.h index 73e1260f66..0237381bbe 100644 --- a/ApplicationCode/FileInterface/RifReaderMockModel.h +++ b/ApplicationCode/FileInterface/RifReaderMockModel.h @@ -33,17 +33,17 @@ public: void addLocalGridRefinement(const cvf::Vec3st& minCellPosition, const cvf::Vec3st& maxCellPosition, const cvf::Vec3st& singleCellRefinementFactors); - virtual bool open( const QString& fileName, RigReservoir* reservoir ); + virtual bool open( const QString& fileName, RigCaseData* eclipseCase ); virtual void close(); virtual bool staticResult( const QString& result, RifReaderInterface::PorosityModelResultType matrixOrFracture, std::vector* values ); virtual bool dynamicResult( const QString& result, RifReaderInterface::PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector* values ); private: - void populateReservoir(RigReservoir* reservoir); + void populateReservoir(RigCaseData* eclipseCase); bool inputProperty( const QString& propertyName, std::vector* values ); RigReservoirBuilderMock m_reservoirBuilder; - cvf::ref m_reservoir; + RigCaseData* m_reservoir; }; diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp index e05c0b0e8c..1973d147c8 100644 --- a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RivCellEdgeEffectGenerator.h" @@ -33,20 +33,27 @@ #include "cvfShaderProgram.h" #include "cvfRenderStateCullFace.h" -#include -#include -#include - -#include "RimReservoirView.h" -#include "RigGridBase.h" -#include "RigMainGrid.h" -#include "RigReservoirCellResults.h" #include "cvfTextureImage.h" #include "cvfTexture.h" #include "cvfSampler.h" #include "cvfScalarMapper.h" #include "cafEffectGenerator.h" +#include + +#include +#include + +#include "RimReservoirView.h" +#include "RimResultSlot.h" + +#include "RigGridBase.h" +#include "RigMainGrid.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigActiveCellInfo.h" + + //-------------------------------------------------------------------------------------------------- /// @@ -87,12 +94,12 @@ void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo( cvf::ScalarMapper* edgeResultScalarMapper = cellEdgeResultSlot->legendConfig()->scalarMapper(); const RigGridBase* grid = dynamic_cast(generator->activeGrid()); - CVF_ASSERT(grid != NULL); - bool cellScalarResultUseGlobalActiveIndex = true; - bool edgeScalarResultUseGlobalActiveIndex[6]; + RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); + CVF_ASSERT(eclipseCase != NULL); + cvf::ref cellCenterDataAccessObject = NULL; if (cellResultSlot->hasResult()) { if (!cellResultSlot->hasDynamicResult()) @@ -101,23 +108,30 @@ void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo( timeStepIndex = 0; } - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); - cellScalarResultUseGlobalActiveIndex = grid->mainGrid()->results(porosityModel)->isUsingGlobalActiveIndex(cellResultSlot->gridScalarIndex()); + 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); - if (cellEdgeResultSlot->hasResult()) + cvf::Collection cellEdgeDataAccessObjects; + + size_t cubeFaceIdx; + for (cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) { - size_t cubeFaceIdx; - for (cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) + cvf::ref daObj; + + if (resultIndices[cubeFaceIdx] != cvf::UNDEFINED_SIZE_T) { - if (resultIndices[cubeFaceIdx] != cvf::UNDEFINED_SIZE_T) - { - edgeScalarResultUseGlobalActiveIndex[cubeFaceIdx] = grid->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->isUsingGlobalActiveIndex(resultIndices[cubeFaceIdx]); - } + // 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(); @@ -138,15 +152,14 @@ void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo( float cellColorTextureCoord = 0.5f; // If no results exists, the texture will have a special color size_t cellIndex = quadToCell[quadIdx]; - size_t resultValueIndex = cellIndex; - if (cellScalarResultUseGlobalActiveIndex) { - resultValueIndex = grid->cell(cellIndex).activeIndexInMatrixModel(); - } + double scalarValue = HUGE_VAL; + + if (cellCenterDataAccessObject.notNull()) + { + scalarValue = cellCenterDataAccessObject->cellScalar(cellIndex); + } - { - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); - double scalarValue = grid->mainGrid()->results(porosityModel)->cellScalarResult(timeStepIndex, cellResultSlot->gridScalarIndex(), resultValueIndex); if (scalarValue != HUGE_VAL) { cellColorTextureCoord = cellResultScalarMapper->mapToTextureCoord(scalarValue)[0]; @@ -168,14 +181,12 @@ void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo( { edgeColor = -1.0f; // Undefined texture coord. Shader handles this. - resultValueIndex = cellIndex; - if (edgeScalarResultUseGlobalActiveIndex[cubeFaceIdx]) + double scalarValue = HUGE_VAL; + if (cellEdgeDataAccessObjects[cubeFaceIdx].notNull()) { - resultValueIndex = grid->cell(cellIndex).activeIndexInMatrixModel(); + scalarValue = cellEdgeDataAccessObjects[cubeFaceIdx]->cellScalar(cellIndex); } - // Assuming static values to be mapped onto cell edge, always using time step zero - double scalarValue = grid->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResult(0, resultIndices[cubeFaceIdx], resultValueIndex); if (scalarValue != HUGE_VAL && scalarValue != ignoredScalarValue) { edgeColor = edgeResultScalarMapper->mapToTextureCoord(scalarValue)[0]; diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index b27f38c339..99a58f3382 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RivGridPartMgr.h" #include "cvfPart.h" #include "cafEffectGenerator.h" @@ -28,7 +28,10 @@ #include "RimResultSlot.h" #include "RimCellEdgeResultSlot.h" #include "RigGridScalarDataAccess.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RiaApplication.h" +#include "RiaPreferences.h" //-------------------------------------------------------------------------------------------------- @@ -143,10 +146,12 @@ void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoB part->setTransform(m_scaleTransform.p()); part->updateBoundingBox(); + RiaPreferences* prefs = RiaApplication::instance()->preferences(); + cvf::ref eff; if (faultGeometry) { - caf::MeshEffectGenerator effGen(cvf::Color3f::BLACK); + caf::MeshEffectGenerator effGen(prefs->defaultFaultGridLineColors()); eff = effGen.generateEffect(); part->setEnableMask(meshFaultBit); @@ -155,7 +160,7 @@ void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoB } else { - caf::MeshEffectGenerator effGen(cvf::Color3f::WHITE); + caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); eff = effGen.generateEffect(); // Set priority to make sure fault lines are rendered first @@ -204,6 +209,23 @@ void RivGridPartMgr::updateCellColor(cvf::Color4f color) m_opacityLevel = color.a(); m_defaultColor = color.toColor3f(); + + // Update mesh colors as well, in case of change + 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()); + eff = effGen.generateEffect(); + m_surfaceGridLines->setEffect(eff.p()); + } } //-------------------------------------------------------------------------------------------------- @@ -220,8 +242,11 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* size_t resTimeStepIdx = timeStepIndex; if (cellResultSlot->hasStaticResult()) resTimeStepIdx = 0; - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); - cvf::ref dataAccessObject = m_grid->dataAccessObject(porosityModel, resTimeStepIdx, scalarSetIndex); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); + + RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); + cvf::ref dataAccessObject = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, scalarSetIndex); + if (dataAccessObject.isNull()) return; // Outer surface diff --git a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp index e7562e8b05..c96ad5d33e 100644 --- a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp @@ -83,6 +83,7 @@ void RivPipeGeometryGenerator::setBendScalingFactor(double scaleFactor) //-------------------------------------------------------------------------------------------------- void RivPipeGeometryGenerator::setRadius(double radius) { + CVF_ASSERT(0 <= radius && radius < 1e100); m_radius = radius; clearComputedData(); @@ -93,6 +94,7 @@ void RivPipeGeometryGenerator::setRadius(double radius) //-------------------------------------------------------------------------------------------------- void RivPipeGeometryGenerator::setCrossSectionVertexCount(size_t nodeCount) { + CVF_ASSERT( 2 < nodeCount && nodeCount < 1000000); m_crossSectionNodeCount = nodeCount; clearComputedData(); diff --git a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp index 369f3279f0..c51ec3c230 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp @@ -16,23 +16,23 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RivReservoirPartMgr.h" #include "RivGridPartMgr.h" #include "cvfStructGrid.h" #include "cvfModelBasicList.h" -#include "RigReservoir.h" +#include "RigCaseData.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivReservoirPartMgr::clearAndSetReservoir(const RigReservoir* reservoir) +void RivReservoirPartMgr::clearAndSetReservoir(const RigCaseData* eclipseCase) { m_allGrids.clear(); - if (reservoir) + if (eclipseCase) { std::vector grids; - reservoir->allGrids(&grids); + eclipseCase->allGrids(&grids); for (size_t i = 0; i < grids.size() ; ++i) { m_allGrids.push_back(new RivGridPartMgr(grids[i], i) ); diff --git a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h index 7ae4eb5b57..58d4dc08f6 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h @@ -30,7 +30,7 @@ namespace cvf class RimResultSlot; class RimCellEdgeResultSlot; class RivGridPartMgr; -class RigReservoir; +class RigCaseData; //================================================================================================== @@ -43,7 +43,7 @@ class RigReservoir; class RivReservoirPartMgr: public cvf::Object { public: - void clearAndSetReservoir(const RigReservoir* reservoir); + void clearAndSetReservoir(const RigCaseData* eclipseCase); void setTransform(cvf::Transform* scaleTransform); void setCellVisibility(size_t gridIndex, cvf::UByteArray* cellVisibilities ); diff --git a/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp index 4767910b98..f54d82e035 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RivReservoirPipesPartMgr.h" #include "RimReservoirView.h" @@ -33,6 +33,8 @@ RivReservoirPipesPartMgr::RivReservoirPipesPartMgr(RimReservoirView* reservoirVi m_reservoirView = reservoirView; m_scaleTransform = new cvf::Transform(); + + m_font = new cvf::FixedAtlasFont(cvf::FixedAtlasFont::LARGE); } //-------------------------------------------------------------------------------------------------- @@ -46,42 +48,25 @@ RivReservoirPipesPartMgr::~RivReservoirPipesPartMgr() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivReservoirPipesPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex) +void RivReservoirPipesPartMgr::clearGeometryCache() { - if (m_reservoirView->wellCollection()->wellPipeVisibility() == RimWellCollection::FORCE_ALL_OFF) return; - - if (m_reservoirView->wellCollection()->wells.size() != m_wellPipesPartMgrs.size()) - { - m_wellPipesPartMgrs.clear(); - m_wellHeadPartMgrs.clear(); - - for (size_t i = 0; i < m_reservoirView->wellCollection()->wells.size(); ++i) - { - RivWellPipesPartMgr * wppmgr = new RivWellPipesPartMgr(m_reservoirView, m_reservoirView->wellCollection()->wells[i]); - m_wellPipesPartMgrs.push_back(wppmgr); - wppmgr->setScaleTransform(m_scaleTransform.p()); - - RivWellHeadPartMgr* wellHeadMgr = new RivWellHeadPartMgr(m_reservoirView, m_reservoirView->wellCollection()->wells[i]); - m_wellHeadPartMgrs.push_back(wellHeadMgr); - wellHeadMgr->setScaleTransform(m_scaleTransform.p()); - } - } - - for (size_t wIdx = 0; wIdx != m_wellPipesPartMgrs.size(); ++ wIdx) - { - m_wellPipesPartMgrs[wIdx]->appendDynamicGeometryPartsToModel(model, frameIndex); - m_wellHeadPartMgrs[wIdx]->appendDynamicGeometryPartsToModel(model, frameIndex); - } + m_wellPipesPartMgrs.clear(); + m_wellHeadPartMgrs.clear(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivReservoirPipesPartMgr::updatePipeResultColor(size_t frameIndex) +void RivReservoirPipesPartMgr::scheduleGeometryRegen() { for (size_t wIdx = 0; wIdx != m_wellPipesPartMgrs.size(); ++ wIdx) { - m_wellPipesPartMgrs[wIdx]->updatePipeResultColor( frameIndex); + m_wellPipesPartMgrs[wIdx]->scheduleGeometryRegen(); + } + + for (size_t wIdx = 0; wIdx != m_wellHeadPartMgrs.size(); ++ wIdx) + { + //m_wellHeadPartMgrs[wIdx]->scheduleGeometryRegen(scaleTransform); } } @@ -103,15 +88,44 @@ void RivReservoirPipesPartMgr::setScaleTransform(cvf::Transform * scaleTransform } } -void RivReservoirPipesPartMgr::scheduleGeometryRegen() +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivReservoirPipesPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex) +{ + if (m_reservoirView->wellCollection()->wellPipeVisibility() == RimWellCollection::FORCE_ALL_OFF) return; + + if (m_reservoirView->wellCollection()->wells.size() != m_wellPipesPartMgrs.size()) + { + clearGeometryCache(); + + for (size_t i = 0; i < m_reservoirView->wellCollection()->wells.size(); ++i) + { + RivWellPipesPartMgr * wppmgr = new RivWellPipesPartMgr(m_reservoirView, m_reservoirView->wellCollection()->wells[i]); + m_wellPipesPartMgrs.push_back(wppmgr); + wppmgr->setScaleTransform(m_scaleTransform.p()); + + RivWellHeadPartMgr* wellHeadMgr = new RivWellHeadPartMgr(m_reservoirView, m_reservoirView->wellCollection()->wells[i], m_font.p()); + m_wellHeadPartMgrs.push_back(wellHeadMgr); + wellHeadMgr->setScaleTransform(m_scaleTransform.p()); + } + } + + for (size_t wIdx = 0; wIdx != m_wellPipesPartMgrs.size(); ++ wIdx) + { + m_wellPipesPartMgrs[wIdx]->appendDynamicGeometryPartsToModel(model, frameIndex); + m_wellHeadPartMgrs[wIdx]->appendDynamicGeometryPartsToModel(model, frameIndex); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivReservoirPipesPartMgr::updatePipeResultColor(size_t frameIndex) { for (size_t wIdx = 0; wIdx != m_wellPipesPartMgrs.size(); ++ wIdx) { - m_wellPipesPartMgrs[wIdx]->scheduleGeometryRegen(); - } - - for (size_t wIdx = 0; wIdx != m_wellHeadPartMgrs.size(); ++ wIdx) - { - //m_wellHeadPartMgrs[wIdx]->scheduleGeometryRegen(scaleTransform); + m_wellPipesPartMgrs[wIdx]->updatePipeResultColor( frameIndex); } } + diff --git a/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.h index ce6209af96..7d830a503d 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.h @@ -33,15 +33,18 @@ public: RivReservoirPipesPartMgr(RimReservoirView* reservoirView); ~RivReservoirPipesPartMgr(); - void setScaleTransform(cvf::Transform * scaleTransform); + void clearGeometryCache(); void scheduleGeometryRegen(); + void setScaleTransform(cvf::Transform * scaleTransform); + void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex); void updatePipeResultColor(size_t frameIndex); private: caf::PdmPointer m_reservoirView; cvf::ref m_scaleTransform; + cvf::ref m_font; cvf::Collection< RivWellPipesPartMgr > m_wellPipesPartMgrs; cvf::Collection< RivWellHeadPartMgr > m_wellHeadPartMgrs; diff --git a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp index a9d1817e16..7f81bee176 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp @@ -16,13 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RivReservoirViewPartMgr.h" #include "RivGridPartMgr.h" #include "RimReservoirView.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "RigGridBase.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "RigGridScalarDataAccess.h" //-------------------------------------------------------------------------------------------------- @@ -125,10 +125,10 @@ void RivReservoirViewPartMgr::scheduleGeometryRegen(ReservoirGeometryCacheType g //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geomType) { - RigReservoir* reservoir = NULL; + RigCaseData* eclipseCase = NULL; if (m_reservoirView != NULL && m_reservoirView->eclipseCase()) { - reservoir = m_reservoirView->eclipseCase()->reservoirData(); + eclipseCase = m_reservoirView->eclipseCase()->reservoirData(); } if (geomType == PROPERTY_FILTERED) @@ -138,7 +138,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geom m_propFilteredGeometryFramesNeedsRegen[i] = true; if (m_propFilteredGeometryFrames[i].notNull()) { - m_propFilteredGeometryFrames[i]->clearAndSetReservoir(reservoir); + m_propFilteredGeometryFrames[i]->clearAndSetReservoir(eclipseCase); m_propFilteredGeometryFrames[i]->setTransform(m_scaleTransform.p()); } } @@ -150,7 +150,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geom m_propFilteredWellGeometryFramesNeedsRegen[i] = true; if (m_propFilteredWellGeometryFrames[i].notNull()) { - m_propFilteredWellGeometryFrames[i]->clearAndSetReservoir(reservoir); + m_propFilteredWellGeometryFrames[i]->clearAndSetReservoir(eclipseCase); m_propFilteredWellGeometryFrames[i]->setTransform(m_scaleTransform.p()); } } @@ -158,7 +158,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geom else { m_geometriesNeedsRegen[geomType] = true; - m_geometries[geomType].clearAndSetReservoir(reservoir); + m_geometries[geomType].clearAndSetReservoir(eclipseCase); m_geometries[geomType].setTransform(m_scaleTransform.p()); } } @@ -224,7 +224,7 @@ void RivReservoirViewPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicL //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::createGeometry(ReservoirGeometryCacheType geometryType) { - RigReservoir* res = m_reservoirView->eclipseCase()->reservoirData(); + RigCaseData* res = m_reservoirView->eclipseCase()->reservoirData(); m_geometries[geometryType].clearAndSetReservoir(res); m_geometries[geometryType].setTransform(m_scaleTransform.p()); std::vector grids; @@ -246,13 +246,16 @@ void RivReservoirViewPartMgr::createGeometry(ReservoirGeometryCacheType geometry //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::computeVisibility(cvf::UByteArray* cellVisibility, ReservoirGeometryCacheType geometryType, RigGridBase* grid, size_t gridIdx) { + RigCaseData* eclipseCase = m_reservoirView->eclipseCase()->reservoirData(); + RigActiveCellInfo* activeCellInfo = m_reservoirView->currentActiveCellInfo(); + switch (geometryType) { case ACTIVE: - computeNativeVisibility(cellVisibility, grid, false, false, true, m_reservoirView->showMainGrid() ); + computeNativeVisibility(cellVisibility, grid, activeCellInfo, eclipseCase->wellCellsInGrid(gridIdx), false, false, true, m_reservoirView->showMainGrid() ); break; case ALL_WELL_CELLS: - computeAllWellCellsVisibility(cellVisibility, grid); + copyByteArray(cellVisibility, eclipseCase->wellCellsInGrid(gridIdx)); break; case VISIBLE_WELL_CELLS: { @@ -287,7 +290,7 @@ void RivReservoirViewPartMgr::computeVisibility(cvf::UByteArray* cellVisibility, } break; case INACTIVE: - computeNativeVisibility(cellVisibility, grid, m_reservoirView->showInvalidCells(), true, false, m_reservoirView->showMainGrid()); + computeNativeVisibility(cellVisibility, grid, activeCellInfo, eclipseCase->wellCellsInGrid(gridIdx), m_reservoirView->showInvalidCells(), true, false, m_reservoirView->showMainGrid()); break; case RANGE_FILTERED: { @@ -367,7 +370,7 @@ void RivReservoirViewPartMgr::computeVisibility(cvf::UByteArray* cellVisibility, //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::createPropertyFilteredGeometry(size_t frameIndex) { - RigReservoir* res = m_reservoirView->eclipseCase()->reservoirData(); + RigCaseData* res = m_reservoirView->eclipseCase()->reservoirData(); if ( frameIndex >= m_propFilteredGeometryFrames.size()) { @@ -382,28 +385,29 @@ void RivReservoirViewPartMgr::createPropertyFilteredGeometry(size_t frameIndex) bool hasActiveRangeFilters = m_reservoirView->rangeFilterCollection()->hasActiveFilters() || m_reservoirView->wellCollection()->hasVisibleWellCells(); - for (size_t i = 0; i < grids.size(); ++i) + for (size_t gIdx = 0; gIdx < grids.size(); ++gIdx) { - cvf::ref cellVisibility = m_propFilteredGeometryFrames[frameIndex]->cellVisibility(i); + cvf::ref cellVisibility = m_propFilteredGeometryFrames[frameIndex]->cellVisibility(gIdx); cvf::ref rangeVisibility; cvf::ref fenceVisibility; + cvf::cref cellIsWellCellStatuses = res->wellCellsInGrid(gIdx); if (m_geometriesNeedsRegen[RANGE_FILTERED]) createGeometry(RANGE_FILTERED); if (m_geometriesNeedsRegen[VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER]) createGeometry(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER); - rangeVisibility = m_geometries[RANGE_FILTERED].cellVisibility(i); - fenceVisibility = m_geometries[VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility(i); + rangeVisibility = m_geometries[RANGE_FILTERED].cellVisibility(gIdx); + fenceVisibility = m_geometries[VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility(gIdx); cellVisibility->resize(rangeVisibility->size()); #pragma omp parallel for for (int cellIdx = 0; cellIdx < static_cast(cellVisibility->size()); ++cellIdx) { - (*cellVisibility)[cellIdx] = (!hasActiveRangeFilters && !grids[i]->cell(cellIdx).isWellCell()) || (*rangeVisibility)[cellIdx] || (*fenceVisibility)[cellIdx]; + (*cellVisibility)[cellIdx] = (!hasActiveRangeFilters && !(*cellIsWellCellStatuses)[cellIdx]) || (*rangeVisibility)[cellIdx] || (*fenceVisibility)[cellIdx]; } - computePropertyVisibility(cellVisibility.p(), grids[i], frameIndex, cellVisibility.p(), m_reservoirView->propertyFilterCollection()); + computePropertyVisibility(cellVisibility.p(), grids[gIdx], frameIndex, cellVisibility.p(), m_reservoirView->propertyFilterCollection()); - m_propFilteredGeometryFrames[frameIndex]->setCellVisibility(i, cellVisibility.p()); + m_propFilteredGeometryFrames[frameIndex]->setCellVisibility(gIdx, cellVisibility.p()); } m_propFilteredGeometryFramesNeedsRegen[frameIndex] = false; @@ -414,7 +418,7 @@ void RivReservoirViewPartMgr::createPropertyFilteredGeometry(size_t frameIndex) //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::createPropertyFilteredWellGeometry(size_t frameIndex) { - RigReservoir* res = m_reservoirView->eclipseCase()->reservoirData(); + RigCaseData* res = m_reservoirView->eclipseCase()->reservoirData(); if ( frameIndex >= m_propFilteredWellGeometryFrames.size()) { @@ -432,26 +436,28 @@ void RivReservoirViewPartMgr::createPropertyFilteredWellGeometry(size_t frameInd bool hasActiveRangeFilters = m_reservoirView->rangeFilterCollection()->hasActiveFilters() || m_reservoirView->wellCollection()->hasVisibleWellCells(); - for (size_t i = 0; i < grids.size(); ++i) + for (size_t gIdx = 0; gIdx < grids.size(); ++gIdx) { - cvf::ref cellVisibility = m_propFilteredWellGeometryFrames[frameIndex]->cellVisibility(i); + cvf::ref cellVisibility = m_propFilteredWellGeometryFrames[frameIndex]->cellVisibility(gIdx); cvf::ref rangeVisibility; cvf::ref wellCellsOutsideVisibility; + cvf::cref cellIsWellCellStatuses = res->wellCellsInGrid(gIdx); + if (m_geometriesNeedsRegen[RANGE_FILTERED_WELL_CELLS]) createGeometry(RANGE_FILTERED_WELL_CELLS); - rangeVisibility = m_geometries[RANGE_FILTERED_WELL_CELLS].cellVisibility(i); + rangeVisibility = m_geometries[RANGE_FILTERED_WELL_CELLS].cellVisibility(gIdx); if (m_geometriesNeedsRegen[VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER]) createGeometry(VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER); - wellCellsOutsideVisibility = m_geometries[VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility(i); + wellCellsOutsideVisibility = m_geometries[VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility(gIdx); cellVisibility->resize(rangeVisibility->size()); #pragma omp parallel for for (int cellIdx = 0; cellIdx < static_cast(cellVisibility->size()); ++cellIdx) { - (*cellVisibility)[cellIdx] = (!hasActiveRangeFilters && grids[i]->cell(cellIdx).isWellCell()) || (*rangeVisibility)[cellIdx] || (*wellCellsOutsideVisibility)[cellIdx]; + (*cellVisibility)[cellIdx] = (!hasActiveRangeFilters && (*cellIsWellCellStatuses)[cellIdx]) || (*rangeVisibility)[cellIdx] || (*wellCellsOutsideVisibility)[cellIdx]; } - computePropertyVisibility(cellVisibility.p(), grids[i], frameIndex, cellVisibility.p(), m_reservoirView->propertyFilterCollection()); - m_propFilteredWellGeometryFrames[frameIndex]->setCellVisibility(i, cellVisibility.p()); + computePropertyVisibility(cellVisibility.p(), grids[gIdx], frameIndex, cellVisibility.p(), m_reservoirView->propertyFilterCollection()); + m_propFilteredWellGeometryFrames[frameIndex]->setCellVisibility(gIdx, cellVisibility.p()); } m_propFilteredWellGeometryFramesNeedsRegen[frameIndex] = false; @@ -460,7 +466,7 @@ void RivReservoirViewPartMgr::createPropertyFilteredWellGeometry(size_t frameInd //-------------------------------------------------------------------------------------------------- /// Evaluate visibility based on cell state //-------------------------------------------------------------------------------------------------- -void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid, +void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid, const RigActiveCellInfo* activeCellInfo, const cvf::UByteArray* cellIsInWellStatuses, bool invalidCellsIsVisible, bool inactiveCellsIsVisible, bool activeCellsIsVisible, @@ -468,18 +474,23 @@ void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisib { CVF_ASSERT(cellVisibility != NULL); CVF_ASSERT(grid != NULL); + CVF_ASSERT(activeCellInfo != NULL); + CVF_ASSERT(cellIsInWellStatuses != NULL); + CVF_ASSERT(cellIsInWellStatuses->size() >= grid->cellCount()); + cellVisibility->resize(grid->cellCount()); #pragma omp parallel for for (int cellIndex = 0; cellIndex < static_cast(grid->cellCount()); cellIndex++) { const RigCell& cell = grid->cell(cellIndex); + size_t globalCellIndex = cell.mainGridCellIndex(); if ( !invalidCellsIsVisible && cell.isInvalid() - || !inactiveCellsIsVisible && !cell.isActiveInMatrixModel() - || !activeCellsIsVisible && cell.isActiveInMatrixModel() + || !inactiveCellsIsVisible && !activeCellInfo->isActive(globalCellIndex) + || !activeCellsIsVisible && activeCellInfo->isActive(globalCellIndex) || mainGridIsVisible && (cell.subGrid() != NULL) - || cell.isWellCell() + || (*cellIsInWellStatuses)[cellIndex] ) { (*cellVisibility)[cellIndex] = false; @@ -493,27 +504,23 @@ void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisib //-------------------------------------------------------------------------------------------------- -/// Evaluate Well cell visibility based on cell state +/// Copy the data from source into destination. This is not trivial to do using cvf::Array ... +/// using parallelized operator [] and not memcopy. Do not know what is faster. //-------------------------------------------------------------------------------------------------- -void RivReservoirViewPartMgr::computeAllWellCellsVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid ) +void RivReservoirViewPartMgr::copyByteArray(cvf::UByteArray* destination, const cvf::UByteArray* source ) { - CVF_ASSERT(cellVisibility != NULL); - CVF_ASSERT(grid != NULL); - cellVisibility->resize(grid->cellCount()); + CVF_ASSERT(destination != NULL); + CVF_ASSERT(source != NULL); + + if (destination->size() != source->size()) + { + destination->resize(source->size()); + } #pragma omp parallel for - for (int cellIndex = 0; cellIndex < static_cast(grid->cellCount()); cellIndex++) + for (int cellIndex = 0; cellIndex < static_cast(source->size()); cellIndex++) { - const RigCell& cell = grid->cell(cellIndex); - - if ( cell.isWellCell() ) - { - (*cellVisibility)[cellIndex] = true; - } - else - { - (*cellVisibility)[cellIndex] = false; - } + (*destination)[cellIndex] = (*source)[cellIndex]; } } @@ -599,8 +606,10 @@ void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVis const RimCellFilter::FilterModeType filterType = (*pfIt)->filterMode(); - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel((*pfIt)->resultDefinition()->porosityModel()); - cvf::ref dataAccessObject = grid->dataAccessObject(porosityModel, timeStepIndex, scalarResultIndex); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel((*pfIt)->resultDefinition()->porosityModel()); + RigCaseData* eclipseCase = propFilterColl->reservoirView()->eclipseCase()->reservoirData(); + + cvf::ref dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, scalarResultIndex); CVF_ASSERT(dataAccessObject.notNull()); #pragma omp parallel for schedule(dynamic) diff --git a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h index 286e2c4a45..fb4bb6420b 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h @@ -28,6 +28,7 @@ class RimReservoirView; class RigGridBase; class RimCellRangeFilterCollection; class RimCellPropertyFilterCollection; +class RigActiveCellInfo; class RivReservoirViewPartMgr: public cvf::Object { @@ -77,10 +78,10 @@ private: void clearGeometryCache(ReservoirGeometryCacheType geomType); - static void computeNativeVisibility (cvf::UByteArray* cellVisibility, const RigGridBase* grid, bool invalidCellsIsVisible, bool inactiveCellsIsVisible, bool activeCellsIsVisible, bool mainGridIsVisible); - static void computeRangeVisibility (cvf::UByteArray* cellVisibility, const RigGridBase* grid, const cvf::UByteArray* nativeVisibility, const RimCellRangeFilterCollection* rangeFilterColl); - static void computePropertyVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid, size_t timeStepIndex, const cvf::UByteArray* rangeFilterVisibility, RimCellPropertyFilterCollection* propFilterColl); - static void computeAllWellCellsVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid ); + static void computeNativeVisibility (cvf::UByteArray* cellVisibilities, const RigGridBase* grid, const RigActiveCellInfo* activeCellInfo, const cvf::UByteArray* cellIsInWellStatuses, bool invalidCellsIsVisible, bool inactiveCellsIsVisible, bool activeCellsIsVisible, bool mainGridIsVisible); + static void computeRangeVisibility (cvf::UByteArray* cellVisibilities, const RigGridBase* grid, const cvf::UByteArray* nativeVisibility, const RimCellRangeFilterCollection* rangeFilterColl); + static void computePropertyVisibility(cvf::UByteArray* cellVisibilities, const RigGridBase* grid, size_t timeStepIndex, const cvf::UByteArray* rangeFilterVisibility, RimCellPropertyFilterCollection* propFilterColl); + static void copyByteArray(cvf::UByteArray* cellVisibilities, const cvf::UByteArray* cellIsWellStatuses ); private: diff --git a/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp index 8eba80f828..8933231fa3 100644 --- a/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp @@ -36,7 +36,7 @@ #include "RimReservoirView.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "RigCell.h" #include "RivPipeGeometryGenerator.h" @@ -46,12 +46,12 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RivWellHeadPartMgr::RivWellHeadPartMgr(RimReservoirView* reservoirView, RimWell* well) +RivWellHeadPartMgr::RivWellHeadPartMgr(RimReservoirView* reservoirView, RimWell* well, cvf::Font* font) { m_rimReservoirView = reservoirView; m_rimWell = well; - m_font = new cvf::FixedAtlasFont(cvf::FixedAtlasFont::LARGE); + m_font = font; } //-------------------------------------------------------------------------------------------------- @@ -72,11 +72,11 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex) if (m_rimReservoirView.isNull()) return; - RigReservoir* rigReservoir = m_rimReservoirView->eclipseCase()->reservoirData(); + RigCaseData* rigReservoir = m_rimReservoirView->eclipseCase()->reservoirData(); RimWell* well = m_rimWell; - RigWellResults* wellResults = well->wellResults(); + RigSingleWellResultsData* wellResults = well->wellResults(); if (wellResults->m_staticWellCells.m_wellResultBranches.size() == 0) { @@ -90,7 +90,7 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex) const RigCell& whCell = rigReservoir->cellFromWellResultCell(wellResultFrame.m_wellHead); - double characteristicCellSize = rigReservoir->mainGrid()->characteristicCellSize(); + double characteristicCellSize = rigReservoir->mainGrid()->characteristicIJCellSize(); // Match this position with pipe start position in RivWellPipesPartMgr::calculateWellPipeCenterline() cvf::Vec3d whStartPos = whCell.faceCenter(cvf::StructGridInterface::NEG_K); @@ -232,6 +232,8 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex) if (m_rimReservoirView->wellCollection()->showWellLabel() && well->showWellLabel()) { + CVF_ASSERT(m_font.p()); + cvf::ref drawableText = new cvf::DrawableText; drawableText->setFont(m_font.p()); drawableText->setCheckPosVisible(false); diff --git a/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.h b/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.h index 8a593e45df..9ef0bf0d40 100644 --- a/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.h @@ -38,7 +38,7 @@ class RimReservoirView; class RivWellHeadPartMgr : public cvf::Object { public: - RivWellHeadPartMgr(RimReservoirView* reservoirView, RimWell* well); + RivWellHeadPartMgr(RimReservoirView* reservoirView, RimWell* well, cvf::Font* font); ~RivWellHeadPartMgr(); void setScaleTransform(cvf::Transform * scaleTransform) { m_scaleTransform = scaleTransform;} diff --git a/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp index 46929737c8..7d82f2f717 100644 --- a/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp @@ -19,8 +19,8 @@ #include "cvfLibCore.h" -#include "RimReservoir.h" -#include "RigReservoir.h" +#include "RimCase.h" +#include "RigCaseData.h" #include "RivWellPipesPartMgr.h" #include "RigCell.h" #include "RivPipeGeometryGenerator.h" @@ -86,7 +86,7 @@ void RivWellPipesPartMgr::buildWellPipeParts() calculateWellPipeCenterline(pipeBranchesCLCoords, pipeBranchesCellIds); - double characteristicCellSize = m_rimReservoirView->eclipseCase()->reservoirData()->mainGrid()->characteristicCellSize(); + double characteristicCellSize = m_rimReservoirView->eclipseCase()->reservoirData()->mainGrid()->characteristicIJCellSize(); double pipeRadius = m_rimReservoirView->wellCollection()->pipeRadiusScaleFactor() *m_rimWell->pipeRadiusScaleFactor() * characteristicCellSize; for (size_t brIdx = 0; brIdx < pipeBranchesCellIds.size(); ++brIdx) @@ -158,8 +158,8 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector bool isAutoDetectBranches = m_rimReservoirView->wellCollection()->isAutoDetectingBranches(); - RigReservoir* rigReservoir = m_rimReservoirView->eclipseCase()->reservoirData(); - RigWellResults* wellResults = m_rimWell->wellResults(); + RigCaseData* rigReservoir = m_rimReservoirView->eclipseCase()->reservoirData(); + RigSingleWellResultsData* wellResults = m_rimWell->wellResults(); const RigWellResultFrame& staticWellFrame = m_rimWell->wellResults()->m_staticWellCells; @@ -357,7 +357,7 @@ void RivWellPipesPartMgr::updatePipeResultColor(size_t frameIndex) { if (m_rimWell == NULL) return; - RigWellResults* wRes = m_rimWell->wellResults(); + RigSingleWellResultsData* wRes = m_rimWell->wellResults(); if (wRes == NULL) return; if (frameIndex < wRes->firstResultTimeStep()) return; // Or reset colors or something diff --git a/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.h b/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.h index f3fc473a50..942b50866c 100644 --- a/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.h @@ -20,7 +20,7 @@ #include "cafPdmPointer.h" #include -#include "RigWellResults.h" +#include "RigSingleWellResultsData.h" namespace cvf { diff --git a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index 86e6d05cb5..0aa4acad71 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -16,15 +16,15 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "Rim3dOverlayInfoConfig.h" #include "RimReservoirView.h" -#include "RIViewer.h" -#include "RimReservoir.h" -#include "RigReservoir.h" +#include "RiuViewer.h" +#include "RimCase.h" +#include "RigCaseData.h" #include "RigMainGrid.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" CAF_PDM_SOURCE_INIT(Rim3dOverlayInfoConfig, "View3dOverlayInfoConfig"); @@ -70,7 +70,8 @@ void Rim3dOverlayInfoConfig::setPosition(cvf::Vec2ui position) //-------------------------------------------------------------------------------------------------- void Rim3dOverlayInfoConfig::update3DInfo() { - if (!m_reservoirView && m_reservoirView->viewer()) return; + if (!m_reservoirView) return; + if (!m_reservoirView->viewer()) return; m_reservoirView->viewer()->showInfoText(showInfoText()); m_reservoirView->viewer()->showHistogram(false); @@ -80,16 +81,22 @@ void Rim3dOverlayInfoConfig::update3DInfo() { QString caseName; QString totCellCount; - QString activeCellCount; + QString activeCellCountText; + QString fractureActiveCellCount; QString iSize, jSize, kSize; QString propName; QString cellEdgeName; - if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) + if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData() && m_reservoirView->eclipseCase()->reservoirData()->mainGrid()) { - caseName = m_reservoirView->eclipseCase()->caseName(); + caseName = m_reservoirView->eclipseCase()->caseUserDescription(); totCellCount = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cells().size()); - activeCellCount = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->globalMatrixModelActiveCellCount()); + size_t mxActCellCount = m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->globalActiveCellCount(); + size_t frActCellCount = m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->globalActiveCellCount(); + if (frActCellCount > 0) activeCellCountText += "Matrix : "; + activeCellCountText += QString::number(mxActCellCount); + if (frActCellCount > 0) activeCellCountText += " Fracture : " + QString::number(frActCellCount); + iSize = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cellCountI()); jSize = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cellCountJ()); kSize = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cellCountK()); @@ -100,7 +107,7 @@ void Rim3dOverlayInfoConfig::update3DInfo() QString infoText = QString( "

-- %1 --

" "Cell count. Total: %2 Active: %3
" - "Main Grid I,J,K: %4, %5, %6
").arg(caseName, totCellCount, activeCellCount, iSize, jSize, kSize); + "Main Grid I,J,K: %4, %5, %6
").arg(caseName, totCellCount, activeCellCountText, iSize, jSize, kSize); if (m_reservoirView->animationMode() && m_reservoirView->cellResult()->hasResult()) { @@ -110,9 +117,9 @@ void Rim3dOverlayInfoConfig::update3DInfo() double p10, p90; double mean; size_t scalarIndex = m_reservoirView->cellResult()->gridScalarIndex(); - m_reservoirView->gridCellResults()->minMaxCellScalarValues(scalarIndex, min, max); - m_reservoirView->gridCellResults()->p10p90CellScalarValues(scalarIndex, p10, p90); - m_reservoirView->gridCellResults()->meanCellScalarValues(scalarIndex, mean); + m_reservoirView->currentGridCellResults()->cellResults()->minMaxCellScalarValues(scalarIndex, min, max); + m_reservoirView->currentGridCellResults()->cellResults()->p10p90CellScalarValues(scalarIndex, p10, p90); + m_reservoirView->currentGridCellResults()->cellResults()->meanCellScalarValues(scalarIndex, mean); //infoText += QString("

Min: %1 P10: %2 Mean: %3 P90: %4 Max: %5
").arg(min).arg(p10).arg(mean).arg(p90).arg(max); //infoText += QString("
Min: %1   P10: %2   Mean: %3 \n  P90: %4   Max: %5 
").arg(min).arg(p10).arg(mean).arg(p90).arg(max); @@ -134,7 +141,7 @@ void Rim3dOverlayInfoConfig::update3DInfo() || m_reservoirView->wellCollection()->hasVisibleWellPipes()) { int currentTimeStep = m_reservoirView->currentTimeStep(); - QDateTime date = m_reservoirView->gridCellResults()->timeStepDate(0, currentTimeStep); + QDateTime date = m_reservoirView->currentGridCellResults()->cellResults()->timeStepDate(0, currentTimeStep); infoText += QString("Time Step: %1 Time: %2").arg(currentTimeStep).arg(date.toString("dd.MMM yyyy")); } @@ -150,12 +157,12 @@ void Rim3dOverlayInfoConfig::update3DInfo() double mean; size_t scalarIndex = m_reservoirView->cellResult()->gridScalarIndex(); - m_reservoirView->gridCellResults()->minMaxCellScalarValues(scalarIndex, min, max); - m_reservoirView->gridCellResults()->p10p90CellScalarValues(scalarIndex, p10, p90); - m_reservoirView->gridCellResults()->meanCellScalarValues(scalarIndex, mean); + m_reservoirView->currentGridCellResults()->cellResults()->minMaxCellScalarValues(scalarIndex, min, max); + m_reservoirView->currentGridCellResults()->cellResults()->p10p90CellScalarValues(scalarIndex, p10, p90); + m_reservoirView->currentGridCellResults()->cellResults()->meanCellScalarValues(scalarIndex, mean); m_reservoirView->viewer()->showHistogram(true); - m_reservoirView->viewer()->setHistogram(min, max, m_reservoirView->gridCellResults()->cellScalarValuesHistogram(scalarIndex)); + m_reservoirView->viewer()->setHistogram(min, max, m_reservoirView->currentGridCellResults()->cellResults()->cellScalarValuesHistogram(scalarIndex)); m_reservoirView->viewer()->setHistogramPercentiles(p10, p90, mean); } } diff --git a/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.cpp b/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.cpp index 0a59a198b2..4d22f6ebe6 100644 --- a/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.cpp +++ b/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimBinaryExportSettings.h" #include "cafPdmUiFilePathEditor.h" diff --git a/ApplicationCode/ProjectDataModel/RimCalcScript.cpp b/ApplicationCode/ProjectDataModel/RimCalcScript.cpp index b16fe12977..f9f44a8f46 100644 --- a/ApplicationCode/ProjectDataModel/RimCalcScript.cpp +++ b/ApplicationCode/ProjectDataModel/RimCalcScript.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cafPdmField.h" @@ -35,6 +35,7 @@ RimCalcScript::RimCalcScript() CAF_PDM_InitField(&absolutePath, "AbsolutePath", QString(), "Location", "", "" ,""); CAF_PDM_InitField(&content, "Content", QString(), "Directory", "", "" ,""); content.setUiHidden(true); + content.setIOWritable(false); absolutePath.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); } diff --git a/ApplicationCode/ProjectDataModel/RimCase.cpp b/ApplicationCode/ProjectDataModel/RimCase.cpp new file mode 100644 index 0000000000..49b52305cb --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimCase.cpp @@ -0,0 +1,479 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RifReaderEclipseOutput.h" +#include "RifReaderMockModel.h" + +#include "RimCase.h" +#include "RimReservoirView.h" + +#include "RigCaseData.h" +#include "RigMainGrid.h" +#include "RigCaseCellResultsData.h" + +#include "cvfAssert.h" + +#include "cafPdmUiPushButtonEditor.h" + +#include +#include "RimProject.h" +#include "RimReservoirCellResultsCacher.h" + +CAF_PDM_SOURCE_INIT(RimCase, "RimReservoir"); + +//------------------------------------------------------------------------------------------------ +/// +//-------------------------------------------------------------------------------------------------- +RimCase::RimCase() +{ + CAF_PDM_InitField(&caseUserDescription, "CaseUserDescription", QString(), "Case name", "", "" ,""); + CAF_PDM_InitFieldNoDefault(&reservoirViews, "ReservoirViews", "", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_matrixModelResults, "MatrixModelResults", "", "", "", ""); + m_matrixModelResults.setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_fractureModelResults, "FractureModelResults", "", "", "", ""); + m_fractureModelResults.setUiHidden(true); + + // Obsolete field + CAF_PDM_InitField(&caseName, "CaseName", QString(), "Obsolete", "", "" ,""); + caseName.setIOWritable(false); + caseName.setUiHidden(true); + + m_matrixModelResults = new RimReservoirCellResultsStorage; + m_fractureModelResults = new RimReservoirCellResultsStorage; + + this->setReservoirData( NULL ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCase::~RimCase() +{ + reservoirViews.deleteAllChildObjects(); + + delete m_matrixModelResults(); + delete m_fractureModelResults(); + + if (this->reservoirData()) + { + // At this point, we assume that memory should be released + CVF_ASSERT(this->reservoirData()->refCount() == 1); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseData* RimCase::reservoirData() +{ + return m_rigEclipseCase.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigCaseData* RimCase::reservoirData() const +{ + return m_rigEclipseCase.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCase::initAfterRead() +{ + size_t j; + for (j = 0; j < reservoirViews().size(); j++) + { + RimReservoirView* riv = reservoirViews()[j]; + CVF_ASSERT(riv); + + riv->setEclipseCase(this); + } + + if (caseUserDescription().isEmpty() && !caseName().isEmpty()) + { + caseUserDescription = caseName; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimReservoirView* RimCase::createAndAddReservoirView() +{ + RimReservoirView* riv = new RimReservoirView(); + riv->setEclipseCase(this); + + size_t i = reservoirViews().size(); + riv->name = QString("View %1").arg(i + 1); + + reservoirViews().push_back(riv); + + return riv; +} + +//-------------------------------------------------------------------------------------------------- +/// TODO: Move this functionality to PdmPointersField +//-------------------------------------------------------------------------------------------------- +void RimCase::removeReservoirView(RimReservoirView* reservoirView) +{ + std::vector indices; + + size_t i; + for (i = 0; i < reservoirViews().size(); i++) + { + if (reservoirViews()[i] == reservoirView) + { + indices.push_back(i); + } + } + + // NB! Make sure the ordering goes from large to low index + while (!indices.empty()) + { + reservoirViews().erase(indices.back()); + indices.pop_back(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCase::removeResult(const QString& resultName) +{ + size_t i; + for (i = 0; i < reservoirViews().size(); i++) + { + RimReservoirView* reservoirView = reservoirViews()[i]; + CVF_ASSERT(reservoirView); + + RimResultSlot* result = reservoirView->cellResult; + CVF_ASSERT(result); + + bool rebuildDisplayModel = false; + + // Set cell result variable to none if displaying + if (result->resultVariable() == resultName) + { + result->resultVariable.v() = RimDefines::undefinedResultName(); + result->loadResult(); + + rebuildDisplayModel = true; + } + + std::list< caf::PdmPointer< RimCellPropertyFilter > >::iterator it; + RimCellPropertyFilterCollection* propFilterCollection = reservoirView->propertyFilterCollection(); + for (it = propFilterCollection->propertyFilters.v().begin(); it != propFilterCollection->propertyFilters.v().end(); ++it) + { + RimCellPropertyFilter* propertyFilter = *it; + if (propertyFilter->resultDefinition->resultVariable.v() == resultName) + { + propertyFilter->resultDefinition->resultVariable.v() = RimDefines::undefinedResultName(); + propertyFilter->resultDefinition->loadResult(); + propertyFilter->setDefaultValues(); + + rebuildDisplayModel = true; + } + } + + if (rebuildDisplayModel) + { + reservoirViews()[i]->createDisplayModelAndRedraw(); + } + + + // TODO + // CellEdgeResults are not considered, as they do not support display of input properties yet + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (changedField == &releaseResultMemory) + { + if (this->reservoirData()) + { + for (size_t i = 0; i < reservoirViews().size(); i++) + { + RimReservoirView* reservoirView = reservoirViews()[i]; + CVF_ASSERT(reservoirView); + + RimResultSlot* result = reservoirView->cellResult; + CVF_ASSERT(result); + + result->resultVariable.v() = RimDefines::undefinedResultName(); + result->loadResult(); + + RimCellEdgeResultSlot* cellEdgeResult = reservoirView->cellEdgeResult; + CVF_ASSERT(cellEdgeResult); + + cellEdgeResult->resultVariable.v() = RimDefines::undefinedResultName(); + cellEdgeResult->loadResult(); + + reservoirView->createDisplayModelAndRedraw(); + } + + RigCaseCellResultsData* matrixModelResults = reservoirData()->results(RifReaderInterface::MATRIX_RESULTS); + if (matrixModelResults) + { + matrixModelResults->clearAllResults(); + } + + RigCaseCellResultsData* fractureModelResults = reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS); + if (fractureModelResults) + { + fractureModelResults->clearAllResults(); + } + } + + releaseResultMemory = oldValue.toBool(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCase::computeCachedData() +{ + RigCaseData* rigEclipseCase = reservoirData(); + if (rigEclipseCase) + { + rigEclipseCase->computeActiveCellBoundingBoxes(); + + rigEclipseCase->mainGrid()->computeCachedData(); + + std::vector grids; + rigEclipseCase->allGrids(&grids); + + size_t i; + for (i = 0; i < grids.size(); i++) + { + grids[i]->computeFaults(); + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCaseCollection* RimCase::parentCaseCollection() +{ + std::vector parentObjects; + this->parentObjectsOfType(parentObjects); + + if (parentObjects.size() > 0) + { + return parentObjects[0]; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup* RimCase::parentGridCaseGroup() +{ + RimCaseCollection* caseColl = parentCaseCollection(); + if (caseColl) + { + return caseColl->parentCaseGroup(); + } + else + { + return NULL; + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCase::setReservoirData(RigCaseData* eclipseCase) +{ + m_rigEclipseCase = eclipseCase; + if (this->reservoirData()) + { + m_fractureModelResults()->setCellResults(reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS)); + m_matrixModelResults()->setCellResults(reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)); + m_fractureModelResults()->setMainGrid(this->reservoirData()->mainGrid()); + m_matrixModelResults()->setMainGrid(this->reservoirData()->mainGrid()); + } + else + { + m_fractureModelResults()->setCellResults(NULL); + m_matrixModelResults()->setCellResults(NULL); + m_fractureModelResults()->setMainGrid(NULL); + m_matrixModelResults()->setMainGrid(NULL); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimReservoirCellResultsStorage* RimCase::results(RifReaderInterface::PorosityModelResultType porosityModel) +{ + if (porosityModel == RifReaderInterface::MATRIX_RESULTS) + { + return m_matrixModelResults(); + } + + return m_fractureModelResults(); +} + + +//-------------------------------------------------------------------------------------------------- +/// Relocate the supplied file name, based on the search path as follows: +/// fileName, newProjectPath/fileNameWoPath, relocatedPath/fileNameWoPath +/// If the file is not found in any of the positions, the fileName is returned unchanged +/// +/// The relocatedPath is found in this way: +/// use the start of newProjectPath +/// plus the end of the path to m_gridFileName +/// such that the common start of oldProjectPath and m_gridFileName is removed from m_gridFileName +/// and replaced with the start of newProjectPath up to where newProjectPath starts to be equal to oldProjectPath +//-------------------------------------------------------------------------------------------------- +QString RimCase::relocateFile(const QString& fileName, const QString& newProjectPath, const QString& oldProjectPath, + bool* foundFile, std::vector* searchedPaths) +{ + if (foundFile) *foundFile = true; + + if (searchedPaths) searchedPaths->push_back(fileName); + if (QFile::exists(fileName)) + { + return fileName; + } + + // First check in the new project file directory + { + QString fileNameWithoutPath = QFileInfo(fileName).fileName(); + QString candidate = QDir::fromNativeSeparators(newProjectPath + QDir::separator() + fileNameWithoutPath); + if (searchedPaths) searchedPaths->push_back(candidate); + + if (QFile::exists(candidate)) + { + return candidate; + } + } + + // Then find the possible move of a directory structure where projects and files referenced are moved in "paralell" + + QFileInfo gridFileInfo(QDir::fromNativeSeparators(fileName)); + QString gridFilePath = gridFileInfo.path(); + QString gridFileNameWoPath = gridFileInfo.fileName(); + QStringList gridPathElements = gridFilePath.split("/", QString::KeepEmptyParts); + + QString oldProjPath = QDir::fromNativeSeparators(oldProjectPath); + QStringList oldProjPathElements = oldProjPath.split("/", QString::KeepEmptyParts); + + QString newProjPath = QDir::fromNativeSeparators(newProjectPath); + QStringList newProjPathElements = newProjPath.split("/", QString::KeepEmptyParts); + + // Find the possible equal start of the old project path, and the referenced file + + bool pathStartsAreEqual = false; + bool pathEndsDiffer = false; + int firstDiffIdx = 0; + for ( firstDiffIdx = 0; firstDiffIdx < gridPathElements.size() && firstDiffIdx < oldProjPathElements.size(); ++firstDiffIdx) + { + if (gridPathElements[firstDiffIdx] == oldProjPathElements[firstDiffIdx]) + { + pathStartsAreEqual = pathStartsAreEqual || !gridPathElements[firstDiffIdx].isEmpty(); + } + else + { + pathEndsDiffer = true; + break; + } + } + + if (!pathEndsDiffer && firstDiffIdx < gridPathElements.size() || firstDiffIdx < oldProjPathElements.size()) + { + pathEndsDiffer = true; + } + + // If the path starts are equal, try to substitute it in the referenced file, with the corresponding new project path start + + if (pathStartsAreEqual) + { + if (pathEndsDiffer) + { + QString oldGridFilePathEnd; + for (int i = firstDiffIdx; i < gridPathElements.size(); ++i) + { + oldGridFilePathEnd += gridPathElements[i]; + oldGridFilePathEnd += "/"; + } + + // Find the new Project File Start Path + + QStringList oldProjectFilePathEndElements; + for (int i = firstDiffIdx; i < oldProjPathElements.size(); ++i) + { + oldProjectFilePathEndElements.push_back(oldProjPathElements[i]); + } + + int ppIdx = oldProjectFilePathEndElements.size() -1; + int lastDiffIdx = newProjPathElements.size() -1; + + for (; lastDiffIdx >= 0 && ppIdx >= 0; --lastDiffIdx, --ppIdx) + { + if (oldProjectFilePathEndElements[ppIdx] != newProjPathElements[lastDiffIdx]) + { + break; + } + } + + QString newProjecetFileStartPath; + for (int i = 0; i <= lastDiffIdx; ++i) + { + newProjecetFileStartPath += newProjPathElements[i]; + newProjecetFileStartPath += "/"; + } + + QString relocationPath = newProjecetFileStartPath + oldGridFilePathEnd; + + QString relocatedFileName = relocationPath + gridFileNameWoPath; + + if (searchedPaths) searchedPaths->push_back(relocatedFileName); + + if (QFile::exists(relocatedFileName)) + { + return relocatedFileName; + } + } + else + { + // The Grid file was located in the same dir as the Project file. This is supposed to be handled above. + // So we did not find it + } + } + + // return the unchanged filename, if we could not find a valid relocation file + if (foundFile) *foundFile = false; + + return fileName; +} diff --git a/ApplicationCode/ProjectDataModel/RimCase.h b/ApplicationCode/ProjectDataModel/RimCase.h new file mode 100644 index 0000000000..dea48e04e9 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimCase.h @@ -0,0 +1,100 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "RimReservoirCellResultsCacher.h" +#include "RifReaderInterface.h" + +class QString; + +class RigCaseData; +class RigGridBase; +class RimReservoirView; +class RimCaseCollection; +class RimIdenticalGridCaseGroup; +//class RimReservoirCellResultsCacher; + +//================================================================================================== +// +// Interface for reservoirs. +// +//================================================================================================== +class RimCase : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimCase(); + virtual ~RimCase(); + + + // Fields: + caf::PdmField caseUserDescription; + caf::PdmField releaseResultMemory; + caf::PdmPointersField reservoirViews; + + virtual bool openEclipseGridFile() { return false;}; // Should be pure virtual but PDM does not allow that. + + RigCaseData* reservoirData(); + const RigCaseData* reservoirData() const; + + RimReservoirCellResultsStorage* results(RifReaderInterface::PorosityModelResultType porosityModel); + + RimReservoirView* createAndAddReservoirView(); + void removeReservoirView(RimReservoirView* reservoirView); + + void removeResult(const QString& resultName); + + virtual QString locationOnDisc() const { return QString(); } + virtual QString gridFileName() const { return QString(); } + + virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath) { }; + + RimCaseCollection* parentCaseCollection(); + RimIdenticalGridCaseGroup* parentGridCaseGroup(); + + + // Overridden methods from PdmObject +public: + virtual caf::PdmFieldHandle* userDescriptionField() { return &caseUserDescription; } +protected: + virtual void initAfterRead(); + virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); + + // Internal methods +protected: + void computeCachedData(); + void setReservoirData(RigCaseData* eclipseCase); + static QString relocateFile(const QString& fileName, const QString& newProjectPath, const QString& oldProjectPath, + bool* foundFile, std::vector* searchedPaths); + +private: + cvf::ref m_rigEclipseCase; + +private: + caf::PdmField m_matrixModelResults; + caf::PdmField m_fractureModelResults; + + // Obsolete fields +protected: + caf::PdmField caseName; +}; diff --git a/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp b/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp new file mode 100644 index 0000000000..67e932b0c2 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp @@ -0,0 +1,77 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RimCaseCollection.h" + +#include "RimReservoirView.h" +#include "RimIdenticalGridCaseGroup.h" + +CAF_PDM_SOURCE_INIT(RimCaseCollection, "RimCaseCollection"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCaseCollection::RimCaseCollection() +{ + CAF_PDM_InitObject("Derived Statistics", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&reservoirs, "Reservoirs", "", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCaseCollection::~RimCaseCollection() +{ + reservoirs.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup* RimCaseCollection::parentCaseGroup() +{ + std::vector parentObjects; + this->parentObjectsOfType(parentObjects); + + if (parentObjects.size() > 0) + { + return parentObjects[0]; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCase* RimCaseCollection::findByDescription(const QString& caseDescription) const +{ + for (size_t i = 0; i < reservoirs.size(); i++) + { + if (caseDescription == reservoirs[i]->caseUserDescription()) + { + return reservoirs[i]; + } + } + + return NULL; +} diff --git a/ApplicationCode/ProjectDataModel/RimCaseCollection.h b/ApplicationCode/ProjectDataModel/RimCaseCollection.h new file mode 100644 index 0000000000..136b6fa766 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimCaseCollection.h @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +#include "RimStatisticsCase.h" + + +//================================================================================================== +// +// +// +//================================================================================================== +class RimCaseCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimCaseCollection(); + virtual ~RimCaseCollection(); + caf::PdmPointersField reservoirs; + + RimIdenticalGridCaseGroup* parentCaseGroup(); + RimCase* findByDescription(const QString& caseDescription) const; + +private: + +}; diff --git a/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp b/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp index 00c2b06d67..28f638ff9d 100644 --- a/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp @@ -16,15 +16,15 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimCellEdgeResultSlot.h" #include "RimLegendConfig.h" #include "RimReservoirView.h" -#include "RimReservoir.h" +#include "RimCase.h" #include "RimReservoirView.h" -#include "RigReservoirCellResults.h" -#include "RigReservoir.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" #include "cafPdmUiListEditor.h" @@ -71,7 +71,7 @@ void RimCellEdgeResultSlot::setReservoirView(RimReservoirView* ownerReservoirVie //-------------------------------------------------------------------------------------------------- void RimCellEdgeResultSlot::loadResult() { - CVF_ASSERT(m_reservoirView && m_reservoirView->gridCellResults()); + CVF_ASSERT(m_reservoirView && m_reservoirView->currentGridCellResults()); resetResultIndices(); QStringList vars = findResultVariableNames(); @@ -80,7 +80,7 @@ void RimCellEdgeResultSlot::loadResult() int i; for (i = 0; i < vars.size(); ++i) { - size_t resultindex = m_reservoirView->gridCellResults()->findOrLoadScalarResult(RimDefines::STATIC_NATIVE, vars[i]); + size_t resultindex = m_reservoirView->currentGridCellResults()->findOrLoadScalarResult(RimDefines::STATIC_NATIVE, vars[i]); int cubeFaceIdx; for (cubeFaceIdx = 0; cubeFaceIdx < 6; ++cubeFaceIdx) { @@ -130,10 +130,10 @@ QList RimCellEdgeResultSlot::calculateValueOptions(const { if (fieldNeedingOptions == &resultVariable) { - if (m_reservoirView && m_reservoirView->gridCellResults()) + if (m_reservoirView && m_reservoirView->currentGridCellResults()) { QStringList varList; - varList = m_reservoirView->gridCellResults()->resultNames(RimDefines::STATIC_NATIVE); + varList = m_reservoirView->currentGridCellResults()->cellResults()->resultNames(RimDefines::STATIC_NATIVE); //TODO: Must also handle input properties //varList += m_reservoirView->gridCellResults()->resultNames(RimDefines::INPUT_PROPERTY); @@ -205,10 +205,10 @@ QStringList RimCellEdgeResultSlot::findResultVariableNames() { QStringList varNames; - if (m_reservoirView && m_reservoirView->gridCellResults() && !resultVariable().isEmpty()) + if (m_reservoirView && m_reservoirView->currentGridCellResults() && !resultVariable().isEmpty()) { QStringList varList; - varList = m_reservoirView->gridCellResults()->resultNames(RimDefines::STATIC_NATIVE); + varList = m_reservoirView->currentGridCellResults()->cellResults()->resultNames(RimDefines::STATIC_NATIVE); //TODO: Must handle Input properties int i; @@ -313,7 +313,7 @@ void RimCellEdgeResultSlot::minMaxCellEdgeValues(double& min, double& max) { double cMin, cMax; - m_reservoirView->gridCellResults()->minMaxCellScalarValues(resultIndices[idx], cMin, cMax); + m_reservoirView->currentGridCellResults()->cellResults()->minMaxCellScalarValues(resultIndices[idx], cMin, cMax); globalMin = CVF_MIN(globalMin, cMin); globalMax = CVF_MAX(globalMax, cMax); diff --git a/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h b/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h index c37bc7577d..8f4eb1eba9 100644 --- a/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h +++ b/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h @@ -23,7 +23,7 @@ #include "cafAppEnum.h" #include "RimDefines.h" -class RigReservoirCellResults; +class RigCaseCellResultsData; namespace caf { diff --git a/ApplicationCode/ProjectDataModel/RimCellFilter.cpp b/ApplicationCode/ProjectDataModel/RimCellFilter.cpp index 0b7f188005..6e901ff774 100644 --- a/ApplicationCode/ProjectDataModel/RimCellFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellFilter.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cafAppEnum.h" diff --git a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp index d4c887a866..753cf5e676 100644 --- a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp @@ -16,13 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimReservoirView.h" #include "RimCellPropertyFilter.h" #include "RimCellPropertyFilterCollection.h" #include "RigGridBase.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "cafPdmUiDoubleSliderEditor.h" @@ -143,10 +143,10 @@ void RimCellPropertyFilter::setDefaultValues() size_t scalarIndex = resultDefinition->gridScalarIndex(); if (scalarIndex != cvf::UNDEFINED_SIZE_T) { - RigReservoirCellResults* results = m_parentContainer->reservoirView()->gridCellResults(); + RimReservoirCellResultsStorage* results = m_parentContainer->reservoirView()->currentGridCellResults(); if (results) { - results->minMaxCellScalarValues(scalarIndex, min, max); + results->cellResults()->minMaxCellScalarValues(scalarIndex, min, max); } } @@ -163,7 +163,7 @@ void RimCellPropertyFilter::setDefaultValues() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimCellPropertyFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) const +void RimCellPropertyFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { // Fields declared in RimCellFilter uiOrdering.add(&name); diff --git a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h index 228826cb6b..a6f2c3d415 100644 --- a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h +++ b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h @@ -32,7 +32,7 @@ class RimCellPropertyFilterCollection; class RimResultDefinition; class RigGridBase; -class RigReservoirCellResults; +class RigCaseCellResultsData; namespace cvf { @@ -72,7 +72,7 @@ public: virtual QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ); protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) const; + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) ; virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); private: diff --git a/ApplicationCode/ProjectDataModel/RimCellPropertyFilterCollection.cpp b/ApplicationCode/ProjectDataModel/RimCellPropertyFilterCollection.cpp index 828aad2447..c69141e0a7 100644 --- a/ApplicationCode/ProjectDataModel/RimCellPropertyFilterCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellPropertyFilterCollection.cpp @@ -16,13 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimCellPropertyFilterCollection.h" #include "RimReservoirView.h" #include "RigGridBase.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" CAF_PDM_SOURCE_INIT(RimCellPropertyFilterCollection, "CellPropertyFilters"); diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp index 72d07621f2..965a93f78f 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp @@ -16,12 +16,12 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimCellRangeFilter.h" #include "RimCellRangeFilterCollection.h" #include "RimReservoirView.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "cafPdmUiSliderEditor.h" @@ -115,11 +115,11 @@ void RimCellRangeFilter::setDefaultValues() { CVF_ASSERT(m_parentContainer); - RigMainGrid* mainGrid = m_parentContainer->mainGrid(); - if (mainGrid) + RigActiveCellInfo* actCellInfo = m_parentContainer->activeCellInfo(); + if (actCellInfo) { cvf::Vec3st min, max; - mainGrid->matrixModelActiveCellsBoundingBox(min, max); + actCellInfo->IJKBoundingBox(min, max); // Adjust to Eclipse indexing min.x() = min.x() + 1; @@ -159,10 +159,13 @@ void RimCellRangeFilter::defineEditorAttribute(const caf::PdmFieldHandle* field, } RigMainGrid* mainGrid = m_parentContainer->mainGrid(); - if (mainGrid) + CVF_ASSERT(mainGrid); + + RigActiveCellInfo* actCellInfo = m_parentContainer->activeCellInfo(); + if (actCellInfo) { cvf::Vec3st min, max; - mainGrid->matrixModelActiveCellsBoundingBox(min, max); + actCellInfo->IJKBoundingBox(min, max); // Adjust to Eclipse indexing min.x() = min.x() + 1; diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp index 37be195aa2..73f90a8c7e 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp @@ -16,12 +16,12 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimCellRangeFilterCollection.h" #include "RimReservoirView.h" -#include "RigReservoir.h" +#include "RigCaseData.h" @@ -97,8 +97,6 @@ void RimCellRangeFilterCollection::compoundCellRangeFilter(cvf::CellRangeFilter* } } - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -126,9 +124,21 @@ RigMainGrid* RimCellRangeFilterCollection::mainGrid() const m_reservoirView->eclipseCase()->reservoirData()->mainGrid()) { - RigMainGrid* mainGrid = m_reservoirView->eclipseCase()->reservoirData()->mainGrid(); + return m_reservoirView->eclipseCase()->reservoirData()->mainGrid(); + } - return mainGrid; + return NULL; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellInfo* RimCellRangeFilterCollection::activeCellInfo() const +{ + if (m_reservoirView ) + { + return m_reservoirView->currentActiveCellInfo(); } return NULL; @@ -209,3 +219,4 @@ bool RimCellRangeFilterCollection::hasActiveFilters() const return false; } + diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h index c85fcab117..ee0fa83543 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h @@ -20,6 +20,8 @@ #include "RimCellRangeFilter.h" +class RigActiveCellInfo; + //================================================================================================== /// /// @@ -42,9 +44,10 @@ public: void compoundCellRangeFilter(cvf::CellRangeFilter* cellRangeFilter) const; bool hasActiveFilters() const; - void setReservoirView(RimReservoirView* reservoirView); - RimReservoirView* reservoirView(); - RigMainGrid* mainGrid() const; + void setReservoirView(RimReservoirView* reservoirView); + RimReservoirView* reservoirView(); + RigMainGrid* mainGrid() const; + RigActiveCellInfo* activeCellInfo() const; // Overridden methods virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); diff --git a/ApplicationCode/ProjectDataModel/RimDefines.cpp b/ApplicationCode/ProjectDataModel/RimDefines.cpp index 5002d0c42a..9fce926af4 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.cpp +++ b/ApplicationCode/ProjectDataModel/RimDefines.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimDefines.h" #include "cafAppEnum.h" diff --git a/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.cpp b/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.cpp index f2f432b775..8a2e491420 100644 --- a/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.cpp +++ b/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimExportInputPropertySettings.h" #include "cafPdmUiFilePathEditor.h" diff --git a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp new file mode 100644 index 0000000000..fc9ee8b431 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp @@ -0,0 +1,454 @@ +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RimIdenticalGridCaseGroup.h" +#include "RimCase.h" +#include "RimReservoirView.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" + +#include "RimStatisticsCase.h" +#include "RimStatisticsCaseCollection.h" +#include "RimResultCase.h" +#include "cafProgressInfo.h" +#include "RigActiveCellInfo.h" +#include "RigGridManager.h" + + +CAF_PDM_SOURCE_INIT(RimIdenticalGridCaseGroup, "RimIdenticalGridCaseGroup"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup::RimIdenticalGridCaseGroup() +{ + CAF_PDM_InitObject("Grid Case Group", ":/GridCaseGroup16x16.png", "", ""); + + CAF_PDM_InitField(&name, "UserDescription", QString("Grid Case Group"), "Name", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&statisticsCaseCollection, "StatisticsCaseCollection", "Derived Statistics", ":/Histograms16x16.png", "", ""); + CAF_PDM_InitFieldNoDefault(&caseCollection, "CaseCollection", "Cases", ":/Cases16x16.png", "", ""); + + caseCollection = new RimCaseCollection; + statisticsCaseCollection = new RimCaseCollection; + + m_mainGrid = NULL; + + m_unionOfMatrixActiveCells = new RigActiveCellInfo; + m_unionOfFractureActiveCells = new RigActiveCellInfo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup::~RimIdenticalGridCaseGroup() +{ + m_mainGrid = NULL; + + delete caseCollection; + caseCollection = NULL; + + delete statisticsCaseCollection; + statisticsCaseCollection = NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::addCase(RimCase* reservoir) +{ + CVF_ASSERT(reservoir); + + if (!reservoir) return; + + if (!m_mainGrid) + { + m_mainGrid = reservoir->reservoirData()->mainGrid(); + } + else + { + reservoir->reservoirData()->setMainGrid(m_mainGrid); + } + + caseCollection()->reservoirs().push_back(reservoir); + + clearActiveCellUnions(); + clearStatisticsResults(); + updateMainGridAndActiveCellsForStatisticsCases(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::removeCase(RimCase* reservoir) +{ + if (caseCollection()->reservoirs().count(reservoir) == 0) + { + return; + } + + caseCollection()->reservoirs().removeChildObject(reservoir); + + if (caseCollection()->reservoirs().size() == 0) + { + m_mainGrid = NULL; + } + + clearActiveCellUnions(); + clearStatisticsResults(); + updateMainGridAndActiveCellsForStatisticsCases(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigMainGrid* RimIdenticalGridCaseGroup::mainGrid() +{ + if (m_mainGrid) return m_mainGrid; + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimIdenticalGridCaseGroup::userDescriptionField() +{ + return &name; +} + +//-------------------------------------------------------------------------------------------------- +/// Make sure changes in this functions is validated to RiaApplication::addEclipseCases() +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::loadMainCaseAndActiveCellInfo() +{ + if (caseCollection()->reservoirs().size() == 0) + { + return; + } + + // Read the main case completely including grid. + // The mainGrid from the first case is reused directly in for the other cases. + // When reading active cell info, only the total cell count is tested for consistency + + RimCase* mainCase = caseCollection()->reservoirs[0]; + mainCase->openEclipseGridFile(); + RigCaseData* mainEclipseCase = mainCase->reservoirData(); + if (!mainEclipseCase) + { + // Error message + return; + } + + // Read active cell info from all source cases + + caf::ProgressInfo info(caseCollection()->reservoirs.size(), "Case group - Reading Active Cell data"); + for (size_t i = 1; i < caseCollection()->reservoirs.size(); i++) + { + RimResultCase* rimReservoir = dynamic_cast(caseCollection()->reservoirs[i]); + if(!rimReservoir) continue; // Input reservoir + + if (!rimReservoir->openAndReadActiveCellData(mainEclipseCase)) + { + // Error message + continue; + } + + info.incrementProgress(); + } + + m_mainGrid = mainEclipseCase->mainGrid(); + + // Check if we need to calculate the union of the active cells + + bool foundResultsInCache = false; + for (size_t i = 0; i < statisticsCaseCollection()->reservoirs.size(); i++) + { + RimCase* rimReservoir = statisticsCaseCollection()->reservoirs[i]; + + // Check if any results are stored in cache + if (rimReservoir->results(RifReaderInterface::MATRIX_RESULTS)->storedResultsCount() > 0 || + rimReservoir->results(RifReaderInterface::FRACTURE_RESULTS)->storedResultsCount() > 0) + { + foundResultsInCache = true; + break; + } + } + + if (foundResultsInCache) + { + computeUnionOfActiveCells(); + } + + // "Load" the statistical cases + + for (size_t i = 0; i < statisticsCaseCollection()->reservoirs.size(); i++) + { + RimCase* rimReservoir = statisticsCaseCollection()->reservoirs[i]; + + rimReservoir->openEclipseGridFile(); + + if (i == 0) + { + rimReservoir->reservoirData()->computeActiveCellBoundingBoxes(); + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::computeUnionOfActiveCells() +{ + if (m_unionOfMatrixActiveCells->globalActiveCellCount() > 0) + { + return; + } + + if (caseCollection->reservoirs.size() == 0 || !m_mainGrid) + { + this->clearActiveCellUnions(); + + return; + } + + m_unionOfMatrixActiveCells->setGlobalCellCount(m_mainGrid->cells().size()); + m_unionOfFractureActiveCells->setGlobalCellCount(m_mainGrid->cells().size()); + m_unionOfMatrixActiveCells->setGridCount(m_mainGrid->gridCount()); + m_unionOfFractureActiveCells->setGridCount(m_mainGrid->gridCount()); + + size_t globalActiveMatrixIndex = 0; + size_t globalActiveFractureIndex = 0; + + for (size_t gridIdx = 0; gridIdx < m_mainGrid->gridCount(); gridIdx++) + { + RigGridBase* grid = m_mainGrid->gridByIndex(gridIdx); + + std::vector activeM(grid->cellCount(), 0); + std::vector activeF(grid->cellCount(), 0); + + for (size_t localGridCellIdx = 0; localGridCellIdx < grid->cellCount(); localGridCellIdx++) + { + for (size_t caseIdx = 0; caseIdx < caseCollection->reservoirs.size(); caseIdx++) + { + size_t globalCellIdx = grid->globalGridCellIndex(localGridCellIdx); + + if (activeM[localGridCellIdx] == 0) + { + if (caseCollection->reservoirs[caseIdx]->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->isActive(globalCellIdx)) + { + activeM[localGridCellIdx] = 1; + } + } + + if (activeF[localGridCellIdx] == 0) + { + if (caseCollection->reservoirs[caseIdx]->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->isActive(globalCellIdx)) + { + activeF[localGridCellIdx] = 1; + } + } + } + } + + size_t activeMatrixIndex = 0; + size_t activeFractureIndex = 0; + + for (size_t localGridCellIdx = 0; localGridCellIdx < grid->cellCount(); localGridCellIdx++) + { + size_t globalCellIdx = grid->globalGridCellIndex(localGridCellIdx); + + if (activeM[localGridCellIdx] != 0) + { + m_unionOfMatrixActiveCells->setCellResultIndex(globalCellIdx, globalActiveMatrixIndex++); + activeMatrixIndex++; + } + + if (activeF[localGridCellIdx] != 0) + { + m_unionOfFractureActiveCells->setCellResultIndex(globalCellIdx, globalActiveFractureIndex++); + activeFractureIndex++; + } + } + + m_unionOfMatrixActiveCells->setGridActiveCellCounts(gridIdx, activeMatrixIndex); + m_unionOfFractureActiveCells->setGridActiveCellCounts(gridIdx, activeFractureIndex); + } + + m_unionOfMatrixActiveCells->computeDerivedData(); + m_unionOfFractureActiveCells->computeDerivedData(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCase* RimIdenticalGridCaseGroup::createAndAppendStatisticsCase() +{ + RimStatisticsCase* newStatisticsCase = new RimStatisticsCase; + + newStatisticsCase->caseUserDescription = QString("Statistics ") + QString::number(statisticsCaseCollection()->reservoirs.size()+1); + statisticsCaseCollection()->reservoirs.push_back(newStatisticsCase); + + newStatisticsCase->openEclipseGridFile(); + + return newStatisticsCase; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::updateMainGridAndActiveCellsForStatisticsCases() +{ + for (size_t i = 0; i < statisticsCaseCollection->reservoirs().size(); i++) + { + RimCase* rimStaticsCase = statisticsCaseCollection->reservoirs[i]; + + rimStaticsCase->reservoirData()->setMainGrid(this->mainGrid()); + + if (i == 0) + { + rimStaticsCase->reservoirData()->computeActiveCellBoundingBoxes(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::clearStatisticsResults() +{ + for (size_t i = 0; i < statisticsCaseCollection->reservoirs().size(); i++) + { + RimCase* rimStaticsCase = statisticsCaseCollection->reservoirs[i]; + if (!rimStaticsCase) continue; + + rimStaticsCase->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->clearAllResults(); + rimStaticsCase->results(RifReaderInterface::FRACTURE_RESULTS)->cellResults()->clearAllResults(); + + for (size_t j = 0; j < rimStaticsCase->reservoirViews.size(); j++) + { + RimReservoirView* rimReservoirView = rimStaticsCase->reservoirViews[j]; + rimReservoirView->cellResult()->resultVariable = RimDefines::undefinedResultName(); + rimReservoirView->cellEdgeResult()->resultVariable = RimDefines::undefinedResultName(); + rimReservoirView->loadDataAndUpdate(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::clearActiveCellUnions() +{ + m_unionOfMatrixActiveCells->clear(); + m_unionOfFractureActiveCells->clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimIdenticalGridCaseGroup::contains(RimCase* reservoir) const +{ + CVF_ASSERT(reservoir); + + for (size_t i = 0; i < caseCollection()->reservoirs().size(); i++) + { + RimCase* rimReservoir = caseCollection()->reservoirs()[i]; + if (reservoir->gridFileName() == rimReservoir->gridFileName()) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellInfo* RimIdenticalGridCaseGroup::unionOfActiveCells(RifReaderInterface::PorosityModelResultType porosityType) +{ + if (porosityType == RifReaderInterface::MATRIX_RESULTS) + { + return m_unionOfMatrixActiveCells.p(); + } + else + { + return m_unionOfFractureActiveCells.p(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimIdenticalGridCaseGroup::isStatisticsCaseCollection(RimCaseCollection* rimCaseCollection) +{ + std::vector fields; + rimCaseCollection->parentFields(fields); + if (fields.size() == 1) + { + if (fields[0]->keyword() == "StatisticsCaseCollection") + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCase* RimIdenticalGridCaseGroup::mainCase() +{ + if(caseCollection()->reservoirs().size()) + { + return caseCollection()->reservoirs()[0]; + } + else + { + return NULL; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimIdenticalGridCaseGroup::canCaseBeAdded(RimCase* reservoir) const +{ + CVF_ASSERT(reservoir && reservoir->reservoirData() && reservoir->reservoirData()->mainGrid()); + + if (!m_mainGrid) + { + // Empty case group, reservoir can be added + return true; + } + + RigMainGrid* incomingMainGrid = reservoir->reservoirData()->mainGrid(); + + if (RigGridManager::isEqual(m_mainGrid, incomingMainGrid)) + { + return true; + } + + return false; +} diff --git a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h new file mode 100644 index 0000000000..fb9201a1fd --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h @@ -0,0 +1,82 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +#include "RimStatisticsCaseCollection.h" +#include "RimCaseCollection.h" + +class RimCase; +class RigMainGrid; +class RigActiveCellInfo; + +//================================================================================================== +// +// +// +//================================================================================================== +class RimIdenticalGridCaseGroup : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimIdenticalGridCaseGroup(); + virtual ~RimIdenticalGridCaseGroup(); + + caf::PdmField name; + caf::PdmField caseCollection; + caf::PdmField statisticsCaseCollection; + + void addCase(RimCase* reservoir); + void removeCase(RimCase* reservoir); + + bool contains(RimCase* reservoir) const; + bool canCaseBeAdded(RimCase* reservoir) const; + + RimStatisticsCase* createAndAppendStatisticsCase(); + + + RimCase* mainCase(); + void loadMainCaseAndActiveCellInfo(); + + RigMainGrid* mainGrid(); + + RigActiveCellInfo* unionOfActiveCells(RifReaderInterface::PorosityModelResultType porosityType); + void computeUnionOfActiveCells(); + + static bool isStatisticsCaseCollection(RimCaseCollection* rimCaseCollection); + +protected: + virtual caf::PdmFieldHandle* userDescriptionField(); + +private: + void updateMainGridAndActiveCellsForStatisticsCases(); + void clearStatisticsResults(); + void clearActiveCellUnions(); + +private: + RigMainGrid* m_mainGrid; + + cvf::ref m_unionOfMatrixActiveCells; + cvf::ref m_unionOfFractureActiveCells; +}; diff --git a/ApplicationCode/ProjectDataModel/RimInputReservoir.cpp b/ApplicationCode/ProjectDataModel/RimInputCase.cpp similarity index 76% rename from ApplicationCode/ProjectDataModel/RimInputReservoir.cpp rename to ApplicationCode/ProjectDataModel/RimInputCase.cpp index b2f5544dbe..b81c30d8ae 100644 --- a/ApplicationCode/ProjectDataModel/RimInputReservoir.cpp +++ b/ApplicationCode/ProjectDataModel/RimInputCase.cpp @@ -16,16 +16,16 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" -#include "RimInputReservoir.h" +#include "RimInputCase.h" #include "RimInputProperty.h" #include "RimReservoirView.h" #include "RifReaderEclipseInput.h" -#include "RigReservoir.h" -#include "RigReservoirCellResults.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" #include "cvfAssert.h" @@ -34,21 +34,22 @@ #include "RifEclipseInputFileTools.h" #include "cafProgressInfo.h" -#include "RIApplication.h" -#include "RIPreferences.h" +#include "RiaApplication.h" +#include "RiaPreferences.h" -CAF_PDM_SOURCE_INIT(RimInputReservoir, "RimInputReservoir"); +CAF_PDM_SOURCE_INIT(RimInputCase, "RimInputReservoir"); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimInputReservoir::RimInputReservoir() - : RimReservoir() +RimInputCase::RimInputCase() + : RimCase() { - CAF_PDM_InitObject("RimInputReservoir", ":/EclipseInput48x48.png", "", ""); + CAF_PDM_InitObject("RimInputCase", ":/EclipseInput48x48.png", "", ""); CAF_PDM_InitField(&m_gridFileName, "GridFileName", QString(), "Case grid filename", "", "" ,""); + m_gridFileName.setUiReadOnly(true); CAF_PDM_InitFieldNoDefault(&m_additionalFileNames, "AdditionalFileNames", "Additional files", "", "" ,""); - + m_additionalFileNames.setUiReadOnly(true); CAF_PDM_InitFieldNoDefault(&m_inputPropertyCollection, "InputPropertyCollection", "", "", "", ""); m_inputPropertyCollection = new RimInputPropertyCollection; @@ -58,7 +59,7 @@ RimInputReservoir::RimInputReservoir() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimInputReservoir::~RimInputReservoir() +RimInputCase::~RimInputCase() { delete m_inputPropertyCollection; } @@ -67,42 +68,23 @@ RimInputReservoir::~RimInputReservoir() /// Open the supplied file set. If no grid data has been read, it will first find the possible /// grid data among the files then read all supported properties from the files matching the grid //-------------------------------------------------------------------------------------------------- -void RimInputReservoir::openDataFileSet(const QStringList& filenames) +void RimInputCase::openDataFileSet(const QStringList& filenames) { - if (caseName().contains("Input Mock Debug Model")) + if (filenames.contains("Input Mock Debug Model")) { - cvf::ref readerInterface = this->createMockModel(this->caseName()); - m_rigReservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); - m_rigReservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); + cvf::ref readerInterface = this->createMockModel(filenames[0]); + results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); + results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); - size_t matrixActiveCellCount = 0; - size_t fractureActiveCellCount = 0; - - for (size_t cellIdx = 0; cellIdx < m_rigReservoir->mainGrid()->cells().size(); cellIdx++) - { - const RigCell& cell = m_rigReservoir->mainGrid()->cells()[cellIdx]; - - if (cell.isActiveInMatrixModel()) - { - matrixActiveCellCount++; - } - if (cell.isActiveInFractureModel()) - { - fractureActiveCellCount++; - } - - } - - m_rigReservoir->mainGrid()->setGlobalMatrixModelActiveCellCount(matrixActiveCellCount); - m_rigReservoir->mainGrid()->setGlobalFractureModelActiveCellCount(fractureActiveCellCount); + reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->computeDerivedData(); + reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->computeDerivedData(); return; } - if (m_rigReservoir.isNull()) + if (this->reservoirData() == NULL) { - RigReservoir* reservoir = new RigReservoir; - m_rigReservoir = reservoir; + this->setReservoirData(new RigCaseData); } // First find and read the grid data @@ -114,8 +96,7 @@ void RimInputReservoir::openDataFileSet(const QStringList& filenames) { m_gridFileName = filenames[i]; - m_rigReservoir->computeFaults(); - m_rigReservoir->mainGrid()->computeCachedData(); + computeCachedData(); break; } @@ -174,46 +155,45 @@ void RimInputReservoir::openDataFileSet(const QStringList& filenames) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimInputReservoir::openEclipseGridFile() +bool RimInputCase::openEclipseGridFile() { // Early exit if reservoir data is created - if (m_rigReservoir.isNull()) + if (this->reservoirData() == NULL) { cvf::ref readerInterface; - if (caseName().contains("Input Mock Debug Model")) + if (m_gridFileName().contains("Input Mock Debug Model")) { - readerInterface = this->createMockModel(this->caseName()); + readerInterface = this->createMockModel(this->m_gridFileName()); } else { - RigReservoir* reservoir = new RigReservoir; + cvf::ref eclipseCase = new RigCaseData; readerInterface = new RifReaderEclipseInput; - if (!readerInterface->open(m_gridFileName, reservoir)) + if (!readerInterface->open(m_gridFileName, eclipseCase.p())) { - delete reservoir; return false; } - m_rigReservoir = reservoir; - loadAndSyncronizeInputProperties(); + this->setReservoirData( eclipseCase.p() ); } - CVF_ASSERT(m_rigReservoir.notNull()); + CVF_ASSERT(this->reservoirData()); CVF_ASSERT(readerInterface.notNull()); - m_rigReservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); - m_rigReservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); - m_rigReservoir->computeFaults(); - m_rigReservoir->mainGrid()->computeCachedData(); + results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); + results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); + + computeCachedData(); + loadAndSyncronizeInputProperties(); } - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); if (app->preferences()->autocomputeDepthRelatedProperties) { - RigReservoirCellResults* matrixResults = m_rigReservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS); - RigReservoirCellResults* fractureResults = m_rigReservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS); + RimReservoirCellResultsStorage* matrixResults = results(RifReaderInterface::MATRIX_RESULTS); + RimReservoirCellResultsStorage* fractureResults = results(RifReaderInterface::FRACTURE_RESULTS); matrixResults->computeDepthRelatedResults(); fractureResults->computeDepthRelatedResults(); @@ -227,11 +207,11 @@ bool RimInputReservoir::openEclipseGridFile() /// Loads input property data from the gridFile and additional files /// Creates new InputProperties if necessary, and flags the unused ones as obsolete //-------------------------------------------------------------------------------------------------- -void RimInputReservoir::loadAndSyncronizeInputProperties() +void RimInputCase::loadAndSyncronizeInputProperties() { // Make sure we actually have reservoir data - CVF_ASSERT(m_rigReservoir.notNull()); + CVF_ASSERT(this->reservoirData()); CVF_ASSERT(this->reservoirData()->mainGrid()->gridPointDimensions() != cvf::Vec3st(0,0,0)); // Then read the properties from all the files referenced by the InputReservoir @@ -305,7 +285,7 @@ void RimInputReservoir::loadAndSyncronizeInputProperties() { if (fileKeywordSet.count(knownKeywords[fkIt])) { - QString resultName = this->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(knownKeywords[fkIt]); + QString resultName = this->reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(knownKeywords[fkIt]); if (RifEclipseInputFileTools::readProperty(filenames[i], this->reservoirData(), knownKeywords[fkIt], resultName)) { RimInputProperty* inputProperty = new RimInputProperty; @@ -334,7 +314,7 @@ void RimInputReservoir::loadAndSyncronizeInputProperties() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimInputReservoir::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimInputCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { } @@ -342,7 +322,7 @@ void RimInputReservoir::fieldChangedByUi(const caf::PdmFieldHandle* changedField //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimInputReservoir::addFiles(const QStringList& newFileNames) +void RimInputCase::addFiles(const QStringList& newFileNames) { } @@ -351,7 +331,7 @@ void RimInputReservoir::addFiles(const QStringList& newFileNames) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimInputReservoir::removeFiles(const QStringList& obsoleteFileNames) +void RimInputCase::removeFiles(const QStringList& obsoleteFileNames) { } @@ -359,7 +339,7 @@ void RimInputReservoir::removeFiles(const QStringList& obsoleteFileNames) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimInputReservoir::removeProperty(RimInputProperty* inputProperty) +void RimInputCase::removeProperty(RimInputProperty* inputProperty) { bool isPropertyFileReferencedByOthers = false; @@ -380,7 +360,7 @@ void RimInputReservoir::removeProperty(RimInputProperty* inputProperty) } // Remove the results pointed to by this input property - RigReservoirCellResults* results = m_rigReservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS); + RigCaseCellResultsData* results = reservoirData()->results(RifReaderInterface::MATRIX_RESULTS); results->removeResult(inputProperty->resultName); this->removeResult(inputProperty->resultName); @@ -389,13 +369,15 @@ void RimInputReservoir::removeProperty(RimInputProperty* inputProperty) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RimInputReservoir::createMockModel(QString modelName) +cvf::ref RimInputCase::createMockModel(QString modelName) { - cvf::ref reservoir = new RigReservoir; + cvf::ref reservoir = new RigCaseData; cvf::ref mockFileInterface = new RifReaderMockModel; if (modelName == "Input Mock Debug Model Simple") { + m_gridFileName = modelName; + // Create the mock file interface and and RigSerervoir and set them up. mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(20, 20, 20)); mockFileInterface->setGridPointDimensions(cvf::Vec3st(4, 5, 6)); @@ -405,12 +387,16 @@ cvf::ref RimInputReservoir::createMockModel(QString modelNam mockFileInterface->open("", reservoir.p()); { size_t idx = reservoir->mainGrid()->cellIndexFromIJK(1, 3, 4); - reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); + + //TODO: Rewrite active cell info in mock models + //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } { size_t idx = reservoir->mainGrid()->cellIndexFromIJK(2, 2, 3); - reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); + + //TODO: Rewrite active cell info in mock models + //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } // Add a property @@ -421,7 +407,7 @@ cvf::ref RimInputReservoir::createMockModel(QString modelNam m_inputPropertyCollection->inputProperties.push_back(inputProperty); } - m_rigReservoir = reservoir; + this->setReservoirData( reservoir.p() ); return mockFileInterface.p(); } @@ -429,10 +415,26 @@ cvf::ref RimInputReservoir::createMockModel(QString modelNam //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimInputReservoir::locationOnDisc() const +QString RimInputCase::locationOnDisc() const { if (m_gridFileName().isEmpty()) return QString(); QFileInfo fi(m_gridFileName); return fi.absolutePath(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimInputCase::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) +{ + bool foundFile = false; + std::vector searchedPaths; + + m_gridFileName = relocateFile(m_gridFileName(), newProjectPath, oldProjectPath, &foundFile, &searchedPaths); + + for (size_t i = 0; i < m_additionalFileNames().size(); i++) + { + m_additionalFileNames.v()[i] = relocateFile(m_additionalFileNames()[i], newProjectPath, oldProjectPath, &foundFile, &searchedPaths); + } +} diff --git a/ApplicationCode/ProjectDataModel/RimInputReservoir.h b/ApplicationCode/ProjectDataModel/RimInputCase.h similarity index 64% rename from ApplicationCode/ProjectDataModel/RimInputReservoir.h rename to ApplicationCode/ProjectDataModel/RimInputCase.h index 45f06d8c7c..1766fc9f3d 100644 --- a/ApplicationCode/ProjectDataModel/RimInputReservoir.h +++ b/ApplicationCode/ProjectDataModel/RimInputCase.h @@ -23,7 +23,7 @@ #include "cafPdmField.h" #include "cafPdmObject.h" -#include "RimReservoir.h" +#include "RimCase.h" #include "RimInputPropertyCollection.h" @@ -36,38 +36,43 @@ class RifReaderInterface; // // //================================================================================================== -class RimInputReservoir : public RimReservoir +class RimInputCase : public RimCase { CAF_PDM_HEADER_INIT; public: - RimInputReservoir(); - virtual ~RimInputReservoir(); + RimInputCase(); + virtual ~RimInputCase(); + + // Fields + caf::PdmField m_inputPropertyCollection; + + // File open methods + void openDataFileSet(const QStringList& filenames); + void loadAndSyncronizeInputProperties(); + + void removeProperty(RimInputProperty* inputProperty); + + // RimCase overrides + virtual bool openEclipseGridFile(); // Find grid file among file set. Read, Find read and validate property date. Syncronize child property sets. + + // PdmObject overrides + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + + // Overrides from RimCase + virtual QString locationOnDisc() const; + virtual QString gridFileName() const { return m_gridFileName();} + + virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath); + +private: + void addFiles(const QStringList& newFileNames); + void removeFiles(const QStringList& obsoleteFileNames); + + cvf::ref createMockModel(QString modelName); // Fields caf::PdmField > m_additionalFileNames; caf::PdmField m_gridFileName; - - caf::PdmField m_inputPropertyCollection; - - // File open methods - void openDataFileSet(const QStringList& filenames); - void loadAndSyncronizeInputProperties(); - - void removeProperty(RimInputProperty* inputProperty); - - // RimReservoir overrides - virtual bool openEclipseGridFile(); // Find grid file among file set. Read, Find read and validate property date. Syncronize child property sets. - - // PdmObject overrides - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - - virtual QString locationOnDisc() const; - -private: - void addFiles(const QStringList& newFileNames); - void removeFiles(const QStringList& obsoleteFileNames); - - cvf::ref createMockModel(QString modelName); }; diff --git a/ApplicationCode/ProjectDataModel/RimInputProperty.cpp b/ApplicationCode/ProjectDataModel/RimInputProperty.cpp index f226a8673c..95936e5f54 100644 --- a/ApplicationCode/ProjectDataModel/RimInputProperty.cpp +++ b/ApplicationCode/ProjectDataModel/RimInputProperty.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimInputProperty.h" diff --git a/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.cpp b/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.cpp index 4520653a03..5798253f13 100644 --- a/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimInputPropertyCollection.h" diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp index 33fca47d93..a9d392c359 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimLegendConfig.h" #include "RimReservoirView.h" @@ -405,13 +405,13 @@ void RimLegendConfig::recreateLegend() //-------------------------------------------------------------------------------------------------- double RimLegendConfig::adjust(double domainValue, double precision) { - double decadeValue = cvf::Math::abs(domainValue); - double threshold = 1e-6; - if (decadeValue < threshold) + double absDomainValue = cvf::Math::abs(domainValue); + if (absDomainValue == 0.0) { return 0.0; } - double logDecValue = log10(decadeValue); + + double logDecValue = log10(absDomainValue); logDecValue = cvf::Math::ceil(logDecValue); double factor = pow(10.0, precision - logDecValue); diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.h b/ApplicationCode/ProjectDataModel/RimLegendConfig.h index c2df1b93ff..540c0a63f2 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.h @@ -92,7 +92,7 @@ private: caf::PdmPointer m_reservoirView; cvf::ref m_linDiscreteScalarMapper; - cvf::ref m_logDiscreteScalarMapper; + cvf::ref m_logDiscreteScalarMapper; cvf::ref m_logSmoothScalarMapper; cvf::ref m_linSmoothScalarMapper; cvf::ref m_currentScalarMapper; diff --git a/ApplicationCode/ProjectDataModel/RimProject.cpp b/ApplicationCode/ProjectDataModel/RimProject.cpp index 4a07ccbb52..166e05c4d3 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationCode/ProjectDataModel/RimProject.cpp @@ -16,12 +16,16 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimProject.h" -#include "RIApplication.h" -#include "RIVersionInfo.h" -#include "RimScriptCollection.h" +#include "RiaApplication.h" +#include "RiaVersionInfo.h" + +#include "RigGridManager.h" +#include "RigCaseData.h" +#include "RimResultCase.h" + CAF_PDM_SOURCE_INIT(RimProject, "ResInsightProject"); //-------------------------------------------------------------------------------------------------- @@ -33,11 +37,15 @@ RimProject::RimProject(void) m_projectFileVersionString.setUiHidden(true); CAF_PDM_InitFieldNoDefault(&reservoirs, "Reservoirs", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&caseGroups, "CaseGroups", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&scriptCollection, "ScriptCollection", "Scripts", ":/Default.png", "", ""); scriptCollection = new RimScriptCollection(); scriptCollection->directory.setUiHidden(true); + m_gridCollection = new RigGridManager; + initAfterRead(); } @@ -46,6 +54,8 @@ RimProject::RimProject(void) //-------------------------------------------------------------------------------------------------- RimProject::~RimProject(void) { + close(); + if (scriptCollection()) delete scriptCollection(); reservoirs.deleteAllChildObjects(); @@ -56,7 +66,10 @@ RimProject::~RimProject(void) //-------------------------------------------------------------------------------------------------- void RimProject::close() { + m_gridCollection->clear(); + reservoirs.deleteAllChildObjects(); + caseGroups.deleteAllChildObjects(); fileName = ""; } @@ -69,7 +82,7 @@ void RimProject::initAfterRead() // // TODO : Must store content of scripts in project file and notify user if stored content is different from disk on execute and edit // - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString scriptDirectory = app->scriptDirectory(); this->setUserScriptPath(scriptDirectory); @@ -113,3 +126,145 @@ QString RimProject::projectFileVersionString() const { return m_projectFileVersionString; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::moveEclipseCaseIntoCaseGroup(RimCase* rimReservoir) +{ + CVF_ASSERT(rimReservoir); + + RigCaseData* rigEclipseCase = rimReservoir->reservoirData(); + RigMainGrid* equalGrid = registerCaseInGridCollection(rigEclipseCase); + CVF_ASSERT(equalGrid); + + // Insert in identical grid group + bool foundGroup = false; + + for (size_t i = 0; i < caseGroups.size(); i++) + { + RimIdenticalGridCaseGroup* cg = caseGroups()[i]; + + if (cg->mainGrid() == equalGrid) + { + cg->addCase(rimReservoir); + foundGroup = true; + } + } + + if (!foundGroup) + { + RimIdenticalGridCaseGroup* group = new RimIdenticalGridCaseGroup; + group->addCase(rimReservoir); + + caseGroups().push_back(group); + } + + // Remove reservoir from main container + reservoirs().removeChildObject(rimReservoir); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::removeCaseFromAllGroups(RimCase* reservoir) +{ + m_gridCollection->removeCase(reservoir->reservoirData()); + + for (size_t i = 0; i < caseGroups.size(); i++) + { + RimIdenticalGridCaseGroup* cg = caseGroups()[i]; + + cg->removeCase(reservoir); + } + + reservoirs().removeChildObject(reservoir); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigMainGrid* RimProject::registerCaseInGridCollection(RigCaseData* rigEclipseCase) +{ + CVF_ASSERT(rigEclipseCase); + + RigMainGrid* equalGrid = m_gridCollection->findEqualGrid(rigEclipseCase->mainGrid()); + + if (equalGrid) + { + // Replace the grid with an already registered grid + rigEclipseCase->setMainGrid(equalGrid); + } + else + { + // This is the first insertion of this grid, compute cached data + rigEclipseCase->mainGrid()->computeCachedData(); + + std::vector grids; + rigEclipseCase->allGrids(&grids); + + size_t i; + for (i = 0; i < grids.size(); i++) + { + grids[i]->computeFaults(); + } + + equalGrid = rigEclipseCase->mainGrid(); + } + + m_gridCollection->addCase(rigEclipseCase); + + return equalGrid; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::insertCaseInCaseGroup(RimIdenticalGridCaseGroup* caseGroup, RimCase* rimReservoir) +{ + CVF_ASSERT(rimReservoir); + + RigCaseData* rigEclipseCase = rimReservoir->reservoirData(); + registerCaseInGridCollection(rigEclipseCase); + + caseGroup->addCase(rimReservoir); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::setProjectFileNameAndUpdateDependencies(const QString& fileName) +{ + // Extract the filename of the project file when it was saved + QString oldProjectFileName = this->fileName; + // Replace with the new actual filename + this->fileName = fileName; + + // Loop over all reservoirs and update file path + + QFileInfo fileInfo(fileName); + QString newProjectPath = fileInfo.path(); + + QFileInfo fileInfoOld(oldProjectFileName); + QString oldProjectPath = fileInfoOld.path(); + + + for (size_t i = 0; i < reservoirs.size(); i++) + { + reservoirs[i]->updateFilePathsFromProjectPath(newProjectPath, oldProjectPath); + } + + // Case groups : Loop over all reservoirs in and update file path + + for (size_t i = 0; i < caseGroups.size(); i++) + { + RimIdenticalGridCaseGroup* cg = caseGroups()[i]; + + for (size_t j = 0; j < cg->caseCollection()->reservoirs().size(); j++) + { + cg->caseCollection()->reservoirs()[j]->updateFilePathsFromProjectPath(newProjectPath, oldProjectPath); + } + } +} + diff --git a/ApplicationCode/ProjectDataModel/RimProject.h b/ApplicationCode/ProjectDataModel/RimProject.h index c295f230d7..aa4f5f4b22 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.h +++ b/ApplicationCode/ProjectDataModel/RimProject.h @@ -20,8 +20,10 @@ #include "cafPdmDocument.h" #include "RimScriptCollection.h" +#include "RimIdenticalGridCaseGroup.h" -class RimReservoir; +class RimCase; +class RigGridManager; //================================================================================================== /// @@ -32,11 +34,11 @@ class RimProject : public caf::PdmDocument CAF_PDM_HEADER_INIT; public: - caf::PdmPointersField reservoirs; - caf::PdmField scriptCollection; + caf::PdmPointersField reservoirs; + caf::PdmPointersField caseGroups; + caf::PdmField scriptCollection; void setUserScriptPath(const QString& path); - //void updateProjectScriptPath(); QString projectFileVersionString() const; @@ -45,11 +47,22 @@ public: void close(); + void insertCaseInCaseGroup(RimIdenticalGridCaseGroup* caseGroup, RimCase* rimReservoir); + + void moveEclipseCaseIntoCaseGroup(RimCase* rimReservoir); + void removeCaseFromAllGroups(RimCase* rimReservoir); + + void setProjectFileNameAndUpdateDependencies(const QString& fileName); + +private: + RigMainGrid* registerCaseInGridCollection(RigCaseData* rigEclipseCase); + protected: // Overridden methods virtual void initAfterRead(); virtual void setupBeforeSave(); private: - caf::PdmField m_projectFileVersionString; + caf::PdmField m_projectFileVersionString; + cvf::ref m_gridCollection; }; diff --git a/ApplicationCode/ProjectDataModel/RimReservoir.cpp b/ApplicationCode/ProjectDataModel/RimReservoir.cpp deleted file mode 100644 index 79bd2bf00a..0000000000 --- a/ApplicationCode/ProjectDataModel/RimReservoir.cpp +++ /dev/null @@ -1,228 +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 "RIStdInclude.h" - -#include "RifReaderEclipseOutput.h" -#include "RifReaderMockModel.h" - -#include "RimReservoir.h" -#include "RimReservoirView.h" - -#include "RigReservoir.h" -#include "RigMainGrid.h" -#include "RigReservoirCellResults.h" - -#include "cvfAssert.h" - -#include "cafPdmUiPushButtonEditor.h" - -#include - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimReservoir::RimReservoir() -{ - m_rigReservoir = NULL; - - CAF_PDM_InitField(&caseName, "CaseName", QString(), "Case name", "", "" ,""); -// CAF_PDM_InitField(&releaseResultMemory, "ReleaseResultMemory", true, "Release result memory", "", "" ,""); -// releaseResultMemory.setIOReadable(false); -// releaseResultMemory.setIOWritable(false); -// releaseResultMemory.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); - - CAF_PDM_InitFieldNoDefault(&reservoirViews, "ReservoirViews", "", "", "", ""); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigReservoir* RimReservoir::reservoirData() -{ - return m_rigReservoir.p(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const RigReservoir* RimReservoir::reservoirData() const -{ - return m_rigReservoir.p(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimReservoir::initAfterRead() -{ - size_t j; - for (j = 0; j < reservoirViews().size(); j++) - { - RimReservoirView* riv = reservoirViews()[j]; - CVF_ASSERT(riv); - - riv->setEclipseCase(this); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimReservoir::~RimReservoir() -{ - reservoirViews.deleteAllChildObjects(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimReservoirView* RimReservoir::createAndAddReservoirView() -{ - RimReservoirView* riv = new RimReservoirView(); - riv->setEclipseCase(this); - - size_t i = reservoirViews().size(); - riv->name = QString("View %1").arg(i + 1); - - reservoirViews().push_back(riv); - - return riv; -} - -//-------------------------------------------------------------------------------------------------- -/// TODO: Move this functionality to PdmPointersField -//-------------------------------------------------------------------------------------------------- -void RimReservoir::removeReservoirView(RimReservoirView* reservoirView) -{ - std::vector indices; - - size_t i; - for (i = 0; i < reservoirViews().size(); i++) - { - if (reservoirViews()[i] == reservoirView) - { - indices.push_back(i); - } - } - - // NB! Make sure the ordering goes from large to low index - while (!indices.empty()) - { - reservoirViews().erase(indices.back()); - indices.pop_back(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimReservoir::removeResult(const QString& resultName) -{ - size_t i; - for (i = 0; i < reservoirViews().size(); i++) - { - RimReservoirView* reservoirView = reservoirViews()[i]; - CVF_ASSERT(reservoirView); - - RimResultSlot* result = reservoirView->cellResult; - CVF_ASSERT(result); - - bool rebuildDisplayModel = false; - - // Set cell result variable to none if displaying - if (result->resultVariable() == resultName) - { - result->resultVariable.v() = RimDefines::undefinedResultName(); - result->loadResult(); - - rebuildDisplayModel = true; - } - - std::list< caf::PdmPointer< RimCellPropertyFilter > >::iterator it; - RimCellPropertyFilterCollection* propFilterCollection = reservoirView->propertyFilterCollection(); - for (it = propFilterCollection->propertyFilters.v().begin(); it != propFilterCollection->propertyFilters.v().end(); ++it) - { - RimCellPropertyFilter* propertyFilter = *it; - if (propertyFilter->resultDefinition->resultVariable.v() == resultName) - { - propertyFilter->resultDefinition->resultVariable.v() = RimDefines::undefinedResultName(); - propertyFilter->resultDefinition->loadResult(); - propertyFilter->setDefaultValues(); - - rebuildDisplayModel = true; - } - } - - if (rebuildDisplayModel) - { - reservoirViews()[i]->createDisplayModelAndRedraw(); - } - - - // TODO - // CellEdgeResults are not considered, as they do not support display of input properties yet - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimReservoir::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) -{ - if (changedField == &releaseResultMemory) - { - if (m_rigReservoir.notNull()) - { - for (size_t i = 0; i < reservoirViews().size(); i++) - { - RimReservoirView* reservoirView = reservoirViews()[i]; - CVF_ASSERT(reservoirView); - - RimResultSlot* result = reservoirView->cellResult; - CVF_ASSERT(result); - - result->resultVariable.v() = RimDefines::undefinedResultName(); - result->loadResult(); - - RimCellEdgeResultSlot* cellEdgeResult = reservoirView->cellEdgeResult; - CVF_ASSERT(cellEdgeResult); - - cellEdgeResult->resultVariable.v() = RimDefines::undefinedResultName(); - cellEdgeResult->loadResult(); - - reservoirView->createDisplayModelAndRedraw(); - } - - RigReservoirCellResults* matrixModelResults = m_rigReservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS); - if (matrixModelResults) - { - matrixModelResults->clearAllResults(); - } - - RigReservoirCellResults* fractureModelResults = m_rigReservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS); - if (fractureModelResults) - { - fractureModelResults->clearAllResults(); - } - } - - releaseResultMemory = oldValue.toBool(); - } -} - diff --git a/ApplicationCode/ProjectDataModel/RimReservoir.h b/ApplicationCode/ProjectDataModel/RimReservoir.h deleted file mode 100644 index 0a8be97631..0000000000 --- a/ApplicationCode/ProjectDataModel/RimReservoir.h +++ /dev/null @@ -1,76 +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. -// -///////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "cvfBase.h" -#include "cvfObject.h" -#include "cafPdmField.h" -#include "cafPdmObject.h" - - -class QString; - -class RigReservoir; -class RigGridBase; -class RimReservoirView; - -//================================================================================================== -// -// Interface for reservoirs. -// As this is a pure virtual class, the factory macros are not relevant (nor possible) to use -// CAF_PDM_HEADER_INIT and CAF_PDM_SOURCE_INIT -// -//================================================================================================== -class RimReservoir : public caf::PdmObject -{ - -public: - RimReservoir(); - virtual ~RimReservoir(); - - virtual bool openEclipseGridFile() = 0; - - RigReservoir* reservoirData(); - const RigReservoir* reservoirData() const; - - RimReservoirView* createAndAddReservoirView(); - void removeReservoirView(RimReservoirView* reservoirView); - - void removeResult(const QString& resultName); - - // Fields: - caf::PdmField caseName; - caf::PdmField releaseResultMemory; - - caf::PdmPointersField reservoirViews; - - virtual caf::PdmFieldHandle* userDescriptionField() { return &caseName; } - - virtual QString locationOnDisc() const { return QString(); } - -protected: - // Overridden methods - virtual void initAfterRead(); - - virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); - -protected: - cvf::ref m_rigReservoir; -}; - diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp new file mode 100644 index 0000000000..38c20c8256 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp @@ -0,0 +1,731 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RimReservoirCellResultsCacher.h" +#include "RigCaseCellResultsData.h" +#include "RiaApplication.h" +#include "RigMainGrid.h" +#include "RigCell.h" +#include "cafProgressInfo.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; + QString projectFileName = RiaApplication::instance()->project()->fileName(); + QFileInfo fileInfo(projectFileName); + cacheDirPath = fileInfo.canonicalPath(); + cacheDirPath += "/" + fileInfo.completeBaseName() + "_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; + + 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; + } + else + { + soilResultValueCount = swatForTimeStep->size(); + soilTimeStepCount = m_cellResults->infoForEachResultIndex()[scalarIndexSWAT].m_timeStepDates.size(); + } + } + + if (scalarIndexSGAS != cvf::UNDEFINED_SIZE_T) + { + sgasForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSGAS, timeStepIndex)); + if (sgasForTimeStep->size() == 0) + { + sgasForTimeStep = NULL; + } + else + { + 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& 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(); +} + + +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/RimReservoirCellResultsCacher.h new file mode 100644 index 0000000000..2806b145f6 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.h @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafAppEnum.h" +#include "RimDefines.h" + +class RimReservoirCellResultsStorageEntryInfo; +class RigCaseCellResultsData; +class RifReaderInterface; +class RigMainGrid; + +class RimReservoirCellResultsStorage : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimReservoirCellResultsStorage(); + virtual ~RimReservoirCellResultsStorage(); + + void setCellResults(RigCaseCellResultsData* cellResults); + RigCaseCellResultsData* cellResults() { return m_cellResults; } + const RigCaseCellResultsData* cellResults() const { return m_cellResults; } + + size_t storedResultsCount(); + + void setMainGrid(RigMainGrid* mainGrid); + + void setReaderInterface(RifReaderInterface* readerInterface); + RifReaderInterface* readerInterface(); + + void loadOrComputeSOIL(); + void computeDepthRelatedResults(); + + size_t findOrLoadScalarResultForTimeStep(RimDefines::ResultCatType type, const QString& resultName, size_t timeStepIndex); + size_t findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName); + size_t findOrLoadScalarResult(const QString& resultName); ///< Simplified search. Assumes unique names across types. + +protected: + // Overridden methods from PdmObject + virtual void setupBeforeSave(); + +private: + void computeSOILForTimeStep(size_t timeStepIndex); + + QString getValidCacheFileName(); + QString getCacheDirectoryPath(); + + // Fields + caf::PdmField m_resultCacheFileName; + caf::PdmPointersField + m_resultCacheMetaData; + + cvf::ref m_readerInterface; + RigCaseCellResultsData* m_cellResults; + RigMainGrid* m_ownerMainGrid; +}; + +class RimReservoirCellResultsStorageEntryInfo : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimReservoirCellResultsStorageEntryInfo(); + virtual ~RimReservoirCellResultsStorageEntryInfo(); + + caf::PdmField > m_resultType; + caf::PdmField m_resultName; + caf::PdmField< std::vector > m_timeStepDates; + caf::PdmField m_filePosition; +}; + diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index ecad221c2f..f6d4d84849 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -16,15 +16,15 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RIViewer.h" +#include "RiaStdInclude.h" +#include "RiuViewer.h" #include "RimReservoirView.h" -#include "RIMainWindow.h" +#include "RiuMainWindow.h" #include "RigGridBase.h" -#include "RigReservoir.h" -#include "RIApplication.h" -#include "RIPreferences.h" +#include "RigCaseData.h" +#include "RiaApplication.h" +#include "RiaPreferences.h" #include "cafEffectGenerator.h" #include "cafFrameAnimationControl.h" @@ -32,7 +32,7 @@ #include "RimCellRangeFilterCollection.h" #include "cvfStructGridGeometryGenerator.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "RivCellEdgeEffectGenerator.h" #include "RimCellEdgeResultSlot.h" #include "cvfqtUtils.h" @@ -41,7 +41,7 @@ #include "cafCadNavigation.h" #include "cafCeetronNavigation.h" -#include "RimReservoir.h" +#include "RimCase.h" #include "Rim3dOverlayInfoConfig.h" #include "RigGridScalarDataAccess.h" @@ -82,8 +82,8 @@ CAF_PDM_SOURCE_INIT(RimReservoirView, "ReservoirView"); //-------------------------------------------------------------------------------------------------- RimReservoirView::RimReservoirView() { - RIApplication* app = RIApplication::instance(); - RIPreferences* preferences = app->preferences(); + RiaApplication* app = RiaApplication::instance(); + RiaPreferences* preferences = app->preferences(); CVF_ASSERT(preferences); CAF_PDM_InitObject("Reservoir View", ":/ReservoirView.png", "", ""); @@ -137,6 +137,9 @@ RimReservoirView::RimReservoirView() CAF_PDM_InitField(&showInactiveCells, "ShowInactiveCells", false, "Show Inactive Cells", "", "", ""); CAF_PDM_InitField(&showInvalidCells, "ShowInvalidCells", false, "Show Invalid Cells", "", "", ""); + CAF_PDM_InitField(&backgroundColor, "ViewBackgroundColor", cvf::Color3f(0.69f, 0.77f, 0.87f), "Viewer Background", "", "", ""); + + CAF_PDM_InitField(&cameraPosition, "CameraPosition", cvf::Mat4d::IDENTITY, "", "", "", ""); @@ -169,7 +172,7 @@ RimReservoirView::~RimReservoirView() if (m_viewer) { - RIMainWindow::instance()->removeViewer(m_viewer); + RiuMainWindow::instance()->removeViewer(m_viewer); } m_geometry->clearGeometryCache(); @@ -189,19 +192,19 @@ void RimReservoirView::updateViewerWidget() if (!m_viewer) { QGLFormat glFormat; - glFormat.setDirectRendering(RIApplication::instance()->useShaders()); + glFormat.setDirectRendering(RiaApplication::instance()->useShaders()); - m_viewer = new RIViewer(glFormat, NULL); + m_viewer = new RiuViewer(glFormat, NULL); m_viewer->setOwnerReservoirView(this); - RIMainWindow::instance()->addViewer(m_viewer); + RiuMainWindow::instance()->addViewer(m_viewer); m_viewer->setMinNearPlaneDistance(10); this->cellResult()->legendConfig->recreateLegend(); this->cellEdgeResult()->legendConfig->recreateLegend(); m_viewer->setColorLegend1(this->cellResult()->legendConfig->legend()); m_viewer->setColorLegend2(this->cellEdgeResult()->legendConfig->legend()); - if (RIApplication::instance()->navigationPolicy() == RIApplication::NAVIGATION_POLICY_CEETRON) + if (RiaApplication::instance()->navigationPolicy() == RiaApplication::NAVIGATION_POLICY_CEETRON) { m_viewer->setNavigationPolicy(new caf::CeetronNavigation); } @@ -210,16 +213,18 @@ void RimReservoirView::updateViewerWidget() m_viewer->setNavigationPolicy(new caf::CadNavigation); } - m_viewer->enablePerfInfoHud(RIApplication::instance()->showPerformanceInfo()); + m_viewer->enablePerfInfoHud(RiaApplication::instance()->showPerformanceInfo()); //m_viewer->layoutWidget()->showMaximized(); isViewerCreated = true; } - RIMainWindow::instance()->setActiveViewer(m_viewer); + RiuMainWindow::instance()->setActiveViewer(m_viewer); if (isViewerCreated) m_viewer->mainCamera()->setViewMatrix(cameraPosition); + m_viewer->mainCamera()->viewport()->setClearColor(cvf::Color4f(backgroundColor())); + m_viewer->update(); } else @@ -250,7 +255,7 @@ void RimReservoirView::updateViewerWidgetWindowTitle() QString windowTitle; if (m_reservoir.notNull()) { - windowTitle = QString("%1 - %2").arg(m_reservoir->caseName()).arg(name); + windowTitle = QString("%1 - %2").arg(m_reservoir->caseUserDescription()).arg(name); } else { @@ -267,11 +272,11 @@ void RimReservoirView::updateViewerWidgetWindowTitle() void RimReservoirView::clampCurrentTimestep() { // Clamp the current timestep to actual possibilities - if (this->gridCellResults()) + if (this->currentGridCellResults()->cellResults()) { - if (m_currentTimeStep() > this->gridCellResults()->maxTimeStepCount()) + if (m_currentTimeStep() >= static_cast(this->currentGridCellResults()->cellResults()->maxTimeStepCount())) { - m_currentTimeStep = static_cast(this->gridCellResults()->maxTimeStepCount()) -1; + m_currentTimeStep = static_cast(this->currentGridCellResults()->cellResults()->maxTimeStepCount()) -1; } } @@ -298,7 +303,7 @@ void RimReservoirView::createDisplayModelAndRedraw() } } - RIMainWindow::instance()->refreshAnimationActions(); + RiuMainWindow::instance()->refreshAnimationActions(); } //-------------------------------------------------------------------------------------------------- @@ -358,6 +363,13 @@ void RimReservoirView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, createDisplayModelAndRedraw(); } } + else if (changedField == &backgroundColor ) + { + if (viewer() != NULL) + { + updateViewerWidget(); + } + } else if (changedField == &m_currentTimeStep) { if (m_viewer) @@ -448,10 +460,10 @@ void RimReservoirView::createDisplayModel() || this->propertyFilterCollection()->hasActiveDynamicFilters() || this->wellCollection->hasVisibleWellPipes()) { - CVF_ASSERT(gridCellResults()); + CVF_ASSERT(currentGridCellResults()); size_t i; - for (i = 0; i < gridCellResults()->maxTimeStepCount(); i++) + for (i = 0; i < currentGridCellResults()->cellResults()->maxTimeStepCount(); i++) { timeStepIndices.push_back(i); } @@ -690,16 +702,18 @@ void RimReservoirView::loadDataAndUpdate() { if (!m_reservoir->openEclipseGridFile()) { - QMessageBox::warning(RIMainWindow::instance(), "Error when opening project file", "Could not open the Eclipse Grid file (EGRID/GRID): \n"+ m_reservoir->caseName()); + QMessageBox::warning(RiuMainWindow::instance(), + "Error when opening project file", + "Could not open the Eclipse Grid file: \n"+ m_reservoir->gridFileName()); m_reservoir = NULL; return; } else { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); if (app->preferences()->autocomputeSOIL) { - RigReservoirCellResults* results = gridCellResults(); + RimReservoirCellResultsStorage* results = currentGridCellResults(); CVF_ASSERT(results); results->loadOrComputeSOIL(); } @@ -709,7 +723,7 @@ void RimReservoirView::loadDataAndUpdate() CVF_ASSERT(this->cellResult() != NULL); this->cellResult()->loadResult(); - if (m_reservoir->reservoirData()->mainGrid()->globalFractureModelActiveCellCount() == 0) + if (m_reservoir->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->globalActiveCellCount() == 0) { this->cellResult->porosityModel.setUiHidden(true); } @@ -820,7 +834,7 @@ void RimReservoirView::updateStaticCellColors(unsigned short geometryType) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIViewer* RimReservoirView::viewer() +RiuViewer* RimReservoirView::viewer() { return m_viewer; } @@ -835,20 +849,20 @@ bool RimReservoirView::pickInfo(size_t gridIndex, size_t cellIndex, const cvf::V if (m_reservoir) { - const RigReservoir* reservoir = m_reservoir->reservoirData(); - if (reservoir) + const RigCaseData* eclipseCase = m_reservoir->reservoirData(); + if (eclipseCase) { size_t i = 0; size_t j = 0; size_t k = 0; - if (reservoir->grid(gridIndex)->ijkFromCellIndex(cellIndex, &i, &j, &k)) + if (eclipseCase->grid(gridIndex)->ijkFromCellIndex(cellIndex, &i, &j, &k)) { // Adjust to 1-based Eclipse indexing i++; j++; k++; - cvf::Vec3d domainCoord = point + reservoir->grid(gridIndex)->displayModelOffset(); + cvf::Vec3d domainCoord = point + eclipseCase->grid(gridIndex)->displayModelOffset(); pickInfoText->sprintf("Hit grid %u, cell [%u, %u, %u], intersection point: [E: %.2f, N: %.2f, Depth: %.2f]", static_cast(gridIndex), static_cast(i), static_cast(j), static_cast(k), domainCoord.x(), domainCoord.y(), -domainCoord.z()); return true; @@ -862,18 +876,19 @@ bool RimReservoirView::pickInfo(size_t gridIndex, size_t cellIndex, const cvf::V //-------------------------------------------------------------------------------------------------- /// Get the current scalar value for the display face at the given index //-------------------------------------------------------------------------------------------------- -void RimReservoirView::appendCellResultInfo(size_t gridIndex, size_t cellIndex, QString* resultInfoText) const +void RimReservoirView::appendCellResultInfo(size_t gridIndex, size_t cellIndex, QString* resultInfoText) { CVF_ASSERT(resultInfoText); if (m_reservoir && m_reservoir->reservoirData()) { - const RigReservoir* reservoir = m_reservoir->reservoirData(); - const RigGridBase* grid = reservoir->grid(gridIndex); + RigCaseData* eclipseCase = m_reservoir->reservoirData(); + RigGridBase* grid = eclipseCase->grid(gridIndex); + if (this->cellResult()->hasResult()) { - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); - cvf::ref dataAccessObject = grid->dataAccessObject(porosityModel, m_currentTimeStep, this->cellResult()->gridScalarIndex()); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); + cvf::ref dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, m_currentTimeStep, this->cellResult()->gridScalarIndex()); if (dataAccessObject.notNull()) { double scalarValue = dataAccessObject->cellScalar(cellIndex); @@ -893,8 +908,8 @@ void RimReservoirView::appendCellResultInfo(size_t gridIndex, size_t cellIndex, if (resultIndices[idx] == cvf::UNDEFINED_SIZE_T) continue; // Cell edge results are static, results are loaded for first time step only - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); - cvf::ref dataAccessObject = grid->dataAccessObject(porosityModel, 0, resultIndices[idx]); + 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); @@ -957,16 +972,30 @@ void RimReservoirView::setupBeforeSave() //-------------------------------------------------------------------------------------------------- /// Convenience for quick access to results //-------------------------------------------------------------------------------------------------- -RigReservoirCellResults* RimReservoirView::gridCellResults() +RimReservoirCellResultsStorage* RimReservoirView::currentGridCellResults() +{ + if (m_reservoir) + { + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult->porosityModel()); + + return m_reservoir->results(porosityModel); + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellInfo* RimReservoirView::currentActiveCellInfo() { if (m_reservoir && - m_reservoir->reservoirData() && - m_reservoir->reservoirData()->mainGrid() + m_reservoir->reservoirData() ) { - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResult->porosityModel()); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult->porosityModel()); - return m_reservoir->reservoirData()->mainGrid()->results(porosityModel); + return m_reservoir->reservoirData()->activeCellInfo(porosityModel); } return NULL; @@ -1032,11 +1061,11 @@ void RimReservoirView::updateLegends() return; } - RigReservoir* reservoir = m_reservoir->reservoirData(); - CVF_ASSERT(reservoir); + RigCaseData* eclipseCase = m_reservoir->reservoirData(); + CVF_ASSERT(eclipseCase); - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); - RigReservoirCellResults* results = reservoir->mainGrid()->results(porosityModel); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); + RigCaseCellResultsData* results = eclipseCase->results(porosityModel); CVF_ASSERT(results); if (this->cellResult()->hasResult()) @@ -1085,7 +1114,7 @@ void RimReservoirView::updateLegends() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimReservoirView::setEclipseCase(RimReservoir* reservoir) +void RimReservoirView::setEclipseCase(RimCase* reservoir) { m_reservoir = reservoir; } @@ -1093,7 +1122,7 @@ void RimReservoirView::setEclipseCase(RimReservoir* reservoir) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimReservoir* RimReservoirView::eclipseCase() +RimCase* RimReservoirView::eclipseCase() { return m_reservoir; } @@ -1115,7 +1144,7 @@ void RimReservoirView::syncronizeWellsWithResults() { if (!(m_reservoir && m_reservoir->reservoirData()) ) return; - cvf::Collection wellResults = m_reservoir->reservoirData()->wellResults(); + cvf::Collection wellResults = m_reservoir->reservoirData()->wellResults(); // Find corresponding well from well result, or create a new size_t wIdx; @@ -1137,7 +1166,7 @@ void RimReservoirView::syncronizeWellsWithResults() for (wIdx = 0; wIdx < this->wellCollection()->wells().size(); ++wIdx) { RimWell* well = this->wellCollection()->wells()[wIdx]; - RigWellResults* wellRes = well->wellResults(); + RigSingleWellResultsData* wellRes = well->wellResults(); if (wellRes == NULL) { delete well; @@ -1171,13 +1200,17 @@ void RimReservoirView::calculateVisibleWellCellsIncFence(cvf::UByteArray* visibl // If all wells are forced off, return if (this->wellCollection()->wellCellVisibility() == RimWellCollection::FORCE_ALL_OFF) return; + RigActiveCellInfo* activeCellInfo = this->currentActiveCellInfo(); + + CVF_ASSERT(activeCellInfo); + // Loop over the wells and find their contribution for (size_t wIdx = 0; wIdx < this->wellCollection()->wells().size(); ++wIdx) { RimWell* well = this->wellCollection()->wells()[wIdx]; if (this->wellCollection()->wellCellVisibility() == RimWellCollection::FORCE_ALL_ON || well->showWellCells()) { - RigWellResults* wres = well->wellResults(); + RigSingleWellResultsData* wres = well->wellResults(); if (!wres) continue; const std::vector< RigWellResultFrame >& wellResFrames = wres->m_wellCellsTimeSteps; @@ -1235,7 +1268,9 @@ void RimReservoirView::calculateVisibleWellCellsIncFence(cvf::UByteArray* visibl for ( fIdx = 0; fIdx < cellCountFenceDirection; ++fIdx) { size_t fenceCellIndex = grid->cellIndexFromIJK(*pI,*pJ,*pK); - if (grid->cell(fenceCellIndex).isActiveInMatrixModel()) + size_t globalGridCellIndex = grid->globalGridCellIndex(fenceCellIndex); + + if (activeCellInfo && activeCellInfo->isActive(globalGridCellIndex)) { (*visibleCells)[fenceCellIndex] = true; } @@ -1249,3 +1284,24 @@ void RimReservoirView::calculateVisibleWellCellsIncFence(cvf::UByteArray* visibl } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirView::updateDisplayModelForWellResults() +{ + m_geometry->clearGeometryCache(); + m_pipesPartManager->clearGeometryCache(); + + syncronizeWellsWithResults(); + + createDisplayModel(); + updateDisplayModelVisibility(); + + overlayInfoConfig()->update3DInfo(); + + if (animationMode && m_viewer) + { + m_viewer->slotSetCurrentFrame(m_currentTimeStep); + } +} + diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.h b/ApplicationCode/ProjectDataModel/RimReservoirView.h index 2dcb730882..c77a67d263 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.h +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.h @@ -23,7 +23,7 @@ #include #include -#include "RimReservoir.h" +#include "RimCase.h" #include "RimResultSlot.h" #include "RimCellEdgeResultSlot.h" #include "RimCellRangeFilter.h" @@ -39,7 +39,7 @@ #include "RivReservoirViewPartMgr.h" #include "RivReservoirPipesPartMgr.h" -class RIViewer; +class RiuViewer; class RigGridBase; class RigGridCellFaceVisibilityFilter; class RivReservoirViewPartMgr; @@ -51,7 +51,6 @@ namespace cvf class ModelBasicList; } - enum ViewState { GEOMETRY_ONLY, @@ -85,97 +84,103 @@ public: NO_SURFACE }; - // Public fields: + // Fields containing child objects : - caf::PdmField cellResult; - caf::PdmField cellEdgeResult; - caf::PdmField overlayInfoConfig; + caf::PdmField cellResult; + caf::PdmField cellEdgeResult; - caf::PdmField scaleZ; - caf::PdmField showWindow; - caf::PdmField name; + caf::PdmField rangeFilterCollection; + caf::PdmField propertyFilterCollection; - // Visibility - caf::PdmField showInvalidCells; - caf::PdmField showInactiveCells; - caf::PdmField showMainGrid; + caf::PdmField wellCollection; - caf::PdmField wellCollection; + caf::PdmField overlayInfoConfig; - caf::PdmField rangeFilterCollection; - caf::PdmField propertyFilterCollection; + // Visualization setup fields - caf::PdmField< caf::AppEnum< MeshModeType > > meshMode; - caf::PdmField< caf::AppEnum< SurfaceModeType > > surfaceMode; + caf::PdmField name; + caf::PdmField scaleZ; + caf::PdmField showWindow; + + caf::PdmField showInvalidCells; + caf::PdmField showInactiveCells; + caf::PdmField showMainGrid; + + caf::PdmField< caf::AppEnum< MeshModeType > > meshMode; + caf::PdmField< caf::AppEnum< SurfaceModeType > > surfaceMode; + + caf::PdmField< cvf::Color3f > backgroundColor; + + caf::PdmField cameraPosition; + + caf::PdmField maximumFrameRate; + caf::PdmField animationMode; + + // Access internal objects + RimReservoirCellResultsStorage* currentGridCellResults(); + RigActiveCellInfo* currentActiveCellInfo(); + + void setEclipseCase(RimCase* reservoir); + RimCase* eclipseCase(); // Animation - caf::PdmField maximumFrameRate; - caf::PdmField animationMode; - - int currentTimeStep() { return m_currentTimeStep;} - void setCurrentTimeStep(int frameIdx); - void updateCurrentTimeStepAndRedraw(); - void endAnimation(); + int currentTimeStep() { return m_currentTimeStep;} + void setCurrentTimeStep(int frameIdx); + void updateCurrentTimeStepAndRedraw(); + void endAnimation(); // 3D Viewer - // Cam pos should be a field, but is not yet supported bu caf::Pdm - caf::PdmField cameraPosition; - void setDefaultView(); - - RIViewer* viewer(); - void updateViewerWidget(); - void updateViewerWidgetWindowTitle(); + RiuViewer* viewer(); + void updateViewerWidget(); + void updateViewerWidgetWindowTitle(); + void setDefaultView(); // Picking info - bool pickInfo(size_t gridIndex, size_t cellIndex, const cvf::Vec3d& point, QString* pickInfoText) const; - void appendCellResultInfo(size_t gridIndex, size_t cellIndex, QString* resultInfoText) const; - - RigReservoirCellResults* gridCellResults(); - - void setEclipseCase(RimReservoir* reservoir); - RimReservoir* eclipseCase(); - - void calculateVisibleWellCellsIncFence(cvf::UByteArray* visibleCells, RigGridBase * grid); + bool pickInfo(size_t gridIndex, size_t cellIndex, const cvf::Vec3d& point, QString* pickInfoText) const; + void appendCellResultInfo(size_t gridIndex, size_t cellIndex, QString* resultInfoText) ; + // Does this belong here, really ? + void calculateVisibleWellCellsIncFence(cvf::UByteArray* visibleCells, RigGridBase * grid); // Display model generation public: - void loadDataAndUpdate(); - void createDisplayModelAndRedraw(); - void scheduleGeometryRegen(unsigned short geometryType); - void schedulePipeGeometryRegen(); + void loadDataAndUpdate(); + void createDisplayModelAndRedraw(); + void scheduleGeometryRegen(unsigned short geometryType); + void schedulePipeGeometryRegen(); + void updateDisplayModelForWellResults(); + + + // Display model generation +private: + void createDisplayModel(); + void updateDisplayModelVisibility(); + void updateCurrentTimeStep(); + void indicesToVisibleGrids(std::vector* gridIndices); + void updateScaleTransform(); + void updateStaticCellColors(); + void updateStaticCellColors(unsigned short geometryType); + void updateLegends(); + + cvf::ref m_geometry; + cvf::ref m_pipesPartManager; // Overridden PDM methods: public: - virtual caf::PdmFieldHandle* userDescriptionField() { return &name;} - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual caf::PdmFieldHandle* userDescriptionField() { return &name;} + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); protected: - virtual void initAfterRead(); - virtual void setupBeforeSave(); + virtual void initAfterRead(); + virtual void setupBeforeSave(); + // Really private +private: + void syncronizeWellsWithResults(); + void clampCurrentTimestep(); private: - void syncronizeWellsWithResults(); - void clampCurrentTimestep(); - -private: - caf::PdmField m_currentTimeStep; - QPointer m_viewer; - caf::PdmPointer m_reservoir; - - -// Display model generation -private: - void createDisplayModel(); - void updateDisplayModelVisibility(); - void updateCurrentTimeStep(); - void indicesToVisibleGrids(std::vector* gridIndices); - void updateScaleTransform(); - void updateStaticCellColors(); - void updateStaticCellColors(unsigned short geometryType); - void updateLegends(); - - cvf::ref m_geometry; - cvf::ref m_pipesPartManager; + caf::PdmField m_currentTimeStep; + QPointer m_viewer; + caf::PdmPointer m_reservoir; }; diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.cpp b/ApplicationCode/ProjectDataModel/RimResultCase.cpp new file mode 100644 index 0000000000..1d16fda647 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimResultCase.cpp @@ -0,0 +1,307 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RimResultCase.h" +#include "RigCaseData.h" +#include "RifReaderEclipseOutput.h" +#include "RigCaseCellResultsData.h" +#include "RimReservoirView.h" +#include "RifReaderMockModel.h" +#include "RifReaderEclipseInput.h" +#include "cafProgressInfo.h" +#include "RimProject.h" +#include "RifEclipseOutputFileTools.h" +#include "RiaApplication.h" + + +CAF_PDM_SOURCE_INIT(RimResultCase, "EclipseCase"); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimResultCase::RimResultCase() + : RimCase() +{ + CAF_PDM_InitObject("Eclipse Case", ":/AppLogo48x48.png", "", ""); + + CAF_PDM_InitField(&caseFileName, "CaseFileName", QString(), "Case file name", "", "" ,""); + caseFileName.setUiReadOnly(true); + + // Obsolete, unused field + CAF_PDM_InitField(&caseDirectory, "CaseFolder", QString(), "Directory", "", "" ,""); + caseDirectory.setIOWritable(false); + caseDirectory.setUiHidden(true); + + m_activeCellInfoIsReadFromFile = false; + m_gridAndWellDataIsReadFromFile = false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimResultCase::openEclipseGridFile() +{ + caf::ProgressInfo progInfo(50, "Reading Eclipse Grid File"); + + progInfo.setProgressDescription("Open Grid File"); + progInfo.setNextProgressIncrement(48); + + // Early exit if data is already read + if (m_gridAndWellDataIsReadFromFile) return true; + + cvf::ref readerInterface; + + if (caseFileName().contains("Result Mock Debug Model")) + { + readerInterface = this->createMockModel(this->caseFileName()); + } + else + { + if (!QFile::exists(caseFileName())) + { + return false; + } + + cvf::ref eclipseCase = new RigCaseData; + readerInterface = new RifReaderEclipseOutput; + if (!readerInterface->open(caseFileName(), eclipseCase.p())) + { + return false; + } + + this->setReservoirData( eclipseCase.p() ); + } + + results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); + results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); + + progInfo.incrementProgress(); + + CVF_ASSERT(this->reservoirData()); + CVF_ASSERT(readerInterface.notNull()); + + progInfo.setProgressDescription("Computing Case Cache"); + computeCachedData(); + + m_gridAndWellDataIsReadFromFile = true; + m_activeCellInfoIsReadFromFile = true; + + return true; + } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimResultCase::openAndReadActiveCellData(RigCaseData* mainEclipseCase) +{ + // Early exit if data is already read + if (m_activeCellInfoIsReadFromFile) return true; + + cvf::ref readerInterface; + if (caseFileName().contains("Result Mock Debug Model")) + { + readerInterface = this->createMockModel(this->caseFileName()); + } + else + { + if (!QFile::exists(caseFileName())) + { + return false; + } + + cvf::ref eclipseCase = new RigCaseData; + + CVF_ASSERT(mainEclipseCase && mainEclipseCase->mainGrid()); + eclipseCase->setMainGrid(mainEclipseCase->mainGrid()); + + size_t scalarIndexWithMaxTimeStepCount = cvf::UNDEFINED_SIZE_T; + mainEclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->maxTimeStepCount(&scalarIndexWithMaxTimeStepCount); + if (scalarIndexWithMaxTimeStepCount == cvf::UNDEFINED_SIZE_T) + { + return false; + } + + std::vector timeStepDates = mainEclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->timeStepDates(scalarIndexWithMaxTimeStepCount); + + cvf::ref readerEclipseOutput = new RifReaderEclipseOutput; + if (!readerEclipseOutput->openAndReadActiveCellData(caseFileName(), timeStepDates, eclipseCase.p())) + { + return false; + } + + readerEclipseOutput->close(); + + this->setReservoirData( eclipseCase.p() ); + + readerInterface = readerEclipseOutput; + } + + results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); + results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); + + CVF_ASSERT(this->reservoirData()); + CVF_ASSERT(readerInterface.notNull()); + + reservoirData()->computeActiveCellBoundingBoxes(); + + m_activeCellInfoIsReadFromFile = true; + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RimResultCase::createMockModel(QString modelName) +{ + cvf::ref mockFileInterface = new RifReaderMockModel; + cvf::ref reservoir = new RigCaseData; + + if (modelName == "Result Mock Debug Model Simple") + { + // Create the mock file interface and and RigSerervoir and set them up. + mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(20, 20, 20)); + mockFileInterface->setGridPointDimensions(cvf::Vec3st(4, 5, 6)); + mockFileInterface->addLocalGridRefinement(cvf::Vec3st(0, 2, 2), cvf::Vec3st(0, 2, 2), cvf::Vec3st(3, 3, 3)); + + mockFileInterface->open("", reservoir.p()); + { + size_t idx = reservoir->mainGrid()->cellIndexFromIJK(1, 3, 4); + + //TODO: Rewrite active cell info in mock models + //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); + } + + { + size_t idx = reservoir->mainGrid()->cellIndexFromIJK(2, 2, 3); + + //TODO: Rewrite active cell info in mock models + //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); + } + } + else if (modelName == "Result Mock Debug Model With Results") + { + mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(-20, -20, -20)); + mockFileInterface->setGridPointDimensions(cvf::Vec3st(5, 10, 20)); + mockFileInterface->addLocalGridRefinement(cvf::Vec3st(0, 3, 3), cvf::Vec3st(1, 4, 9), cvf::Vec3st(2, 2, 2)); + mockFileInterface->setResultInfo(3, 10); + + mockFileInterface->open("", reservoir.p()); + + // Make a fault + cvf::Vec3d& tmp = reservoir->mainGrid()->nodes()[1]; + tmp += cvf::Vec3d(1, 0, 0); + } + else if (modelName =="Result Mock Debug Model Large With Results") + { + double startX = 0; + double startY = 0; + double startZ = 0; + + double widthX = 6000; + double widthY = 12000; + double widthZ = 500; + + double offsetX = 0; + double offsetY = 0; + double offsetZ = 0; + + // Test code to simulate UTM coordinates + offsetX = 400000; + offsetY = 6000000; + offsetZ = 0; + + + mockFileInterface->setWorldCoordinates(cvf::Vec3d(startX + offsetX, startY + offsetY, startZ + offsetZ), cvf::Vec3d(startX + widthX + offsetX, startY + widthY + offsetY, startZ + widthZ + offsetZ)); + mockFileInterface->setGridPointDimensions(cvf::Vec3st(50, 100, 200)); + mockFileInterface->addLocalGridRefinement(cvf::Vec3st(0, 30, 30), cvf::Vec3st(1, 40, 90), cvf::Vec3st(2, 2, 2)); + mockFileInterface->setResultInfo(3, 10); + + mockFileInterface->open("", reservoir.p()); + + } + + this->setReservoirData( reservoir.p() ); + + return mockFileInterface.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimResultCase::~RimResultCase() +{ + reservoirViews.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimResultCase::locationOnDisc() const +{ + QFileInfo fi(caseFileName()); + return fi.absolutePath(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimResultCase::readGridDimensions(std::vector< std::vector >& gridDimensions) +{ + RifEclipseOutputFileTools::readGridDimensions(caseFileName(), gridDimensions); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimResultCase::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) +{ + bool foundFile = false; + std::vector searchedPaths; + + // Update filename and folder paths when opening project from a different file location + caseFileName = relocateFile(caseFileName(), newProjectPath, oldProjectPath, &foundFile, &searchedPaths); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimResultCase::setCaseInfo(const QString& userDescription, const QString& caseFileName) +{ + this->caseUserDescription = userDescription; + this->caseFileName = caseFileName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimResultCase::initAfterRead() +{ + RimCase::initAfterRead(); + + // Convert from old (9.0.2) way of storing the case file + if (caseFileName().isEmpty()) + { + if (!this->caseName().isEmpty() && !caseDirectory().isEmpty()) + { + caseFileName = QDir::fromNativeSeparators(caseDirectory()) + "/" + caseName() + ".EGRID"; + } + } +} + diff --git a/ApplicationCode/ProjectDataModel/RimResultCase.h b/ApplicationCode/ProjectDataModel/RimResultCase.h new file mode 100644 index 0000000000..d3db414e87 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimResultCase.h @@ -0,0 +1,67 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "RimCase.h" + +class RifReaderInterface; +class RigMainGrid; + +//================================================================================================== +// +// +// +//================================================================================================== +class RimResultCase : public RimCase +{ + CAF_PDM_HEADER_INIT; + +public: + RimResultCase(); + virtual ~RimResultCase(); + + void setCaseInfo(const QString& userDescription, const QString& caseFileName); + + virtual bool openEclipseGridFile(); + bool openAndReadActiveCellData(RigCaseData* mainEclipseCase); + void readGridDimensions(std::vector< std::vector >& gridDimensions); + + // Overrides from RimCase + virtual QString locationOnDisc() const; + virtual QString gridFileName() const { return caseFileName();} + virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath); + +private: + cvf::ref createMockModel(QString modelName); + + virtual void initAfterRead(); + + // Fields: + caf::PdmField caseFileName; + + // Obsolete field + caf::PdmField caseDirectory; + + bool m_gridAndWellDataIsReadFromFile; + bool m_activeCellInfoIsReadFromFile; +}; diff --git a/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp index 29ec38da4a..6016b2a3a5 100644 --- a/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp @@ -16,14 +16,14 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimResultDefinition.h" #include "RimReservoirView.h" -#include "RimReservoir.h" -#include "RigReservoirCellResults.h" -#include "RigReservoir.h" +#include "RimCase.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" #include "RigMainGrid.h" #include "cafPdmUiListEditor.h" @@ -63,9 +63,9 @@ void RimResultDefinition::setReservoirView(RimReservoirView* 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()->mainGrid() ) + m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS) ) { - if (m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->globalFractureModelActiveCellCount() == 0) + if (m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->globalActiveCellCount() == 0) { porosityModel.setUiHidden(true); } @@ -92,9 +92,9 @@ QList RimResultDefinition::calculateValueOptions(const c { if (fieldNeedingOptions == &resultVariable) { - if (m_reservoirView && m_reservoirView->gridCellResults()) + if (m_reservoirView && m_reservoirView->currentGridCellResults()) { - QStringList varList = m_reservoirView->gridCellResults()->resultNames(resultType()); + QStringList varList = m_reservoirView->currentGridCellResults()->cellResults()->resultNames(resultType()); QList optionList; int i; for (i = 0; i < varList.size(); ++i) @@ -119,8 +119,8 @@ size_t RimResultDefinition::gridScalarIndex() const { if (m_gridScalarResultIndex == cvf::UNDEFINED_SIZE_T) { - const RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults(); - if (gridCellResults) m_gridScalarResultIndex = gridCellResults->findScalarResultIndex(resultType(), resultVariable()); + const RimReservoirCellResultsStorage* gridCellResults = m_reservoirView->currentGridCellResults(); + if (gridCellResults) m_gridScalarResultIndex = gridCellResults->cellResults()->findScalarResultIndex(resultType(), resultVariable()); } return m_gridScalarResultIndex; } @@ -130,7 +130,7 @@ size_t RimResultDefinition::gridScalarIndex() const //-------------------------------------------------------------------------------------------------- void RimResultDefinition::loadResult() { - RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults(); + RimReservoirCellResultsStorage* gridCellResults = m_reservoirView->currentGridCellResults(); if (gridCellResults) { m_gridScalarResultIndex = gridCellResults->findOrLoadScalarResult(resultType(), resultVariable); @@ -148,8 +148,8 @@ void RimResultDefinition::loadResult() //-------------------------------------------------------------------------------------------------- bool RimResultDefinition::hasStaticResult() const { - const RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults(); - if (hasResult() && gridCellResults->timeStepCount(m_gridScalarResultIndex) == 1 ) + const RimReservoirCellResultsStorage* gridCellResults = m_reservoirView->currentGridCellResults(); + if (hasResult() && gridCellResults->cellResults()->timeStepCount(m_gridScalarResultIndex) == 1 ) { return true; } @@ -166,7 +166,7 @@ bool RimResultDefinition::hasResult() const { if (m_gridScalarResultIndex != cvf::UNDEFINED_SIZE_T) return true; - const RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults(); + const RigCaseCellResultsData* gridCellResults = m_reservoirView->currentGridCellResults()->cellResults(); if (gridCellResults) { m_gridScalarResultIndex = gridCellResults->findScalarResultIndex(resultType(), resultVariable()); @@ -182,11 +182,22 @@ bool RimResultDefinition::hasResult() const //-------------------------------------------------------------------------------------------------- bool RimResultDefinition::hasDynamicResult() const { - const RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults(); - if (hasResult() && gridCellResults->timeStepCount(m_gridScalarResultIndex) > 1 ) - return true; - else - return false; + const RigCaseCellResultsData* gridCellResults = m_reservoirView->currentGridCellResults()->cellResults(); + + if (hasResult()) + { + if (resultType() == RimDefines::DYNAMIC_NATIVE) + { + return true; + } + + if (gridCellResults->timeStepCount(m_gridScalarResultIndex) > 1 ) + { + return true; + } + } + + return false; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimResultDefinition.h b/ApplicationCode/ProjectDataModel/RimResultDefinition.h index a9a159935b..138ce0a5ab 100644 --- a/ApplicationCode/ProjectDataModel/RimResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimResultDefinition.h @@ -26,7 +26,7 @@ class RimReservoirView; -class RigReservoirCellResults; +class RigCaseCellResultsData; //================================================================================================== /// diff --git a/ApplicationCode/ProjectDataModel/RimResultReservoir.cpp b/ApplicationCode/ProjectDataModel/RimResultReservoir.cpp deleted file mode 100644 index fb42bda412..0000000000 --- a/ApplicationCode/ProjectDataModel/RimResultReservoir.cpp +++ /dev/null @@ -1,248 +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 "RIStdInclude.h" -#include "RimResultReservoir.h" -#include "RigReservoir.h" -#include "RifReaderEclipseOutput.h" -#include "RigReservoirCellResults.h" -#include "RimReservoirView.h" -#include "RifReaderMockModel.h" -#include "RifReaderEclipseInput.h" -#include "cafProgressInfo.h" -#include "RimProject.h" - - -CAF_PDM_SOURCE_INIT(RimResultReservoir, "EclipseCase"); -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimResultReservoir::RimResultReservoir() - : RimReservoir() -{ - CAF_PDM_InitField(&caseFileName, "CaseFileName", QString(), "Case file name", "", "" ,""); - CAF_PDM_InitField(&caseDirectory, "CaseFolder", QString(), "Directory", "", "" ,""); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimResultReservoir::openEclipseGridFile() -{ - caf::ProgressInfo progInfo(50, "Reading Eclipse Grid File"); - - progInfo.setProgressDescription("Open Grid File"); - progInfo.setNextProgressIncrement(48); - // Early exit if reservoir data is created - if (m_rigReservoir.notNull()) return true; - - cvf::ref readerInterface; - - if (caseName().contains("Result Mock Debug Model")) - { - readerInterface = this->createMockModel(this->caseName()); - - size_t matrixActiveCellCount = 0; - size_t fractureActiveCellCount = 0; - - for (size_t cellIdx = 0; cellIdx < m_rigReservoir->mainGrid()->cells().size(); cellIdx++) - { - const RigCell& cell = m_rigReservoir->mainGrid()->cells()[cellIdx]; - - if (cell.isActiveInMatrixModel()) - { - matrixActiveCellCount++; - } - if (cell.isActiveInFractureModel()) - { - fractureActiveCellCount++; - } - - } - m_rigReservoir->mainGrid()->setGlobalMatrixModelActiveCellCount(matrixActiveCellCount); - m_rigReservoir->mainGrid()->setGlobalFractureModelActiveCellCount(fractureActiveCellCount); - - m_rigReservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); - m_rigReservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); - } - else - { - QString fname = createAbsoluteFilenameFromCase(caseName); - if (fname.isEmpty()) - { - return false; - } - - RigReservoir* reservoir = new RigReservoir; - readerInterface = new RifReaderEclipseOutput; - if (!readerInterface->open(fname, reservoir)) - { - delete reservoir; - return false; - } - - m_rigReservoir = reservoir; - } - - progInfo.incrementProgress(); - - CVF_ASSERT(m_rigReservoir.notNull()); - CVF_ASSERT(readerInterface.notNull()); - - progInfo.setProgressDescription("Computing Faults"); - m_rigReservoir->computeFaults(); - - progInfo.incrementProgress(); - progInfo.setProgressDescription("Computing Cache"); - m_rigReservoir->mainGrid()->computeCachedData(); - - return true; - } - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref RimResultReservoir::createMockModel(QString modelName) -{ - cvf::ref mockFileInterface = new RifReaderMockModel; - cvf::ref reservoir = new RigReservoir; - - if (modelName == "Result Mock Debug Model Simple") - { - // Create the mock file interface and and RigSerervoir and set them up. - mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(20, 20, 20)); - mockFileInterface->setGridPointDimensions(cvf::Vec3st(4, 5, 6)); - mockFileInterface->addLocalGridRefinement(cvf::Vec3st(0, 2, 2), cvf::Vec3st(0, 2, 2), cvf::Vec3st(3, 3, 3)); - - mockFileInterface->open("", reservoir.p()); - { - size_t idx = reservoir->mainGrid()->cellIndexFromIJK(1, 3, 4); - reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); - } - - { - size_t idx = reservoir->mainGrid()->cellIndexFromIJK(2, 2, 3); - reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); - } - } - else if (modelName == "Result Mock Debug Model With Results") - { - mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(-20, -20, -20)); - mockFileInterface->setGridPointDimensions(cvf::Vec3st(5, 10, 20)); - mockFileInterface->addLocalGridRefinement(cvf::Vec3st(0, 3, 3), cvf::Vec3st(1, 4, 9), cvf::Vec3st(2, 2, 2)); - mockFileInterface->setResultInfo(3, 10); - - mockFileInterface->open("", reservoir.p()); - - // Make a fault - cvf::Vec3d& tmp = reservoir->mainGrid()->nodes()[1]; - tmp += cvf::Vec3d(1, 0, 0); - } - else if (modelName =="Result Mock Debug Model Large With Results") - { - double startX = 0; - double startY = 0; - double startZ = 0; - - double widthX = 6000; - double widthY = 12000; - double widthZ = 500; - - double offsetX = 0; - double offsetY = 0; - double offsetZ = 0; - - // Test code to simulate UTM coordinates - offsetX = 400000; - offsetY = 6000000; - offsetZ = 0; - - - mockFileInterface->setWorldCoordinates(cvf::Vec3d(startX + offsetX, startY + offsetY, startZ + offsetZ), cvf::Vec3d(startX + widthX + offsetX, startY + widthY + offsetY, startZ + widthZ + offsetZ)); - mockFileInterface->setGridPointDimensions(cvf::Vec3st(50, 100, 200)); - mockFileInterface->addLocalGridRefinement(cvf::Vec3st(0, 30, 30), cvf::Vec3st(1, 40, 90), cvf::Vec3st(2, 2, 2)); - mockFileInterface->setResultInfo(3, 10); - - mockFileInterface->open("", reservoir.p()); - - } - - m_rigReservoir = reservoir; - - return mockFileInterface.p(); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimResultReservoir::~RimResultReservoir() -{ - reservoirViews.deleteAllChildObjects(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimResultReservoir::locationOnDisc() const -{ - return caseDirectory; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimResultReservoir::createAbsoluteFilenameFromCase(const QString& caseName) -{ - QString candidate; - - candidate = QDir::fromNativeSeparators(caseDirectory.v() + QDir::separator() + caseName + ".EGRID"); - if (QFile::exists(candidate)) return candidate; - - candidate = QDir::fromNativeSeparators(caseDirectory.v() + QDir::separator() + caseName + ".GRID"); - if (QFile::exists(candidate)) return candidate; - - std::vector parentObjects; - this->parentObjects(parentObjects); - - QString projectPath; - for (size_t i = 0; i < parentObjects.size(); i++) - { - caf::PdmObject* obj = parentObjects[i]; - RimProject* proj = dynamic_cast(obj); - if (proj) - { - QFileInfo fi(proj->fileName); - projectPath = fi.path(); - } - } - - if (!projectPath.isEmpty()) - { - candidate = QDir::fromNativeSeparators(projectPath + QDir::separator() + caseName + ".EGRID"); - if (QFile::exists(candidate)) return candidate; - - candidate = QDir::fromNativeSeparators(projectPath + QDir::separator() + caseName + ".GRID"); - if (QFile::exists(candidate)) return candidate; - } - - return QString(); -} - diff --git a/ApplicationCode/ProjectDataModel/RimResultSlot.cpp b/ApplicationCode/ProjectDataModel/RimResultSlot.cpp index 9d1564a564..3e7cbac4ff 100644 --- a/ApplicationCode/ProjectDataModel/RimResultSlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultSlot.cpp @@ -16,13 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimResultSlot.h" #include "RimLegendConfig.h" #include "RimReservoirView.h" -#include "RimReservoir.h" -#include "RIMainWindow.h" +#include "RimCase.h" +#include "RiuMainWindow.h" #include "RimUiTreeModelPdm.h" @@ -91,7 +91,7 @@ void RimResultSlot::changeLegendConfig(QString resultVarNameOfNewLegend) m_legendConfigData.v().erase(it); m_legendConfigData.v().push_back(this->legendConfig()); this->legendConfig = newLegend; - RIMainWindow::instance()->uiPdmModel()->rebuildUiSubTree(this); + RiuMainWindow::instance()->uiPdmModel()->rebuildUiSubTree(this); found = true; break; } @@ -105,7 +105,7 @@ void RimResultSlot::changeLegendConfig(QString resultVarNameOfNewLegend) newLegend->resultVariableName = resultVarNameOfNewLegend; m_legendConfigData.v().push_back(this->legendConfig()); this->legendConfig = newLegend; - RIMainWindow::instance()->uiPdmModel()->rebuildUiSubTree(this); + RiuMainWindow::instance()->uiPdmModel()->rebuildUiSubTree(this); } } diff --git a/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp b/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp index f7e6a2e344..e267ab6389 100644 --- a/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp @@ -16,13 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimScriptCollection.h" #include "cafPdmField.h" #include "cafUtils.h" -#include "RIMainWindow.h" +#include "RiuMainWindow.h" #include "RimUiTreeModelPdm.h" #include "cafPdmUiFilePathEditor.h" @@ -161,7 +161,7 @@ void RimScriptCollection::fieldChangedByUi(const caf::PdmFieldHandle *changedFie QFileInfo fi(directory); this->setUiName(fi.baseName()); this->readContentFromDisc(); - RimUiTreeModelPdm* treeModel = RIMainWindow::instance()->uiPdmModel(); + RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); if (treeModel) treeModel->rebuildUiSubTree(this); } } diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCase.cpp b/ApplicationCode/ProjectDataModel/RimStatisticsCase.cpp new file mode 100644 index 0000000000..5dfa809860 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCase.cpp @@ -0,0 +1,681 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "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" + +namespace caf { + template<> + void caf::AppEnum::setUp() + { + addItem(RimStatisticsCase::NEAREST_OBSERVATION, "NearestObservationPercentile", "Nearest Observation"); + addItem(RimStatisticsCase::HISTOGRAM_ESTIMATED, "HistogramEstimatedPercentile", "Histogram based estimate"); + setDefault(RimStatisticsCase::NEAREST_OBSERVATION); + } +} + + +CAF_PDM_SOURCE_INIT(RimStatisticsCase, "RimStatisticalCalculation"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCase::RimStatisticsCase() + : RimCase() +{ + CAF_PDM_InitObject("Case Group Statistics", ":/Histogram16x16.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_calculateEditCommand, "m_editingAllowed", "", "", "", ""); + m_calculateEditCommand.setIOWritable(false); + m_calculateEditCommand.setIOReadable(false); + m_calculateEditCommand.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + m_calculateEditCommand.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + + m_calculateEditCommand = false; + + CAF_PDM_InitField(&m_selectionSummary, "SelectionSummary", QString(""), "Summary of calculation setup", "", "", ""); + m_selectionSummary.setIOWritable(false); + m_selectionSummary.setIOReadable(false); + m_selectionSummary.setUiReadOnly(true); + m_selectionSummary.setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); + m_selectionSummary.setUiLabelPosition(caf::PdmUiItemInfo::TOP); + + CAF_PDM_InitFieldNoDefault(&m_resultType, "ResultType", "Result Type", "", "", ""); + m_resultType.setIOWritable(false); + CAF_PDM_InitFieldNoDefault(&m_porosityModel, "PorosityModel", "Porosity Model", "", "", ""); + m_porosityModel.setIOWritable(false); + + CAF_PDM_InitFieldNoDefault(&m_selectedDynamicProperties, "DynamicPropertiesToCalculate", "Dyn Prop", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_selectedStaticProperties, "StaticPropertiesToCalculate", "Stat Prop", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_selectedGeneratedProperties, "GeneratedPropertiesToCalculate", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_selectedInputProperties, "InputPropertiesToCalculate", "", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_selectedFractureDynamicProperties, "FractureDynamicPropertiesToCalculate", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_selectedFractureStaticProperties, "FractureStaticPropertiesToCalculate", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_selectedFractureGeneratedProperties, "FractureGeneratedPropertiesToCalculate", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_selectedFractureInputProperties, "FractureInputPropertiesToCalculate", "", "", "", ""); + + m_selectedDynamicProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedStaticProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedGeneratedProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedInputProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + + m_selectedFractureDynamicProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedFractureStaticProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedFractureGeneratedProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedFractureInputProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + + CAF_PDM_InitField(&m_calculatePercentiles, "CalculatePercentiles", true, "Calculate Percentiles", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_percentileCalculationType, "PercentileCalculationType", "Method", "", "", ""); + + CAF_PDM_InitField(&m_lowPercentile, "LowPercentile", 10.0, "Low", "", "", ""); + CAF_PDM_InitField(&m_midPercentile, "MidPercentile", 50.0, "Mid", "", "", ""); + CAF_PDM_InitField(&m_highPercentile, "HighPercentile", 90.0, "High", "", "", ""); + + CAF_PDM_InitField(&m_wellDataSourceCase, "WellDataSourceCase", RimDefines::undefinedResultName(), "Well Data Source Case", "", "", "" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCase::~RimStatisticsCase() +{ + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::setMainGrid(RigMainGrid* mainGrid) +{ + CVF_ASSERT(mainGrid); + CVF_ASSERT(this->reservoirData()); + + reservoirData()->setMainGrid(mainGrid); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimStatisticsCase::openEclipseGridFile() +{ + if (this->reservoirData()) return true; + + cvf::ref eclipseCase = new RigCaseData; + + CVF_ASSERT(parentStatisticsCaseCollection()); + + RimIdenticalGridCaseGroup* gridCaseGroup = parentStatisticsCaseCollection()->parentCaseGroup(); + CVF_ASSERT(gridCaseGroup); + + RigMainGrid* mainGrid = gridCaseGroup->mainGrid(); + + eclipseCase->setMainGrid(mainGrid); + + eclipseCase->setActiveCellInfo(RifReaderInterface::MATRIX_RESULTS, gridCaseGroup->unionOfActiveCells(RifReaderInterface::MATRIX_RESULTS)); + eclipseCase->setActiveCellInfo(RifReaderInterface::FRACTURE_RESULTS, gridCaseGroup->unionOfActiveCells(RifReaderInterface::FRACTURE_RESULTS)); + + this->setReservoirData( eclipseCase.p() ); + + this->populateWithDefaultsIfNeeded(); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCaseCollection* RimStatisticsCase::parentStatisticsCaseCollection() +{ + std::vector parentObjects; + this->parentObjectsOfType(parentObjects); + + if (parentObjects.size() > 0) + { + return parentObjects[0]; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::computeStatistics() +{ + if (this->reservoirData() == NULL) + { + openEclipseGridFile(); + } + + RimIdenticalGridCaseGroup* gridCaseGroup = caseGroup(); + CVF_ASSERT(gridCaseGroup); + gridCaseGroup->computeUnionOfActiveCells(); + + std::vector sourceCases; + + getSourceCases(sourceCases); + + if (sourceCases.size() == 0) + { + return; + } + + // The first source has been read completely from disk, and contains grid and meta data + // Use this information for all cases in the case group + size_t timeStepCount = sourceCases.at(0)->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->maxTimeStepCount(); + + RimStatisticsConfig statisticsConfig; + + statisticsConfig.m_calculatePercentiles = m_calculatePercentiles(); + statisticsConfig.m_pMaxPos = m_highPercentile(); + statisticsConfig.m_pMidPos = m_midPercentile(); + statisticsConfig.m_pMinPos = m_lowPercentile(); + statisticsConfig.m_pValMethod = m_percentileCalculationType(); + + std::vector timeStepIndices; + for (size_t i = 0; i < timeStepCount; i++) + { + timeStepIndices.push_back(i); + } + + RigCaseData* resultCase = reservoirData(); + + QList resultSpecification; + + for(size_t pIdx = 0; pIdx < m_selectedDynamicProperties().size(); ++pIdx) + { + resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::MATRIX_RESULTS, RimDefines::DYNAMIC_NATIVE, m_selectedDynamicProperties()[pIdx])); + } + + for(size_t pIdx = 0; pIdx < m_selectedStaticProperties().size(); ++pIdx) + { + resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::MATRIX_RESULTS, RimDefines::STATIC_NATIVE, m_selectedStaticProperties()[pIdx])); + } + + for(size_t pIdx = 0; pIdx < m_selectedGeneratedProperties().size(); ++pIdx) + { + resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::MATRIX_RESULTS, RimDefines::GENERATED, m_selectedGeneratedProperties()[pIdx])); + } + + for(size_t pIdx = 0; pIdx < m_selectedInputProperties().size(); ++pIdx) + { + resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::MATRIX_RESULTS, RimDefines::INPUT_PROPERTY, m_selectedInputProperties()[pIdx])); + } + + for(size_t pIdx = 0; pIdx < m_selectedFractureDynamicProperties().size(); ++pIdx) + { + resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::FRACTURE_RESULTS, RimDefines::DYNAMIC_NATIVE, m_selectedFractureDynamicProperties()[pIdx])); + } + + for(size_t pIdx = 0; pIdx < m_selectedFractureStaticProperties().size(); ++pIdx) + { + resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::FRACTURE_RESULTS, RimDefines::STATIC_NATIVE, m_selectedFractureStaticProperties()[pIdx])); + } + + for(size_t pIdx = 0; pIdx < m_selectedFractureGeneratedProperties().size(); ++pIdx) + { + resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::FRACTURE_RESULTS, RimDefines::GENERATED, m_selectedFractureGeneratedProperties()[pIdx])); + } + + for(size_t pIdx = 0; pIdx < m_selectedFractureInputProperties().size(); ++pIdx) + { + resultSpecification.append(RimStatisticsCaseEvaluator::ResSpec(RifReaderInterface::FRACTURE_RESULTS, RimDefines::INPUT_PROPERTY, m_selectedFractureInputProperties()[pIdx])); + } + + RimStatisticsCaseEvaluator stat(sourceCases, timeStepIndices, statisticsConfig, resultCase); + stat.evaluateForResults(resultSpecification); + + // Todo: Is this really the time and place to do the following ? JJS + + for (size_t i = 0; i < reservoirViews().size(); i++) + { + RimReservoirView* reservoirView = reservoirViews()[i]; + CVF_ASSERT(reservoirView); + + reservoirView->scheduleGeometryRegen(RivReservoirViewPartMgr::ACTIVE); + reservoirView->createDisplayModelAndRedraw(); + } + + + this->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::getSourceCases(std::vector& sourceCases) +{ + RimIdenticalGridCaseGroup* gridCaseGroup = caseGroup(); + if (gridCaseGroup) + { + size_t caseCount = gridCaseGroup->caseCollection->reservoirs.size(); + for (size_t i = 0; i < caseCount; i++) + { + CVF_ASSERT(gridCaseGroup->caseCollection); + CVF_ASSERT(gridCaseGroup->caseCollection->reservoirs[i]); + CVF_ASSERT(gridCaseGroup->caseCollection->reservoirs[i]->reservoirData()); + + RimCase* sourceCase = gridCaseGroup->caseCollection->reservoirs[i]; + sourceCases.push_back(sourceCase); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup* RimStatisticsCase::caseGroup() +{ + RimCaseCollection* parentCollection = parentStatisticsCaseCollection(); + if (parentCollection) + { + return parentCollection->parentCaseGroup(); + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + + updateSelectionSummaryLabel(); + updateSelectionListVisibilities(); + updatePercentileUiVisibility(); + + uiOrdering.add(&caseUserDescription); + uiOrdering.add(&m_calculateEditCommand); + uiOrdering.add(&m_selectionSummary); + + caf::PdmUiGroup * group = uiOrdering.addNewGroup("Properties to consider"); + group->setUiHidden(hasComputedStatistics()); + group->add(&m_resultType); + group->add(&m_porosityModel); + group->add(&m_selectedDynamicProperties); + group->add(&m_selectedStaticProperties); + group->add(&m_selectedGeneratedProperties); + group->add(&m_selectedInputProperties); + group->add(&m_selectedFractureDynamicProperties); + group->add(&m_selectedFractureStaticProperties); + group->add(&m_selectedFractureGeneratedProperties); + group->add(&m_selectedFractureInputProperties); + + group = uiOrdering.addNewGroup("Percentile setup"); + group->setUiHidden(hasComputedStatistics()); + group->add(&m_calculatePercentiles); + group->add(&m_percentileCalculationType); + group->add(&m_lowPercentile); + group->add(&m_midPercentile); + group->add(&m_highPercentile); +} + +QList toOptionList(const QStringList& varList) +{ + QList optionList; + int i; + for (i = 0; i < varList.size(); ++i) + { + optionList.push_back(caf::PdmOptionItemInfo( varList[i], varList[i])); + } + return optionList; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimStatisticsCase::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +{ + QList options; + if (useOptionsOnly) *useOptionsOnly = true; + + RimIdenticalGridCaseGroup* idgcg = caseGroup(); + if (!(caseGroup() && caseGroup()->mainCase() && caseGroup()->mainCase()->reservoirData())) + { + return options; + } + + RigCaseData* caseData = idgcg->mainCase()->reservoirData(); + + if (&m_selectedDynamicProperties == fieldNeedingOptions) + { + QStringList varList = caseData->results(RifReaderInterface::MATRIX_RESULTS)->resultNames(RimDefines::DYNAMIC_NATIVE); + return toOptionList(varList); + } + else if (&m_selectedStaticProperties == fieldNeedingOptions) + { + QStringList varList = caseData->results(RifReaderInterface::MATRIX_RESULTS)->resultNames(RimDefines::STATIC_NATIVE); + return toOptionList(varList); + } + else if (&m_selectedGeneratedProperties == fieldNeedingOptions) + { + QStringList varList = caseData->results(RifReaderInterface::MATRIX_RESULTS)->resultNames(RimDefines::GENERATED); + return toOptionList(varList); + } + else if (&m_selectedInputProperties == fieldNeedingOptions) + { + QStringList varList = caseData->results(RifReaderInterface::MATRIX_RESULTS)->resultNames(RimDefines::INPUT_PROPERTY); + return toOptionList(varList); + } + else if (&m_selectedFractureDynamicProperties == fieldNeedingOptions) + { + QStringList varList = caseData->results(RifReaderInterface::FRACTURE_RESULTS)->resultNames(RimDefines::DYNAMIC_NATIVE); + return toOptionList(varList); + } + else if (&m_selectedFractureStaticProperties == fieldNeedingOptions) + { + QStringList varList = caseData->results(RifReaderInterface::FRACTURE_RESULTS)->resultNames(RimDefines::STATIC_NATIVE); + return toOptionList(varList); + } + else if (&m_selectedFractureGeneratedProperties == fieldNeedingOptions) + { + QStringList varList = caseData->results(RifReaderInterface::FRACTURE_RESULTS)->resultNames(RimDefines::GENERATED); + return toOptionList(varList); + } + else if (&m_selectedFractureInputProperties == fieldNeedingOptions) + { + QStringList varList = caseData->results(RifReaderInterface::FRACTURE_RESULTS)->resultNames(RimDefines::INPUT_PROPERTY); + return toOptionList(varList); + } + + else if (&m_wellDataSourceCase == fieldNeedingOptions) + { + QStringList sourceCaseNames; + sourceCaseNames += RimDefines::undefinedResultName(); + + for (size_t i = 0; i < caseGroup()->caseCollection()->reservoirs().size(); i++) + { + sourceCaseNames += caseGroup()->caseCollection()->reservoirs()[i]->caseUserDescription(); + } + + return toOptionList(sourceCaseNames); + } + + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (&m_resultType == changedField || &m_porosityModel == changedField) + { + } + + if (&m_calculateEditCommand == changedField) + { + if (hasComputedStatistics()) + { + clearComputedStatistics(); + } + else + { + computeStatistics(); + } + m_calculateEditCommand = false; + } + + if (&m_wellDataSourceCase == changedField) + { + RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); + + // Find or load well data for given case + RimCase* sourceResultCase = caseGroup()->caseCollection()->findByDescription(m_wellDataSourceCase); + if (sourceResultCase) + { + sourceResultCase->openEclipseGridFile(); + + // Propagate well info to statistics case + if (sourceResultCase->reservoirData()) + { + const cvf::Collection& sourceCaseWellResults = sourceResultCase->reservoirData()->wellResults(); + setWellResultsAndUpdateViews(sourceCaseWellResults); + } + } + else + { + cvf::Collection sourceCaseWellResults; + setWellResultsAndUpdateViews(sourceCaseWellResults); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::setWellResultsAndUpdateViews(const cvf::Collection& sourceCaseWellResults) +{ + RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); + + this->reservoirData()->setWellResults(sourceCaseWellResults); + + caf::ProgressInfo progInfo(reservoirViews().size() + 1, "Updating Well Data for Views"); + + // Update views + for (size_t i = 0; i < reservoirViews().size(); i++) + { + RimReservoirView* reservoirView = reservoirViews()[i]; + CVF_ASSERT(reservoirView); + + reservoirView->wellCollection()->wells.deleteAllChildObjects(); + reservoirView->updateDisplayModelForWellResults(); + + treeModel->rebuildUiSubTree(reservoirView->wellCollection()); + + progInfo.incrementProgress(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void addPropertySetToHtmlText(QString& html, const QString& heading, const std::vector& varNames) +{ + if (varNames.size()) + { + html += "

" + heading + "

"; + html += "

"; + for (size_t pIdx = 0; pIdx < varNames.size(); ++pIdx) + { + html += varNames[pIdx]; + if ( (pIdx+1)%6 == 0 ) html += "
"; + else if (pIdx != varNames.size() -1) html += ", "; + } + html += "

"; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::updateSelectionSummaryLabel() +{ + QString html; + + html += ""; + + html += "

Statistical variables to compute:

"; + html += "

"; + html += "Min, Max, Range, Mean, Std.dev"; ; + if (m_calculatePercentiles()) + { + html += "
"; + html += "Percentiles for : " + + QString::number(m_lowPercentile()) + ", " + + QString::number(m_midPercentile()) + ", " + + QString::number(m_highPercentile()); + } + html += "

"; + + addPropertySetToHtmlText(html, "Dynamic properties", m_selectedDynamicProperties()); + addPropertySetToHtmlText(html, "Static properties", m_selectedStaticProperties()); + addPropertySetToHtmlText(html, "Generated properties", m_selectedGeneratedProperties()); + addPropertySetToHtmlText(html, "Input properties", m_selectedInputProperties()); + + addPropertySetToHtmlText(html, "Dynamic properties, fracture model" , m_selectedFractureDynamicProperties()); + addPropertySetToHtmlText(html, "Static properties, fracture model" , m_selectedFractureStaticProperties()); + addPropertySetToHtmlText(html, "Generated properties, fracture model", m_selectedFractureGeneratedProperties()); + addPropertySetToHtmlText(html, "Input properties, fracture model" , m_selectedFractureInputProperties()); + + m_selectionSummary = html; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) +{ + if (&m_selectionSummary == field) + { + caf::PdmUiTextEditorAttribute* textEditAttrib = dynamic_cast (attribute); + textEditAttrib->textMode = caf::PdmUiTextEditorAttribute::HTML; + } + + if (&m_calculateEditCommand == field) + { + caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast (attribute); + attrib->m_buttonText = hasComputedStatistics() ? "Edit (Will DELETE current results)": "Compute"; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::updateSelectionListVisibilities() +{ + bool isLocked = hasComputedStatistics(); + m_resultType.setUiHidden(isLocked); + m_porosityModel.setUiHidden(isLocked ); // || !caseGroup()->mainCase()->reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS)->resultCount() + + m_selectedDynamicProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::DYNAMIC_NATIVE)); + m_selectedStaticProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::STATIC_NATIVE)); + m_selectedGeneratedProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::GENERATED)); + m_selectedInputProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::INPUT_PROPERTY)); + + m_selectedFractureDynamicProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::DYNAMIC_NATIVE)); + m_selectedFractureStaticProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::STATIC_NATIVE)); + m_selectedFractureGeneratedProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::GENERATED)); + m_selectedFractureInputProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::INPUT_PROPERTY)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::updatePercentileUiVisibility() +{ + bool isLocked = hasComputedStatistics(); + m_calculatePercentiles.setUiHidden(isLocked); + m_percentileCalculationType.setUiHidden( isLocked || !m_calculatePercentiles()); + m_lowPercentile .setUiHidden(isLocked || !m_calculatePercentiles()); + m_midPercentile .setUiHidden(isLocked || !m_calculatePercentiles()); + m_highPercentile.setUiHidden(isLocked || !m_calculatePercentiles()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimStatisticsCase::hasComputedStatistics() const +{ + if ( reservoirData() + && ( reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)->resultCount() + || reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS)->resultCount())) + { + return true; + } + else + { + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::clearComputedStatistics() +{ + reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)->clearAllResults(); + reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS)->clearAllResults(); + + this->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::populateWithDefaultsIfNeeded() +{ + RimIdenticalGridCaseGroup* idgcg = caseGroup(); + if (!(caseGroup() && caseGroup()->mainCase() && caseGroup()->mainCase()->reservoirData())) + { + return ; + } + + RigCaseData* caseData = idgcg->mainCase()->reservoirData(); + + if (m_selectedDynamicProperties().size() == 0) + { + QStringList varList = caseData->results(RifReaderInterface::MATRIX_RESULTS)->resultNames(RimDefines::DYNAMIC_NATIVE); + if (varList.contains("SOIL")) m_selectedDynamicProperties.v().push_back("SOIL"); + if (varList.contains("PRESSURE")) m_selectedDynamicProperties.v().push_back("PRESSURE"); + } + + if (m_selectedStaticProperties().size() == 0) + { + QStringList varList = caseData->results(RifReaderInterface::MATRIX_RESULTS)->resultNames(RimDefines::STATIC_NATIVE); + if (varList.contains("PERMX")) m_selectedStaticProperties.v().push_back("PERMX"); + if (varList.contains("PORO")) m_selectedStaticProperties.v().push_back("PORO"); + } + + if (m_selectedFractureDynamicProperties().size() == 0) + { + QStringList varList = caseData->results(RifReaderInterface::FRACTURE_RESULTS)->resultNames(RimDefines::DYNAMIC_NATIVE); + if (varList.contains("SOIL")) m_selectedFractureDynamicProperties.v().push_back("SOIL"); + if (varList.contains("PRESSURE")) m_selectedFractureDynamicProperties.v().push_back("PRESSURE"); + } + + if (m_selectedFractureStaticProperties().size() == 0) + { + QStringList varList = caseData->results(RifReaderInterface::FRACTURE_RESULTS)->resultNames(RimDefines::STATIC_NATIVE); + if (varList.contains("PERMX")) m_selectedFractureStaticProperties.v().push_back("PERMX"); + if (varList.contains("PORO")) m_selectedFractureStaticProperties.v().push_back("PORO"); + } +} + diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCase.h b/ApplicationCode/ProjectDataModel/RimStatisticsCase.h new file mode 100644 index 0000000000..e56235e24e --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCase.h @@ -0,0 +1,111 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +#include "RimCase.h" + +class RimIdenticalGridCaseGroup; +class RimResultDefinition; +class RimStatisticsCaseCollection; +class RigMainGrid; +class RigSingleWellResultsData; + + +//================================================================================================== +// +// +// +//================================================================================================== +class RimStatisticsCase : public RimCase +{ + CAF_PDM_HEADER_INIT; + +public: + RimStatisticsCase(); + virtual ~RimStatisticsCase(); + + void setMainGrid(RigMainGrid* mainGrid); + + void computeStatistics(); + bool hasComputedStatistics() const; + void clearComputedStatistics(); + + virtual bool openEclipseGridFile(); + + RimCaseCollection* parentStatisticsCaseCollection(); + + enum PercentileCalcType + { + NEAREST_OBSERVATION, + HISTOGRAM_ESTIMATED + }; + + +private: + RimIdenticalGridCaseGroup* caseGroup(); + + void getSourceCases(std::vector& sourceCases); + + void populateWithDefaultsIfNeeded(); + + void updateSelectionListVisibilities(); + void updateSelectionSummaryLabel(); + void updatePercentileUiVisibility(); + + void setWellResultsAndUpdateViews(const cvf::Collection& sourceCaseWellResults); + + // Pdm system overrides + virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) ; + virtual QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ); + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + + virtual void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute ); + + // Fields + caf::PdmField< bool > m_calculateEditCommand; + + caf::PdmField< caf::AppEnum< RimDefines::ResultCatType > > m_resultType; + caf::PdmField< caf::AppEnum< RimDefines::PorosityModelType > > m_porosityModel; + + caf::PdmField m_selectionSummary; + + caf::PdmField > m_selectedDynamicProperties; + caf::PdmField > m_selectedStaticProperties; + caf::PdmField > m_selectedGeneratedProperties; + caf::PdmField > m_selectedInputProperties; + + caf::PdmField > m_selectedFractureDynamicProperties; + caf::PdmField > m_selectedFractureStaticProperties; + caf::PdmField > m_selectedFractureGeneratedProperties; + caf::PdmField > m_selectedFractureInputProperties; + + + caf::PdmField< bool > m_calculatePercentiles; + caf::PdmField< caf::AppEnum< PercentileCalcType > > m_percentileCalculationType; + caf::PdmField m_lowPercentile; + caf::PdmField m_midPercentile; + caf::PdmField m_highPercentile; + + caf::PdmField m_wellDataSourceCase; +}; diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.cpp b/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.cpp new file mode 100644 index 0000000000..0d68ebdf07 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.cpp @@ -0,0 +1,63 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RimReservoirView.h" + +#include "RimStatisticsCaseCollection.h" +#include "RimIdenticalGridCaseGroup.h" + + +CAF_PDM_SOURCE_INIT(RimStatisticsCaseCollection, "RimStatisticalCollection"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCaseCollection::RimStatisticsCaseCollection() + : PdmObject() +{ + CAF_PDM_InitObject("Derived Statistics", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&cases, "Reservoirs", "", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCaseCollection::~RimStatisticsCaseCollection() +{ + cases.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup* RimStatisticsCaseCollection::parentCaseGroup() +{ + std::vector parentObjects; + this->parentObjectsOfType(parentObjects); + + if (parentObjects.size() > 0) + { + return parentObjects[0]; + } + + return NULL; +} + diff --git a/ApplicationCode/ProjectDataModel/RimResultReservoir.h b/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.h similarity index 65% rename from ApplicationCode/ProjectDataModel/RimResultReservoir.h rename to ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.h index cfbffd5abc..e7c0059363 100644 --- a/ApplicationCode/ProjectDataModel/RimResultReservoir.h +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.h @@ -22,37 +22,28 @@ #include "cvfObject.h" #include "cafPdmField.h" #include "cafPdmObject.h" -#include "RimReservoir.h" - class RifReaderInterface; +#include "RimStatisticsCase.h" + + //================================================================================================== // // // //================================================================================================== -class RimResultReservoir : public RimReservoir +class RimStatisticsCaseCollection : public caf::PdmObject { CAF_PDM_HEADER_INIT; public: - RimResultReservoir(); - virtual ~RimResultReservoir(); + RimStatisticsCaseCollection(); + virtual ~RimStatisticsCaseCollection(); + caf::PdmPointersField cases; - // Fields: - caf::PdmField caseFileName; - caf::PdmField caseDirectory; - - virtual bool openEclipseGridFile(); - - //virtual caf::PdmFieldHandle* userDescriptionField() { return &caseName;} - - virtual QString locationOnDisc() const; + RimIdenticalGridCaseGroup* parentCaseGroup(); private: - cvf::ref createMockModel(QString modelName); - - QString createAbsoluteFilenameFromCase(const QString& caseName); }; diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.cpp b/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.cpp new file mode 100644 index 0000000000..05f90e9fd4 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.cpp @@ -0,0 +1,360 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RimStatisticsCaseEvaluator.h" +#include "RigCaseCellResultsData.h" +#include "RimReservoirView.h" +#include "RimCase.h" +#include "RigCaseData.h" +#include "RigStatisticsMath.h" + +//#include "RigCaseData.h" +#include +#include "cafProgressInfo.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCaseEvaluator::addNamedResult(RigCaseCellResultsData* destinationCellResults, RimDefines::ResultCatType resultType, const QString& resultName, size_t activeUnionCellCount) +{ + // Use time step dates from first result in first source case + CVF_ASSERT(m_sourceCases.size() > 0); + + std::vector sourceTimeStepDates = m_sourceCases[0]->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->timeStepDates(0); + + size_t destinationScalarResultIndex = destinationCellResults->addEmptyScalarResult(resultType, resultName, true); + CVF_ASSERT(destinationScalarResultIndex != cvf::UNDEFINED_SIZE_T); + + destinationCellResults->setTimeStepDates(destinationScalarResultIndex, sourceTimeStepDates); + std::vector< std::vector >& dataValues = destinationCellResults->cellScalarResults(destinationScalarResultIndex); + dataValues.resize(sourceTimeStepDates.size()); + + + // Initializes the size of the destination dataset to active union cell count + for (size_t i = 0; i < sourceTimeStepDates.size(); i++) + { + dataValues[i].resize(activeUnionCellCount, HUGE_VAL); + } +} + + +QString createResultNameMin(const QString& resultName) { return resultName + "_MIN"; } +QString createResultNameMax(const QString& resultName) { return resultName + "_MAX"; } +QString createResultNameMean(const QString& resultName) { return resultName + "_MEAN"; } +QString createResultNameDev(const QString& resultName) { return resultName + "_DEV"; } +QString createResultNameRange(const QString& resultName) { return resultName + "_RANGE"; } +QString createResultNamePVal(const QString& resultName, double pValPos) { return resultName + "_P_" + QString::number(pValPos); } + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCaseEvaluator::buildSourceMetaData(RifReaderInterface::PorosityModelResultType poroModel, RimDefines::ResultCatType resultType, const QString& resultName) +{ + if (m_sourceCases.size() == 0) return; + + std::vector timeStepDates = m_sourceCases[0]->results(poroModel)->cellResults()->timeStepDates(0); + + for (size_t caseIdx = 1; caseIdx < m_sourceCases.size(); caseIdx++) + { + RimReservoirCellResultsStorage* cellResultsStorage = m_sourceCases[caseIdx]->results(poroModel); + size_t scalarResultIndex = cellResultsStorage->findOrLoadScalarResult(resultType, resultName); + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) + { + size_t scalarResultIndex = cellResultsStorage->cellResults()->addEmptyScalarResult(resultType, resultName, false); + cellResultsStorage->cellResults()->setTimeStepDates(scalarResultIndex, timeStepDates); + + std::vector< std::vector >& dataValues = cellResultsStorage->cellResults()->cellScalarResults(scalarResultIndex); + dataValues.resize(timeStepDates.size()); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCaseEvaluator::evaluateForResults(const QList& resultSpecification) +{ + CVF_ASSERT(m_destinationCase); + + // First build the destination result data structures to receive the statistics + + for (int i = 0; i < resultSpecification.size(); i++) + { + RifReaderInterface::PorosityModelResultType poroModel = resultSpecification[i].m_poroModel; + RimDefines::ResultCatType resultType = resultSpecification[i].m_resType; + QString resultName = resultSpecification[i].m_resVarName; + + size_t activeCellCount = m_destinationCase->activeCellInfo(poroModel)->globalActiveCellCount(); + RigCaseCellResultsData* destCellResultsData = m_destinationCase->results(poroModel); + + // Special handling if SOIL is asked for + // Build SGAS/SWAT meta data, SOIL is automatically generated as part of RigCaseCellResultsData::findOrLoadScalarResultForTimeStep + if (resultName.toUpper() == "SOIL") + { + size_t swatIndex = m_sourceCases.at(0)->results(poroModel)->cellResults()->findScalarResultIndex(resultType, "SWAT"); + if (swatIndex != cvf::UNDEFINED_SIZE_T) + { + buildSourceMetaData(poroModel, resultType, "SWAT"); + } + + size_t sgasIndex = m_sourceCases.at(0)->results(poroModel)->cellResults()->findScalarResultIndex(resultType, "SGAS"); + if (sgasIndex != cvf::UNDEFINED_SIZE_T) + { + buildSourceMetaData(poroModel, resultType, "SGAS"); + } + } + else + { + // Meta info is loaded from disk for first case only + // Build metadata for all other source cases + buildSourceMetaData(poroModel, resultType, resultName); + } + + // Create new result data structures to contain the statistical values + std::vector statisticalResultNames; + + statisticalResultNames.push_back(createResultNameMin(resultName)); + statisticalResultNames.push_back(createResultNameMax(resultName)); + statisticalResultNames.push_back(createResultNameMean(resultName)); + statisticalResultNames.push_back(createResultNameDev(resultName)); + statisticalResultNames.push_back(createResultNameRange(resultName)); + + if (m_statisticsConfig.m_calculatePercentiles) + { + statisticalResultNames.push_back(createResultNamePVal(resultName, m_statisticsConfig.m_pMinPos)); + statisticalResultNames.push_back(createResultNamePVal(resultName, m_statisticsConfig.m_pMidPos)); + statisticalResultNames.push_back(createResultNamePVal(resultName, m_statisticsConfig.m_pMaxPos)); + } + + if (activeCellCount > 0) + { + for (size_t i = 0; i < statisticalResultNames.size(); ++i) + { + addNamedResult(destCellResultsData, resultType, statisticalResultNames[i], activeCellCount); + } + } + } + + // Start the loop that calculates the statistics + + caf::ProgressInfo progressInfo(m_timeStepIndices.size(), "Computing Statistics"); + + for (size_t timeIndicesIdx = 0; timeIndicesIdx < m_timeStepIndices.size(); timeIndicesIdx++) + { + size_t timeStepIdx = m_timeStepIndices[timeIndicesIdx]; + + for (size_t gridIdx = 0; gridIdx < m_destinationCase->gridCount(); gridIdx++) + { + RigGridBase* grid = m_destinationCase->grid(gridIdx); + + for (int i = 0; i < resultSpecification.size(); i++) + { + RifReaderInterface::PorosityModelResultType poroModel = resultSpecification[i].m_poroModel; + RimDefines::ResultCatType resultType = resultSpecification[i].m_resType; + QString resultName = resultSpecification[i].m_resVarName; + + size_t activeCellCount = m_destinationCase->activeCellInfo(poroModel)->globalActiveCellCount(); + + if (activeCellCount == 0) continue; + + RigCaseCellResultsData* destCellResultsData = m_destinationCase->results(poroModel); + + size_t dataAccessTimeStepIndex = timeStepIdx; + + // Always evaluate statistics once, and always use time step index zero + if (resultType == RimDefines::STATIC_NATIVE) + { + if (timeIndicesIdx > 0) continue; + + dataAccessTimeStepIndex = 0; + } + + // Build data access objects for source scalar results + + cvf::Collection sourceDataAccessList; + for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++) + { + RimCase* eclipseCase = m_sourceCases.at(caseIdx); + + size_t scalarResultIndex = eclipseCase->results(poroModel)->findOrLoadScalarResultForTimeStep(resultType, resultName, dataAccessTimeStepIndex); + + cvf::ref dataAccessObject = eclipseCase->reservoirData()->dataAccessObject(grid, poroModel, dataAccessTimeStepIndex, scalarResultIndex); + if (dataAccessObject.notNull()) + { + sourceDataAccessList.push_back(dataAccessObject.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 + + cvf::Collection destinationDataAccessList; + std::vector statisticalResultNames(STAT_PARAM_COUNT); + + statisticalResultNames[MIN] = createResultNameMin(resultName); + statisticalResultNames[MAX] = createResultNameMax(resultName); + statisticalResultNames[RANGE] = createResultNameRange(resultName); + statisticalResultNames[MEAN] = createResultNameMean(resultName); + statisticalResultNames[STDEV] = createResultNameDev(resultName); + statisticalResultNames[PMIN] = createResultNamePVal(resultName, m_statisticsConfig.m_pMinPos); + statisticalResultNames[PMID] = createResultNamePVal(resultName, m_statisticsConfig.m_pMidPos); + statisticalResultNames[PMAX] = createResultNamePVal(resultName, m_statisticsConfig.m_pMaxPos); + + 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); + } + } + + // Loop over the cells in the grid, get the case values, and calculate the cell statistics + + for (size_t cellIdx = 0; cellIdx < grid->cellCount(); cellIdx++) + { + + size_t globalGridCellIdx = grid->globalGridCellIndex(cellIdx); + if (m_destinationCase->activeCellInfo(poroModel)->isActive(globalGridCellIdx)) + { + // Extract the cell values from each of the cases and assemble them into one vector + + std::vector values(sourceDataAccessList.size(), HUGE_VAL); + + bool foundAnyValidValues = false; + for (size_t caseIdx = 0; caseIdx < sourceDataAccessList.size(); caseIdx++) + { + double val = sourceDataAccessList.at(caseIdx)->cellScalar(cellIdx); + values[caseIdx] = val; + + if (val != HUGE_VAL) + { + foundAnyValidValues = true; + } + } + + // Do the real statistics calculations + std::vector statParams(STAT_PARAM_COUNT, HUGE_VAL); + + if (foundAnyValidValues) + { + RigStatisticsMath::calculateBasicStatistics(values, &statParams[MIN], &statParams[MAX], &statParams[RANGE], &statParams[MEAN], &statParams[STDEV]); + + // Calculate percentiles + if (m_statisticsConfig.m_calculatePercentiles ) + { + if (m_statisticsConfig.m_pValMethod == RimStatisticsCase::NEAREST_OBSERVATION) + { + std::vector pValPoss; + pValPoss.push_back(m_statisticsConfig.m_pMinPos); + pValPoss.push_back(m_statisticsConfig.m_pMidPos); + pValPoss.push_back(m_statisticsConfig.m_pMaxPos); + std::vector pVals = RigStatisticsMath::calculateNearestRankPercentiles(values, pValPoss); + statParams[PMIN] = pVals[0]; + statParams[PMID] = pVals[1]; + statParams[PMAX] = pVals[2]; + } + else if (m_statisticsConfig.m_pValMethod == RimStatisticsCase::HISTOGRAM_ESTIMATED) + { + std::vector histogram; + RigHistogramCalculator histCalc(statParams[MIN], statParams[MAX], 100, &histogram); + histCalc.addData(values); + statParams[PMIN] = histCalc.calculatePercentil(m_statisticsConfig.m_pMinPos); + statParams[PMID] = histCalc.calculatePercentil(m_statisticsConfig.m_pMidPos); + statParams[PMAX] = histCalc.calculatePercentil(m_statisticsConfig.m_pMaxPos); + } + else + { + CVF_ASSERT(false); + } + } + } + + // Set the results into the results data structures + + for (size_t stIdx = 0; stIdx < statParams.size(); ++stIdx) + { + if (destinationDataAccessList[stIdx].notNull()) + { + destinationDataAccessList[stIdx]->setCellScalar(cellIdx, statParams[stIdx]); + } + } + } + } + } + } + + // When one time step is completed, close all result files. + // Microsoft note: On Windows, the maximum number of files open at the same time is 512 + // http://msdn.microsoft.com/en-us/library/kdfaxaay%28vs.71%29.aspx + + for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++) + { + RimCase* eclipseCase = m_sourceCases.at(caseIdx); + eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->readerInterface()->close(); + eclipseCase->results(RifReaderInterface::FRACTURE_RESULTS)->readerInterface()->close(); + } + + progressInfo.setProgress(timeIndicesIdx); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +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); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCaseEvaluator::RimStatisticsCaseEvaluator(const std::vector& sourceCases, const std::vector& timeStepIndices, const RimStatisticsConfig& statisticsConfig, RigCaseData* destinationCase) + : m_sourceCases(sourceCases), + m_statisticsConfig(statisticsConfig), + m_destinationCase(destinationCase), + m_globalCellCount(0), + m_timeStepIndices(timeStepIndices) +{ + if (sourceCases.size() > 0) + { + m_globalCellCount = sourceCases[0]->reservoirData()->mainGrid()->cells().size(); + } + + CVF_ASSERT(m_destinationCase); +} + diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.h b/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.h new file mode 100644 index 0000000000..1c4cb49962 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.h @@ -0,0 +1,95 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfCollection.h" +#include +#include + +#include +#include "RimDefines.h" +#include "RimStatisticsCase.h" + +class RimCase; +class RigCaseData; +class RigCaseCellResultsData; + + +class RimStatisticsConfig +{ +public: + RimStatisticsConfig() + : m_calculatePercentiles(true), + m_pMinPos(10.0), + m_pMidPos(50.0), + m_pMaxPos(90.0), + m_pValMethod(RimStatisticsCase::NEAREST_OBSERVATION) + { + } + +public: + bool m_calculatePercentiles; + double m_pMinPos; + double m_pMidPos; + double m_pMaxPos; + RimStatisticsCase::PercentileCalcType m_pValMethod; +}; + + +class RimStatisticsCaseEvaluator +{ +public: + RimStatisticsCaseEvaluator(const std::vector& sourceCases, + const std::vector& timeStepIndices, + const RimStatisticsConfig& statisticsConfig, + RigCaseData* destinationCase); + + struct ResSpec + { + ResSpec() : m_resType(RimDefines::DYNAMIC_NATIVE), m_poroModel(RifReaderInterface::MATRIX_RESULTS) {} + ResSpec( RifReaderInterface::PorosityModelResultType poroModel, + RimDefines::ResultCatType resType, + QString resVarName) : m_poroModel(poroModel), m_resType(resType), m_resVarName(resVarName) {} + + RifReaderInterface::PorosityModelResultType m_poroModel; + RimDefines::ResultCatType m_resType; + QString m_resVarName; + }; + + 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); + + enum StatisticsParamType { MIN, MAX, RANGE, MEAN, STDEV, PMIN, PMID, PMAX, STAT_PARAM_COUNT }; + +private: + std::vector m_sourceCases; + std::vector m_timeStepIndices; + + size_t m_globalCellCount; + RimStatisticsConfig m_statisticsConfig; + RigCaseData* m_destinationCase; +}; + diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp index 34713d1ba4..076ef7df8d 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp +++ b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimUiTreeModelPdm.h" #include "RimCellRangeFilter.h" @@ -27,14 +27,19 @@ #include "RimCellPropertyFilterCollection.h" #include "RimReservoirView.h" -#include "RIViewer.h" +#include "RiuViewer.h" #include "RimCalcScript.h" -#include "RIApplication.h" -#include "RIMainWindow.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" #include "RimInputProperty.h" #include "RimInputPropertyCollection.h" #include "cafPdmField.h" -#include "RimInputReservoir.h" +#include "RimInputCase.h" +#include "RimStatisticsCase.h" +#include "RimResultCase.h" +#include "RigGridManager.h" +#include "RimCase.h" +#include "RigCaseData.h" //-------------------------------------------------------------------------------------------------- /// @@ -49,9 +54,9 @@ RimUiTreeModelPdm::RimUiTreeModelPdm(QObject* parent) } //-------------------------------------------------------------------------------------------------- -/// +/// TO BE DELETED //-------------------------------------------------------------------------------------------------- -bool RimUiTreeModelPdm::insertRows(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) +bool RimUiTreeModelPdm::insertRows_special(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) { caf::PdmUiTreeItem* parentItem = getTreeItemFromIndex(parent); @@ -124,7 +129,7 @@ bool RimUiTreeModelPdm::deletePropertyFilter(const QModelIndex& itemIndex) bool wasSomeFilterActive = propertyFilterCollection->hasActiveFilters(); // Remove Ui items pointing at the pdm object to delete - removeRow(itemIndex.row(), itemIndex.parent()); + removeRows_special(itemIndex.row(), 1, itemIndex.parent()); propertyFilterCollection->remove(propertyFilter); delete propertyFilter; @@ -138,6 +143,9 @@ bool RimUiTreeModelPdm::deletePropertyFilter(const QModelIndex& itemIndex) { propertyFilterCollection->reservoirView()->createDisplayModelAndRedraw(); } + + clearClipboard(); + return true; } @@ -161,7 +169,7 @@ bool RimUiTreeModelPdm::deleteRangeFilter(const QModelIndex& itemIndex) bool wasSomeFilterActive = rangeFilterCollection->hasActiveFilters(); // Remove Ui items pointing at the pdm object to delete - removeRow(itemIndex.row(), itemIndex.parent()); + removeRows_special(itemIndex.row(), 1, itemIndex.parent()); rangeFilterCollection->remove(rangeFilter); delete rangeFilter; @@ -176,6 +184,8 @@ bool RimUiTreeModelPdm::deleteRangeFilter(const QModelIndex& itemIndex) rangeFilterCollection->reservoirView()->createDisplayModelAndRedraw(); } + clearClipboard(); + return true; } @@ -193,34 +203,69 @@ bool RimUiTreeModelPdm::deleteReservoirView(const QModelIndex& itemIndex) CVF_ASSERT(reservoirView); // Remove Ui items pointing at the pdm object to delete - removeRow(itemIndex.row(), itemIndex.parent()); + removeRows_special(itemIndex.row(), 1, itemIndex.parent()); reservoirView->eclipseCase()->removeReservoirView(reservoirView); delete reservoirView; + clearClipboard(); + return true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::deleteReservoir(const QModelIndex& itemIndex) +void RimUiTreeModelPdm::deleteReservoir(RimCase* reservoir) { - CVF_ASSERT(itemIndex.isValid()); + if (reservoir->parentCaseCollection()) + { + RimCaseCollection* caseCollection = reservoir->parentCaseCollection(); + QModelIndex caseCollectionModelIndex = getModelIndexFromPdmObject(caseCollection); + if (!caseCollectionModelIndex.isValid()) return; - caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(itemIndex); - CVF_ASSERT(uiItem); + QModelIndex mi = getModelIndexFromPdmObjectRecursive(caseCollectionModelIndex, reservoir); + if (mi.isValid()) + { + caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(mi); + CVF_ASSERT(uiItem); - RimReservoir* reservoir = dynamic_cast(uiItem->dataObject().p()); - CVF_ASSERT(reservoir); + // Remove Ui items pointing at the pdm object to delete + removeRows_special(mi.row(), 1, mi.parent()); + } - // Remove Ui items pointing at the pdm object to delete - removeRow(itemIndex.row(), itemIndex.parent()); + if (RimIdenticalGridCaseGroup::isStatisticsCaseCollection(caseCollection)) + { + RimIdenticalGridCaseGroup* caseGroup = caseCollection->parentCaseGroup(); + CVF_ASSERT(caseGroup); - RimProject* proj = RIApplication::instance()->project(); - proj->reservoirs().removeChildObject(reservoir); + caseGroup->statisticsCaseCollection()->reservoirs.removeChildObject(reservoir); + } + else + { + RimProject* proj = RiaApplication::instance()->project(); + proj->removeCaseFromAllGroups(reservoir); + } + } + else + { + RimProject* proj = RiaApplication::instance()->project(); + QModelIndex mi = getModelIndexFromPdmObject(reservoir); + if (mi.isValid()) + { + caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(mi); + CVF_ASSERT(uiItem); + + // Remove Ui items pointing at the pdm object to delete + removeRows_special(mi.row(), 1, mi.parent()); + } + + proj->removeCaseFromAllGroups(reservoir); + } delete reservoir; + + clearClipboard(); } //-------------------------------------------------------------------------------------------------- @@ -322,24 +367,43 @@ RimReservoirView* RimUiTreeModelPdm::addReservoirView(const QModelIndex& itemInd caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); if (!currentItem) return NULL; - RimReservoirView* reservoirView = dynamic_cast(currentItem->dataObject().p()); - if (!reservoirView) return NULL; + caf::PdmUiTreeItem* collectionItem = NULL; - RimReservoirView* insertedView = reservoirView->eclipseCase()->createAndAddReservoirView(); - caf::PdmUiTreeItem* collectionItem = currentItem->parent(); + bool itemIndexIsCollection = false; + QModelIndex collectionIndex; + if (dynamic_cast(currentItem->dataObject().p())) + { + collectionItem = currentItem->parent(); + collectionIndex = itemIndex.parent(); + } + else if (dynamic_cast(currentItem->dataObject().p())) + { + collectionItem = currentItem; + collectionIndex = itemIndex; + } - int viewCount = rowCount(itemIndex.parent()); - beginInsertRows(itemIndex.parent(), viewCount, viewCount); + if (collectionItem) + { + RimCase* rimReservoir = dynamic_cast(collectionItem->dataObject().p()); + rimReservoir->openEclipseGridFile(); - caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(collectionItem, viewCount, insertedView); + RimReservoirView* insertedView = rimReservoir->createAndAddReservoirView(); - endInsertRows(); + // Must be run before buildViewItems, as wells are created in this function + insertedView->loadDataAndUpdate(); - insertedView->loadDataAndUpdate(); + int viewCount = rowCount(collectionIndex); + beginInsertRows(collectionIndex, viewCount, viewCount); - rebuildUiSubTree(insertedView); - - return insertedView; + // NOTE: -1 as second argument indicates append + caf::PdmUiTreeItem* childItem = caf::UiTreeItemBuilderPdm::buildViewItems(collectionItem, -1, insertedView); + + endInsertRows(); + + return insertedView; + } + + return NULL; } @@ -348,7 +412,7 @@ RimReservoirView* RimUiTreeModelPdm::addReservoirView(const QModelIndex& itemInd //-------------------------------------------------------------------------------------------------- void RimUiTreeModelPdm::updateScriptPaths() { - RimProject* proj = RIApplication::instance()->project(); + RimProject* proj = RiaApplication::instance()->project(); if (!proj || !proj->scriptCollection()) return; @@ -368,7 +432,7 @@ void RimUiTreeModelPdm::updateScriptPaths() //-------------------------------------------------------------------------------------------------- void RimUiTreeModelPdm::slotRefreshScriptTree(QString path) { - RimProject* proj = RIApplication::instance()->project(); + RimProject* proj = RiaApplication::instance()->project(); if (!proj || !proj->scriptCollection()) return; @@ -390,13 +454,11 @@ void RimUiTreeModelPdm::addInputProperty(const QModelIndex& itemIndex, const QSt RimInputPropertyCollection* inputPropertyCollection = dynamic_cast(currentItem->dataObject().p()); CVF_ASSERT(inputPropertyCollection); - std::vector parentObjects; - inputPropertyCollection->parentObjects(parentObjects); - - + std::vector parentObjects; + inputPropertyCollection->parentObjectsOfType(parentObjects); CVF_ASSERT(parentObjects.size() == 1); - RimInputReservoir* inputReservoir = dynamic_cast(parentObjects[0]); + RimInputCase* inputReservoir = parentObjects[0]; CVF_ASSERT(inputReservoir); if (inputReservoir) { @@ -421,24 +483,398 @@ void RimUiTreeModelPdm::deleteInputProperty(const QModelIndex& itemIndex) if (!inputProperty) return; // Remove item from UI tree model before delete of project data structure - removeRow(itemIndex.row(), itemIndex.parent()); + removeRows_special(itemIndex.row(), 1, itemIndex.parent()); - std::vector parentObjects; - object->parentObjects(parentObjects); + std::vector parentObjects; + object->parentObjectsOfType(parentObjects); CVF_ASSERT(parentObjects.size() == 1); - RimInputPropertyCollection* inputPropertyCollection = dynamic_cast(parentObjects[0]); + RimInputPropertyCollection* inputPropertyCollection = parentObjects[0]; if (!inputPropertyCollection) return; - std::vector parentObjects2; - inputPropertyCollection->parentObjects(parentObjects2); + std::vector parentObjects2; + inputPropertyCollection->parentObjectsOfType(parentObjects2); CVF_ASSERT(parentObjects2.size() == 1); - RimInputReservoir* inputReservoir = dynamic_cast(parentObjects2[0]); + RimInputCase* inputReservoir = parentObjects2[0]; if (!inputReservoir) return; inputReservoir->removeProperty(inputProperty); delete inputProperty; + + clearClipboard(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCase* RimUiTreeModelPdm::addStatisticalCalculation(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex) +{ + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); + + QModelIndex collectionIndex; + RimIdenticalGridCaseGroup* caseGroup = NULL; + caf::PdmUiTreeItem* parentCollectionItem = NULL; + int position = 0; + + if (dynamic_cast(currentItem->dataObject().p())) + { + RimStatisticsCase* currentObject = dynamic_cast(currentItem->dataObject().p()); + caseGroup = currentObject->parentStatisticsCaseCollection()->parentCaseGroup(); + parentCollectionItem = currentItem->parent(); + position = itemIndex.row(); + collectionIndex = itemIndex.parent(); + } + else if (dynamic_cast(currentItem->dataObject().p())) + { + RimCaseCollection* statColl = dynamic_cast(currentItem->dataObject().p()); + caseGroup = statColl->parentCaseGroup(); + parentCollectionItem = currentItem; + position = parentCollectionItem->childCount(); + collectionIndex = itemIndex; + } + + if (parentCollectionItem && caseGroup) + { + beginInsertRows(collectionIndex, position, position); + + RimStatisticsCase* createdObject = caseGroup->createAndAppendStatisticsCase(); + caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(parentCollectionItem, position, createdObject); + + endInsertRows(); + + insertedModelIndex = index(position, 0, collectionIndex); + + return createdObject; + } + else + { + return NULL; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup* RimUiTreeModelPdm::addCaseGroup(QModelIndex& insertedModelIndex) +{ + RimProject* proj = RiaApplication::instance()->project(); + CVF_ASSERT(proj); + + QModelIndex scriptModelIndex = getModelIndexFromPdmObject(proj->scriptCollection()); + if (!scriptModelIndex.isValid()) return NULL; + + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(scriptModelIndex); + if (!currentItem) return NULL; + + QModelIndex rootIndex = scriptModelIndex.parent(); + caf::PdmUiTreeItem* rootTreeItem = currentItem->parent(); + + // New case group is inserted before the last item, the script item + int position = rootTreeItem->childCount() - 1; + + beginInsertRows(rootIndex, position, position); + + RimIdenticalGridCaseGroup* createdObject = new RimIdenticalGridCaseGroup; + createdObject->createAndAppendStatisticsCase(); + createdObject->name = QString("Grid Case Group %1").arg(position + 1); + proj->caseGroups().push_back(createdObject); + + caf::PdmUiTreeItem* childItem = caf::UiTreeItemBuilderPdm::buildViewItems(rootTreeItem, position, createdObject); + endInsertRows(); + + insertedModelIndex = index(position, 0, rootIndex); + + return createdObject; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects) +{ + RimProject* proj = RiaApplication::instance()->project(); + CVF_ASSERT(proj); + + RimIdenticalGridCaseGroup* gridCaseGroup = gridCaseGroupFromItemIndex(itemIndex); + if (gridCaseGroup) + { + std::vector > typedObjects; + pdmObjects.createCopyByType(&typedObjects); + + if (typedObjects.size() == 0) + { + return; + } + + RimResultCase* mainResultCase = NULL; + std::vector< std::vector > mainCaseGridDimensions; + + // Read out main grid and main grid dimensions if present in case group + if (gridCaseGroup->mainCase()) + { + mainResultCase = dynamic_cast(gridCaseGroup->mainCase()); + CVF_ASSERT(mainResultCase); + + mainResultCase->readGridDimensions(mainCaseGridDimensions); + } + + // Add cases to case group + for (size_t i = 0; i < typedObjects.size(); i++) + { + RimResultCase* rimResultReservoir = typedObjects[i]; + + if (gridCaseGroup->contains(rimResultReservoir)) + { + continue; + } + + if (!mainResultCase) + { + rimResultReservoir->openEclipseGridFile(); + rimResultReservoir->readGridDimensions(mainCaseGridDimensions); + + mainResultCase = rimResultReservoir; + } + else + { + std::vector< std::vector > caseGridDimensions; + rimResultReservoir->readGridDimensions(caseGridDimensions); + + bool identicalGrid = RigGridManager::isGridDimensionsEqual(mainCaseGridDimensions, caseGridDimensions); + if (!identicalGrid) + { + continue; + } + + if (!rimResultReservoir->openAndReadActiveCellData(mainResultCase->reservoirData())) + { + CVF_ASSERT(false); + } + } + + proj->insertCaseInCaseGroup(gridCaseGroup, rimResultReservoir); + + caf::PdmObjectGroup::initAfterReadTraversal(rimResultReservoir); + + { + QModelIndex rootIndex = getModelIndexFromPdmObject(gridCaseGroup->caseCollection()); + caf::PdmUiTreeItem* caseCollectionUiItem = getTreeItemFromIndex(rootIndex); + + int position = rowCount(rootIndex); + beginInsertRows(rootIndex, position, position); + caf::PdmUiTreeItem* childItem = caf::UiTreeItemBuilderPdm::buildViewItems(caseCollectionUiItem, -1, rimResultReservoir); + endInsertRows(); + } + + for (size_t i = 0; i < rimResultReservoir->reservoirViews.size(); i++) + { + RimReservoirView* riv = rimResultReservoir->reservoirViews()[i]; + riv->loadDataAndUpdate(); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeModelPdm::moveObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects) +{ + addObjects(itemIndex, pdmObjects); + + // Delete objects from original container + std::vector > typedObjects; + pdmObjects.objectsByType(&typedObjects); + + for (size_t i = 0; i < typedObjects.size(); i++) + { + RimCase* rimReservoir = typedObjects[i]; + deleteReservoir(rimReservoir); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimUiTreeModelPdm::deleteObjectFromPdmPointersField(const QModelIndex& itemIndex) +{ + if (!itemIndex.isValid()) + { + return false; + } + + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); + CVF_ASSERT(currentItem); + + caf::PdmObject* currentPdmObject = currentItem->dataObject().p(); + CVF_ASSERT(currentPdmObject); + + std::vector parentFields; + currentPdmObject->parentFields(parentFields); + + if (parentFields.size() == 1) + { + beginRemoveRows(itemIndex.parent(), itemIndex.row(), itemIndex.row()); + if (currentItem->parent()) + { + currentItem->parent()->removeChildren(itemIndex.row(), 1); + } + endRemoveRows(); + + caf::PdmPointersField* caseGroup = dynamic_cast *>(parentFields[0]); + if (caseGroup) + { + caseGroup->removeChildObject(currentPdmObject); + + delete currentPdmObject; + } + } + + clearClipboard(); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeModelPdm::clearClipboard() +{ + // We use QModelIndex to identify a selection on the clipboard + // When we delete or move an entity, the clipboard data might be invalid + + QClipboard* clipboard = QApplication::clipboard(); + if (clipboard) + { + if (dynamic_cast(clipboard->mimeData())) + { + clipboard->clear(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Qt::DropActions RimUiTreeModelPdm::supportedDropActions() const +{ + return Qt::CopyAction | Qt::MoveAction; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Qt::ItemFlags RimUiTreeModelPdm::flags(const QModelIndex &index) const +{ + Qt::ItemFlags defaultFlags = caf::UiTreeModelPdm::flags(index); + if (index.isValid()) + { + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(index); + CVF_ASSERT(currentItem); + + if (dynamic_cast(currentItem->dataObject().p()) || + dynamic_cast(currentItem->dataObject().p())) + { + return Qt::ItemIsDropEnabled | defaultFlags; + } + else if (dynamic_cast(currentItem->dataObject().p())) + { + // TODO: Remember to handle reservoir holding the main grid + return Qt::ItemIsDragEnabled | defaultFlags; + } + } + + return defaultFlags; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimUiTreeModelPdm::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + const MimeDataWithIndexes* myMimeData = qobject_cast(data); + if (myMimeData && parent.isValid()) + { + caf::PdmObjectGroup pog; + + for (int i = 0; i < myMimeData->indexes().size(); i++) + { + QModelIndex mi = myMimeData->indexes().at(i); + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(mi); + caf::PdmObject* pdmObj = currentItem->dataObject().p(); + + pog.objects().push_back(pdmObj); + } + + if (action == Qt::CopyAction) + { + addObjects(parent, pog); + } + else if (action == Qt::MoveAction) + { + moveObjects(parent, pog); + } + + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QMimeData* RimUiTreeModelPdm::mimeData(const QModelIndexList &indexes) const +{ + MimeDataWithIndexes* myObj = new MimeDataWithIndexes(); + myObj->setIndexes(indexes); + return myObj; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RimUiTreeModelPdm::mimeTypes() const +{ + QStringList types; + types << MimeDataWithIndexes::formatName(); + return types; +} + +//-------------------------------------------------------------------------------------------------- +/// Return grid case group when QModelIndex points to grid case group, case collection or case in a grid case group +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup* RimUiTreeModelPdm::gridCaseGroupFromItemIndex(const QModelIndex& itemIndex) +{ + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); + + RimIdenticalGridCaseGroup* gridCaseGroup = NULL; + + if (dynamic_cast(currentItem->dataObject().p())) + { + gridCaseGroup = dynamic_cast(currentItem->dataObject().p()); + } + else if (dynamic_cast(currentItem->dataObject().p())) + { + RimCaseCollection* caseCollection = dynamic_cast(currentItem->dataObject().p()); + CVF_ASSERT(caseCollection); + + gridCaseGroup = caseCollection->parentCaseGroup(); + } + else if (dynamic_cast(currentItem->dataObject().p())) + { + RimCase* rimReservoir = dynamic_cast(currentItem->dataObject().p()); + CVF_ASSERT(rimReservoir); + + RimCaseCollection* caseCollection = rimReservoir->parentCaseCollection(); + if (caseCollection) + { + gridCaseGroup = caseCollection->parentCaseGroup(); + } + } + + return gridCaseGroup; } diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h index 1e41d090a3..dc265b738f 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h +++ b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h @@ -20,15 +20,71 @@ #include "cafPdmObject.h" #include "cafPdmPointer.h" +#include "cafPdmDocument.h" #include "cafUiTreeModelPdm.h" +#include + class QFileSystemWatcher; class RimCellPropertyFilter; class RimCellRangeFilter; +class RimCase; class RimReservoirView; class RimInputProperty; +class RimStatisticsCase; +class RimIdenticalGridCaseGroup; +//-------------------------------------------------------------------------------------------------- +/// MimeData class used to carry a QModelIndexList +//-------------------------------------------------------------------------------------------------- +class MimeDataWithIndexes : public QMimeData +{ + Q_OBJECT + +public: + MimeDataWithIndexes() + { + } + + + MimeDataWithIndexes(const MimeDataWithIndexes & other) : QMimeData() + { + setIndexes(other.indexes()); + } + + void setIndexes(const QModelIndexList & indexes) + { + m_indexes = indexes; + } + + const QModelIndexList& indexes() const { return m_indexes; } + + virtual bool hasFormat( const QString &mimetype ) const + { + return (mimetype == formatName()); + } + + virtual QStringList formats() const + { + QStringList supportedFormats = QMimeData::formats(); + supportedFormats << formatName(); + + return supportedFormats; + } + + static QString formatName() + { + return "MimeDataWithIndexes"; + } + +private: + QModelIndexList m_indexes; +}; + +Q_DECLARE_METATYPE(MimeDataWithIndexes) + + //================================================================================================== /// /// @@ -40,31 +96,47 @@ class RimUiTreeModelPdm : public caf::UiTreeModelPdm public: RimUiTreeModelPdm(QObject* parent); - // Overrides - virtual bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + + // TO BE DELETED, NOT USED + virtual bool insertRows_special(int position, int rows, const QModelIndex &parent = QModelIndex()); // Special edit methods - bool deleteRangeFilter(const QModelIndex& itemIndex); - bool deletePropertyFilter(const QModelIndex& itemIndex); - bool deleteReservoirView(const QModelIndex& itemIndex); - void deleteInputProperty(const QModelIndex& itemIndex); - void deleteReservoir(const QModelIndex& itemIndex); + bool deleteRangeFilter(const QModelIndex& itemIndex); + bool deletePropertyFilter(const QModelIndex& itemIndex); + bool deleteReservoirView(const QModelIndex& itemIndex); + void deleteInputProperty(const QModelIndex& itemIndex); + void deleteReservoir(RimCase* reservoir); - RimCellPropertyFilter* addPropertyFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); - RimCellRangeFilter* addRangeFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); - RimReservoirView* addReservoirView(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); - void addInputProperty(const QModelIndex& itemIndex, const QStringList& fileNames); + RimCellPropertyFilter* addPropertyFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); + RimCellRangeFilter* addRangeFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); + RimReservoirView* addReservoirView(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); + void addInputProperty(const QModelIndex& itemIndex, const QStringList& fileNames); + + void addObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects); + void moveObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects); + + RimStatisticsCase* addStatisticalCalculation(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); + RimIdenticalGridCaseGroup* addCaseGroup(QModelIndex& insertedModelIndex); - void updateScriptPaths(); + bool deleteObjectFromPdmPointersField(const QModelIndex& itemIndex); + + void updateScriptPaths(); + + virtual Qt::DropActions supportedDropActions() const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); + virtual QMimeData* mimeData(const QModelIndexList &indexes) const; + virtual QStringList mimeTypes() const; + + RimIdenticalGridCaseGroup* gridCaseGroupFromItemIndex(const QModelIndex& itemIndex); private slots: - void slotRefreshScriptTree(QString path); + void slotRefreshScriptTree(QString path); private: - QFileSystemWatcher* m_scriptChangeDetector; + void clearClipboard(); + +private: + QFileSystemWatcher* m_scriptChangeDetector; }; - - - - diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp index 624104775e..7dbdeea1d3 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp +++ b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp @@ -16,21 +16,25 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" + +#include "cafPdmDocument.h" #include "RimUiTreeView.h" #include "RimUiTreeModelPdm.h" #include "RimReservoirView.h" #include "RimCalcScript.h" -#include "RIApplication.h" -#include "RIMainWindow.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" #include "RimInputPropertyCollection.h" #include "RimExportInputPropertySettings.h" -#include "RIPreferencesDialog.h" +#include "RiuPreferencesDialog.h" #include "RifEclipseInputFileTools.h" -#include "RimInputReservoir.h" +#include "RimInputCase.h" #include "RimBinaryExportSettings.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" +#include "RimStatisticsCase.h" +#include "RimResultCase.h" //-------------------------------------------------------------------------------------------------- /// @@ -39,6 +43,16 @@ RimUiTreeView::RimUiTreeView(QWidget *parent /*= 0*/) : QTreeView(parent) { setHeaderHidden(true); + + m_pasteAction = new QAction(QString("Paste"), this); + connect(m_pasteAction, SIGNAL(triggered()), SLOT(slotPastePdmObjects())); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimUiTreeView::~RimUiTreeView() +{ } //-------------------------------------------------------------------------------------------------- @@ -46,12 +60,25 @@ RimUiTreeView::RimUiTreeView(QWidget *parent /*= 0*/) //-------------------------------------------------------------------------------------------------- void RimUiTreeView::contextMenuEvent(QContextMenuEvent* event) { + m_pasteAction->setEnabled(hasClipboardValidData()); + + if (selectionModel() && selectionModel()->selection().size() == 0) + { + // Clicking in blank space in tree view + QMenu menu; + menu.addAction(QString("New Grid Case Group"), this, SLOT(slotAddCaseGroup())); + menu.exec(event->globalPos()); + + return; + } + RimUiTreeModelPdm* myModel = dynamic_cast(model()); if (myModel) { caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); if (uiItem && uiItem->dataObject()) { + // Range filters if (dynamic_cast(uiItem->dataObject().p())) { @@ -100,7 +127,7 @@ void RimUiTreeView::contextMenuEvent(QContextMenuEvent* event) } else if (dynamic_cast(uiItem->dataObject().p())) { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QMenu menu; { @@ -143,12 +170,52 @@ void RimUiTreeView::contextMenuEvent(QContextMenuEvent* event) menu.addAction(QString("Save Property To File"), this, SLOT(slotWriteBinaryResultAsInputProperty())); menu.exec(event->globalPos()); } - else if (dynamic_cast(uiItem->dataObject().p())) + else if (dynamic_cast(uiItem->dataObject().p())) { QMenu menu; + menu.addAction(QString("New Statistcs Case"), this, SLOT(slotNewStatisticsCase())); + menu.exec(event->globalPos()); + } + else if (dynamic_cast(uiItem->dataObject().p())) + { + QMenu menu; + menu.addAction(QString("New View"), this, SLOT(slotAddView())); + menu.addAction(QString("Compute"), this, SLOT(slotComputeStatistics())); menu.addAction(QString("Close"), this, SLOT(slotCloseCase())); menu.exec(event->globalPos()); } + else if (dynamic_cast(uiItem->dataObject().p())) + { + QMenu menu; + menu.addAction(QString("Copy"), this, SLOT(slotCopyPdmObjectToClipboard())); + menu.addAction(m_pasteAction); + menu.addAction(QString("Close"), this, SLOT(slotCloseCase())); + menu.addAction(QString("New View"), this, SLOT(slotAddView())); + menu.addAction(QString("New Grid Case Group"), this, SLOT(slotAddCaseGroup())); + menu.exec(event->globalPos()); + } + else if (dynamic_cast(uiItem->dataObject().p())) + { + QMenu menu; + menu.addAction(QString("New Grid Case Group"), this, SLOT(slotAddCaseGroup())); + menu.addAction(m_pasteAction); + menu.addAction(QString("Close"), this, SLOT(slotDeleteObjectFromPdmPointersField())); + menu.exec(event->globalPos()); + } + else if (dynamic_cast(uiItem->dataObject().p())) + { + QMenu menu; + menu.addAction(m_pasteAction); + + // Check if parent field is a StatisticsCaseCollection + RimCaseCollection* rimCaseCollection = dynamic_cast(uiItem->dataObject().p()); + if (RimIdenticalGridCaseGroup::isStatisticsCaseCollection(rimCaseCollection)) + { + menu.addAction(QString("New Statistics Case"), this, SLOT(slotNewStatisticsCase())); + } + + menu.exec(event->globalPos()); + } } } } @@ -368,7 +435,7 @@ void RimUiTreeView::slotEditScript() { RimCalcScript* calcScript = dynamic_cast(uiItem->dataObject().p()); - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString scriptEditor = app->scriptEditorPath(); if (!scriptEditor.isEmpty()) { @@ -380,7 +447,7 @@ void RimUiTreeView::slotEditScript() if (!myProcess->waitForStarted(1000)) { - QMessageBox::warning(RIMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor); + QMessageBox::warning(RiuMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor); } } } @@ -425,7 +492,7 @@ void RimUiTreeView::slotNewScript() num++; } - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString scriptEditor = app->scriptEditorPath(); if (!scriptEditor.isEmpty()) { @@ -437,7 +504,7 @@ void RimUiTreeView::slotNewScript() if (!myProcess->waitForStarted(1000)) { - QMessageBox::warning(RIMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor); + QMessageBox::warning(RiuMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor); } } } @@ -455,7 +522,7 @@ void RimUiTreeView::slotExecuteScript() { RimCalcScript* calcScript = dynamic_cast(uiItem->dataObject().p()); - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString octavePath = app->octavePath(); if (!octavePath.isEmpty()) { @@ -482,7 +549,7 @@ void RimUiTreeView::slotExecuteScript() arguments.append("-q"); arguments << calcScript->absolutePath(); - RIApplication::instance()->launchProcess(octavePath, arguments); + RiaApplication::instance()->launchProcess(octavePath, arguments); } } } @@ -496,12 +563,8 @@ void RimUiTreeView::slotAddView() RimUiTreeModelPdm* myModel = dynamic_cast(model()); caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - RimReservoirView* rimView = dynamic_cast(uiItem->dataObject().p()); - if (rimView) - { - QModelIndex insertedIndex; - myModel->addReservoirView(index, insertedIndex); - } + QModelIndex insertedIndex; + myModel->addReservoirView(index, insertedIndex); } @@ -515,7 +578,7 @@ void RimUiTreeView::slotDeleteView() { myModel->deleteReservoirView(currentIndex()); - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->setActiveReservoirView(NULL); } } @@ -565,7 +628,7 @@ void RimUiTreeView::setModel(QAbstractItemModel* model) //-------------------------------------------------------------------------------------------------- void RimUiTreeView::slotAddInputProperty() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString defaultDir = app->defaultFileDialogDirectory("INPUT_FILES"); QStringList fileNames = QFileDialog::getOpenFileNames(this, "Select Eclipse Input Property Files", defaultDir, "All Files (*.* *)"); @@ -623,7 +686,7 @@ void RimUiTreeView::slotWriteInputProperty() if (!isResolved) { - QMessageBox::warning(RIMainWindow::instance(), "Export failure", "Property is not resolved, and then it is not possible to export the property."); + QMessageBox::warning(RiuMainWindow::instance(), "Export failure", "Property is not resolved, and then it is not possible to export the property."); return; } @@ -633,20 +696,20 @@ void RimUiTreeView::slotWriteInputProperty() exportSettings.eclipseKeyword = inputProperty->eclipseKeyword; // Find input reservoir for this property - RimInputReservoir* inputReservoir = NULL; + RimInputCase* inputReservoir = NULL; { - std::vector parentObjects; - inputProperty->parentObjects(parentObjects); + std::vector parentObjects; + inputProperty->parentObjectsOfType(parentObjects); CVF_ASSERT(parentObjects.size() == 1); - RimInputPropertyCollection* inputPropertyCollection = dynamic_cast(parentObjects[0]); + RimInputPropertyCollection* inputPropertyCollection = parentObjects[0]; if (!inputPropertyCollection) return; - std::vector parentObjects2; - inputPropertyCollection->parentObjects(parentObjects2); + std::vector parentObjects2; + inputPropertyCollection->parentObjectsOfType(parentObjects2); CVF_ASSERT(parentObjects2.size() == 1); - inputReservoir = dynamic_cast(parentObjects2[0]); + inputReservoir = parentObjects2[0]; } if (!inputReservoir) return; @@ -654,7 +717,7 @@ void RimUiTreeView::slotWriteInputProperty() { QString projectFolder; - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString projectFileName = app->currentProjectFileName(); if (!projectFileName.isEmpty()) { @@ -671,7 +734,7 @@ void RimUiTreeView::slotWriteInputProperty() exportSettings.fileName = outputFileName; } - RIPreferencesDialog preferencesDialog(this, &exportSettings, "Export Eclipse Property to Text File"); + RiuPreferencesDialog preferencesDialog(this, &exportSettings, "Export Eclipse Property to Text File"); if (preferencesDialog.exec() == QDialog::Accepted) { bool isOk = RifEclipseInputFileTools::writePropertyToTextFile(exportSettings.fileName, inputReservoir->reservoirData(), 0, inputProperty->resultName, exportSettings.eclipseKeyword); @@ -707,7 +770,7 @@ void RimUiTreeView::slotWriteBinaryResultAsInputProperty() { QString projectFolder; - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString projectFileName = app->currentProjectFileName(); if (!projectFileName.isEmpty()) { @@ -724,11 +787,11 @@ void RimUiTreeView::slotWriteBinaryResultAsInputProperty() exportSettings.fileName = outputFileName; } - RIPreferencesDialog preferencesDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File"); + RiuPreferencesDialog preferencesDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File"); if (preferencesDialog.exec() == QDialog::Accepted) { size_t timeStep = resultSlot->reservoirView()->currentTimeStep(); - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(resultSlot->porosityModel()); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultSlot->porosityModel()); bool isOk = RifEclipseInputFileTools::writeBinaryResultToTextFile(exportSettings.fileName, resultSlot->reservoirView()->eclipseCase()->reservoirData(), porosityModel, timeStep, resultSlot->resultVariable, exportSettings.eclipseKeyword, exportSettings.undefinedValue); if (!isOk) @@ -743,10 +806,340 @@ void RimUiTreeView::slotWriteBinaryResultAsInputProperty() //-------------------------------------------------------------------------------------------------- void RimUiTreeView::slotCloseCase() { - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) + QModelIndexList miList; + miList << currentIndex(); + + if (userConfirmedGridCaseGroupChange(miList)) { - myModel->deleteReservoir(currentIndex()); + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + if (myModel) + { + QItemSelectionModel* m = selectionModel(); + CVF_ASSERT(m); + + caf::PdmObjectGroup group; + + QModelIndexList mil = m->selectedRows(); + for (int i = 0; i < mil.size(); i++) + { + caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(mil.at(i)); + group.addObject(uiItem->dataObject().p()); + } + + std::vector > typedObjects; + group.objectsByType(&typedObjects); + + for (size_t i = 0; i < typedObjects.size(); i++) + { + RimCase* rimReservoir = typedObjects[i]; + myModel->deleteReservoir(rimReservoir); + } + } } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::slotNewStatisticsCase() +{ + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + if (myModel) + { + QModelIndex insertedIndex; + RimStatisticsCase* newObject = myModel->addStatisticalCalculation(currentIndex(), insertedIndex); + setCurrentIndex(insertedIndex); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::slotComputeStatistics() +{ + QModelIndex index = currentIndex(); + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); + + RimStatisticsCase* statisticsCase = dynamic_cast(uiItem->dataObject().p()); + if (!statisticsCase) return; + + statisticsCase->computeStatistics(); + + if (statisticsCase->reservoirViews.size() == 0) + { + slotAddView(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::slotAddCaseGroup() +{ + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + if (myModel) + { + QModelIndex insertedIndex; + myModel->addCaseGroup(insertedIndex); + setCurrentIndex(insertedIndex); + + setExpanded(insertedIndex, true); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::slotDeleteObjectFromPdmPointersField() +{ + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + if (myModel) + { + myModel->deleteObjectFromPdmPointersField(currentIndex()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::slotCopyPdmObjectToClipboard() +{ + QItemSelectionModel* m = selectionModel(); + + QModelIndexList mil = m->selectedRows(); + if (mil.size() == 0) + { + return; + } + + MimeDataWithIndexes* myObject = new MimeDataWithIndexes; + myObject->setIndexes(mil); + + QClipboard* clipboard = QApplication::clipboard(); + if (clipboard) + { + clipboard->setMimeData(myObject); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::slotPastePdmObjects() +{ + if (!currentIndex().isValid()) return; + + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + if (!myModel) return; + + QModelIndexList miList; + miList << currentIndex(); + if (userConfirmedGridCaseGroupChange(miList)) + { + caf::PdmObjectGroup objectGroup; + createPdmObjectsFromClipboard(&objectGroup); + if (objectGroup.objects().size() == 0) return; + + myModel->addObjects(currentIndex(), objectGroup); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::createPdmObjectsFromClipboard(caf::PdmObjectGroup* objectGroup) +{ + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + if (!myModel) return; + + QClipboard* clipboard = QApplication::clipboard(); + if (!clipboard) return; + + const MimeDataWithIndexes* mdWithIndexes = dynamic_cast(clipboard->mimeData()); + if (!mdWithIndexes) return; + + QModelIndexList indexList = mdWithIndexes->indexes(); + for (int i = 0; i < indexList.size(); i++) + { + caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(indexList.at(i)); + objectGroup->addObject(uiItem->dataObject().p()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::keyPressEvent(QKeyEvent* keyEvent) +{ + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); + + if (dynamic_cast(uiItem->dataObject().p())) + { + if (keyEvent->matches(QKeySequence::Copy)) + { + slotCopyPdmObjectToClipboard(); + keyEvent->setAccepted(true); + + return; + } + } + + if (dynamic_cast(uiItem->dataObject().p()) + || dynamic_cast(uiItem->dataObject().p()) + || dynamic_cast(uiItem->dataObject().p())) + { + if (keyEvent->matches(QKeySequence::Paste)) + { + slotPastePdmObjects(); + keyEvent->setAccepted(true); + + return; + } + } + + QTreeView::keyPressEvent(keyEvent); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimUiTreeView::hasClipboardValidData() +{ + QClipboard* clipboard = QApplication::clipboard(); + if (clipboard) + { + if (dynamic_cast(clipboard->mimeData())) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::dropEvent(QDropEvent* dropEvent) +{ + QModelIndexList affectedModels; + + if (dropEvent->dropAction() == Qt::MoveAction) + { + const MimeDataWithIndexes* myMimeData = qobject_cast(dropEvent->mimeData()); + if (myMimeData) + { + affectedModels = myMimeData->indexes(); + } + } + + QModelIndex dropIndex = indexAt(dropEvent->pos()); + if (dropIndex.isValid()) + { + affectedModels.push_back(dropIndex); + } + + if (userConfirmedGridCaseGroupChange(affectedModels)) + { + QTreeView::dropEvent(dropEvent); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Displays a question to the user when a grid case group with statistical results is about to change +//-------------------------------------------------------------------------------------------------- +bool RimUiTreeView::userConfirmedGridCaseGroupChange(const QModelIndexList& itemIndexList) +{ + if (itemIndexList.size() == 0) return true; + + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + if (myModel) + { + caf::PdmObjectGroup pog; + + for (int i = 0; i < itemIndexList.size(); i++) + { + QModelIndex itemIndex = itemIndexList.at(i); + if (!itemIndex.isValid()) continue; + + RimIdenticalGridCaseGroup* gridCaseGroup = myModel->gridCaseGroupFromItemIndex(itemIndex); + if (gridCaseGroup) + { + if (hasAnyStatisticsResults(gridCaseGroup)) + { + if (pog.objects().count(gridCaseGroup) == 0) + { + pog.addObject(gridCaseGroup); + } + } + } + } + + std::vector > typedObjects; + pog.objectsByType(&typedObjects); + + if (typedObjects.size() > 0) + { + RiuMainWindow* mainWnd = RiuMainWindow::instance(); + + QMessageBox msgBox(mainWnd); + msgBox.setIcon(QMessageBox::Question); + + QString questionText; + if (typedObjects.size() == 1) + { + questionText = QString("This operation will invalidate statistics results in grid case group\n\"%1\".\n").arg(typedObjects[0]->name()); + questionText += "Computed results in this group will be deleted if you continue."; + } + else + { + questionText = "This operation will invalidate statistics results in grid case groups\n"; + for (int i = 0; i < typedObjects.size(); i++) + { + questionText += QString("\"%1\"\n").arg(typedObjects[i]->name()); + } + + questionText += "Computed results in these groups will be deleted if you continue."; + } + + msgBox.setText(questionText); + msgBox.setInformativeText("Do you want to continue?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + + int ret = msgBox.exec(); + if (ret == QMessageBox::No) + { + return false; + } + } + + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimUiTreeView::hasAnyStatisticsResults(RimIdenticalGridCaseGroup* gridCaseGroup) +{ + CVF_ASSERT(gridCaseGroup); + + for (size_t i = 0; i < gridCaseGroup->statisticsCaseCollection()->reservoirs().size(); i++) + { + RimStatisticsCase* rimStaticsCase = dynamic_cast(gridCaseGroup->statisticsCaseCollection()->reservoirs[i]); + if (rimStaticsCase) + { + if (rimStaticsCase->hasComputedStatistics()) + { + return true; + } + } + } + + return false; +} + diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeView.h b/ApplicationCode/ProjectDataModel/RimUiTreeView.h index 30c4723e76..a18672b20a 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeView.h +++ b/ApplicationCode/ProjectDataModel/RimUiTreeView.h @@ -23,6 +23,11 @@ #include class QItemSelection; +class RimIdenticalGridCaseGroup; + +namespace caf { + class PdmObjectGroup; +} //================================================================================================== /// @@ -34,6 +39,7 @@ class RimUiTreeView : public QTreeView public: RimUiTreeView(QWidget *parent = 0); + ~RimUiTreeView(); virtual void setModel(QAbstractItemModel* model); @@ -69,11 +75,32 @@ private slots: void slotCloseCase(); + void slotNewStatisticsCase(); + void slotComputeStatistics(); + + void slotAddCaseGroup(); + void slotDeleteObjectFromPdmPointersField(); + + void slotCopyPdmObjectToClipboard(); + void slotPastePdmObjects(); + void slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); signals: void selectedObjectChanged( caf::PdmObject* pdmObject ); + +private: + bool userConfirmedGridCaseGroupChange(const QModelIndexList& itemIndexList); + bool hasAnyStatisticsResults(RimIdenticalGridCaseGroup* gridCaseGroup); + + void createPdmObjectsFromClipboard(caf::PdmObjectGroup* objectGroup); + bool hasClipboardValidData(); + + virtual void keyPressEvent(QKeyEvent* keyEvent); + virtual void dropEvent(QDropEvent* dropEvent); + +private: + QAction* m_pasteAction; }; - diff --git a/ApplicationCode/ProjectDataModel/RimWell.cpp b/ApplicationCode/ProjectDataModel/RimWell.cpp index 59b8a9ea4e..893a3d13ae 100644 --- a/ApplicationCode/ProjectDataModel/RimWell.cpp +++ b/ApplicationCode/ProjectDataModel/RimWell.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cafAppEnum.h" diff --git a/ApplicationCode/ProjectDataModel/RimWell.h b/ApplicationCode/ProjectDataModel/RimWell.h index 56e405fe77..a9f18b1ea7 100644 --- a/ApplicationCode/ProjectDataModel/RimWell.h +++ b/ApplicationCode/ProjectDataModel/RimWell.h @@ -24,7 +24,7 @@ #include "cafAppEnum.h" #include "cafPdmFieldCvfColor.h" -#include "RigWellResults.h" +#include "RigSingleWellResultsData.h" class RimReservoirView; //================================================================================================== @@ -41,8 +41,8 @@ public: void setReservoirView(RimReservoirView* ownerReservoirView); - void setWellResults(RigWellResults* wellResults) { m_wellResults = wellResults;} - RigWellResults* wellResults() { return m_wellResults.p();} + void setWellResults(RigSingleWellResultsData* wellResults) { m_wellResults = wellResults;} + RigSingleWellResultsData* wellResults() { return m_wellResults.p();} virtual caf::PdmFieldHandle* userDescriptionField(); @@ -61,7 +61,7 @@ public: caf::PdmField pipeRadiusScaleFactor; private: - cvf::ref m_wellResults; + cvf::ref m_wellResults; RimReservoirView* m_reservoirView; }; diff --git a/ApplicationCode/ProjectDataModel/RimWellCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellCollection.cpp index 8e115ecde6..d1fd3f5ba0 100644 --- a/ApplicationCode/ProjectDataModel/RimWellCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellCollection.cpp @@ -16,13 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cafAppEnum.h" #include "cafPdmFieldCvfColor.h" -#include "RigWellResults.h" +#include "RigSingleWellResultsData.h" #include "RimWellCollection.h" #include "RimWell.h" #include "RimReservoirView.h" diff --git a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake new file mode 100644 index 0000000000..e6f817fab5 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake @@ -0,0 +1,39 @@ + +# Use this workaround until we're on 2.8.3 on all platforms and can use CMAKE_CURRENT_LIST_DIR directly +if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") + set(CEE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}/) +endif() + + +list(APPEND CODE_HEADER_FILES +${CEE_CURRENT_LIST_DIR}RigActiveCellInfo.h +${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}RigLocalGrid.h +${CEE_CURRENT_LIST_DIR}RigMainGrid.h +${CEE_CURRENT_LIST_DIR}RigReservoirBuilderMock.h +${CEE_CURRENT_LIST_DIR}RigCaseCellResultsData.h +${CEE_CURRENT_LIST_DIR}RigSingleWellResultsData.h +${CEE_CURRENT_LIST_DIR}RigStatisticsMath.h + +) + +list(APPEND CODE_SOURCE_FILES +${CEE_CURRENT_LIST_DIR}RigActiveCellInfo.cpp +${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}RigLocalGrid.cpp +${CEE_CURRENT_LIST_DIR}RigMainGrid.cpp +${CEE_CURRENT_LIST_DIR}RigReservoirBuilderMock.cpp +${CEE_CURRENT_LIST_DIR}RigCaseCellResultsData.cpp +${CEE_CURRENT_LIST_DIR}RigSingleWellResultsData.cpp +${CEE_CURRENT_LIST_DIR}RigStatisticsMath.cpp +) + + diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/CMakeLists.txt b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/CMakeLists.txt index ca2ec9976e..3ed2140ef2 100644 --- a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/CMakeLists.txt +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/CMakeLists.txt @@ -22,10 +22,31 @@ include_directories( ${ResInsight_SOURCE_DIR}/cafProjectDataModel ${ResInsight_SOURCE_DIR}/CommonCode + + #Remove when RigStatistics is out + #${ResInsight_SOURCE_DIR}/ApplicationCode/ModelVisualization ) -file( GLOB CPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../*.cpp ) -file( GLOB UNIT_TEST_CPP_SOURCES *.cpp ) +# Populate the filenames into variable lists +include ("${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists_files.cmake") + + +set( UNIT_TEST_CPP_SOURCES + + ${ResInsight_SOURCE_DIR}/cafUserInterface/cafProgressInfo.cpp + + main.cpp + RigActiveCellInfo-Test.cpp + RigReservoir-Test.cpp + RigStatisticsMath-Test.cpp +) + + +############################################################################# +# Adds folders for Visual Studio solution explorer (and for Xcode explorer) +############################################################################# +source_group( "UnitTests" FILES ${UNIT_TEST_CPP_SOURCES} ) + set( LINK_LIBRARIES @@ -45,8 +66,9 @@ set( LINK_LIBRARIES add_executable( ${ProjectName} - ${CPP_SOURCES} + ${CODE_SOURCE_FILES} ${UNIT_TEST_CPP_SOURCES} + ${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists_files.cmake ${ResInsight_SOURCE_DIR}/ThirdParty/gtest/gtest-all.cc ) diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigActiveCellInfo-Test.cpp b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigActiveCellInfo-Test.cpp new file mode 100644 index 0000000000..57e99d4ec0 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigActiveCellInfo-Test.cpp @@ -0,0 +1,73 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "gtest/gtest.h" + +#include "RigActiveCellInfo.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigActiveCellInfo, BasicTest) +{ + RigActiveCellInfo rigActiveCellInfo; + + size_t globalActiveCellCount = 10; + rigActiveCellInfo.setGlobalCellCount(globalActiveCellCount); + + for (size_t i = 0; i < globalActiveCellCount; i++) + { + EXPECT_TRUE(rigActiveCellInfo.cellResultIndex(i) == cvf::UNDEFINED_SIZE_T); + EXPECT_FALSE(rigActiveCellInfo.isActive(i)); + } + + rigActiveCellInfo.setCellResultIndex(3, 1); + EXPECT_TRUE(rigActiveCellInfo.cellResultIndex(3) == 1); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigActiveCellInfo, GridCellCounts) +{ + { + RigActiveCellInfo rigActiveCellInfo; + rigActiveCellInfo.setGridCount(3); + rigActiveCellInfo.setGridActiveCellCounts(0, 0); + rigActiveCellInfo.setGridActiveCellCounts(1, 1); + rigActiveCellInfo.setGridActiveCellCounts(2, 2); + rigActiveCellInfo.computeDerivedData(); + + EXPECT_TRUE(rigActiveCellInfo.globalActiveCellCount() == 3); + } + + { + RigActiveCellInfo rigActiveCellInfo; + rigActiveCellInfo.setGridCount(3); + rigActiveCellInfo.setGridActiveCellCounts(0, 3 ); + rigActiveCellInfo.setGridActiveCellCounts(1, 4 ); + rigActiveCellInfo.setGridActiveCellCounts(2, 5 ); + rigActiveCellInfo.computeDerivedData(); + + EXPECT_TRUE(rigActiveCellInfo.globalActiveCellCount() == 12); + } +} diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigReservoir-Test.cpp b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigReservoir-Test.cpp index 6157a4751e..5fe9cd233b 100644 --- a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigReservoir-Test.cpp +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigReservoir-Test.cpp @@ -18,19 +18,85 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "gtest/gtest.h" -#include "RigReservoir.h" +#include "RigCaseData.h" +#include "RigGridManager.h" +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigGridManager, BasicTest) +{ + cvf::ref mainGridA = new RigMainGrid; + + cvf::ref eclipseCase = new RigCaseData; + eclipseCase->setMainGrid(mainGridA.p()); + + int count = mainGridA->refCount(); + EXPECT_EQ(mainGridA->refCount(), 2); + + RigGridManager gridCollection; + gridCollection.addCase(eclipseCase.p()); + EXPECT_EQ(mainGridA->refCount(), 2); + + cvf::ref mainGridB = mainGridA; + EXPECT_EQ(mainGridA->refCount(), 3); + + cvf::ref existingGrid = gridCollection.findEqualGrid(mainGridB.p()); + EXPECT_TRUE(existingGrid.notNull()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigGridManager, EqualTests) +{ + cvf::ref mainGridA = new RigMainGrid; + mainGridA->nodes().push_back(cvf::Vec3d(0, 0, 0)); + mainGridA->nodes().push_back(cvf::Vec3d(0, 0, 1)); + mainGridA->nodes().push_back(cvf::Vec3d(0, 0, 2)); + + cvf::ref eclipseCase = new RigCaseData; + eclipseCase->setMainGrid(mainGridA.p()); + + + RigGridManager gridCollection; + gridCollection.addCase(eclipseCase.p()); + + + cvf::ref mainGridB = new RigMainGrid; + cvf::ref existingGrid = gridCollection.findEqualGrid(mainGridB.p()); + EXPECT_TRUE(existingGrid.isNull()); + + mainGridB->nodes().push_back(cvf::Vec3d(0, 0, 0)); + existingGrid = gridCollection.findEqualGrid(mainGridB.p()); + EXPECT_TRUE(existingGrid.isNull()); + + // Insert nodes in opposite direction + mainGridB->nodes().push_back(cvf::Vec3d(0, 0, 2)); + mainGridB->nodes().push_back(cvf::Vec3d(0, 0, 1)); + existingGrid = gridCollection.findEqualGrid(mainGridB.p()); + EXPECT_TRUE(existingGrid.isNull()); + + // Overwrite to match the node structure of mainGridA + mainGridB->nodes()[1] = cvf::Vec3d(0, 0, 1); + mainGridB->nodes()[2] = cvf::Vec3d(0, 0, 2); + existingGrid = gridCollection.findEqualGrid(mainGridB.p()); + EXPECT_TRUE(existingGrid.notNull()); + +} + +/* //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(RigReservoirTest, BasicTest) { - cvf::ref wellCellTimeHistory = new RigWellResults; + cvf::ref wellCellTimeHistory = new RigSingleWellResultsData; QDateTime wellStartTime = QDateTime::currentDateTime(); @@ -44,7 +110,7 @@ TEST(RigReservoirTest, BasicTest) } int resultTimeStepCount = 2 * wellTimeStepCount; - QList resultTimes; + std::vector resultTimes; for (i = 0; i < resultTimeStepCount; i++) { resultTimes.push_back(QDateTime(wellStartTime).addMonths(i * 6)); @@ -62,3 +128,5 @@ TEST(RigReservoirTest, BasicTest) } + +*/ diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigStatisticsMath-Test.cpp b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigStatisticsMath-Test.cpp new file mode 100644 index 0000000000..7be162ef86 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigStatisticsMath-Test.cpp @@ -0,0 +1,143 @@ + + +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "gtest/gtest.h" + +#include "RigStatisticsMath.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigStatisticsMath, BasicTest) +{ + std::vector values; + values.push_back(HUGE_VAL); + values.push_back(2788.2723335651900); + values.push_back(-22481.0927881701000); + values.push_back(68778.6851686236000); + values.push_back(-76092.8157632591000); + values.push_back(6391.97999909729003); + values.push_back(65930.1200169780000); + values.push_back(-27696.2320267235000); + values.push_back(HUGE_VAL); + values.push_back(HUGE_VAL); + values.push_back(96161.7546348456000); + values.push_back(73875.6716288563000); + values.push_back(80720.4378655615000); + values.push_back(-98649.8109937874000); + values.push_back(99372.9362079615000); + values.push_back(HUGE_VAL); + values.push_back(-57020.4389966513000); + + double min, max, range, mean, stdev; + RigStatisticsMath::calculateBasicStatistics(values, &min, &max, &range, &mean, &stdev); + + EXPECT_DOUBLE_EQ(-98649.8109937874000, min ); + EXPECT_DOUBLE_EQ(99372.9362079615000 , max ); + EXPECT_DOUBLE_EQ(198022.7472017490000, range ); + EXPECT_DOUBLE_EQ(16313.8051759152000 , mean ); + EXPECT_DOUBLE_EQ(66104.391542887200 , stdev ); + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigStatisticsMath, RankPercentiles) +{ + std::vector values; + values.push_back(HUGE_VAL); + values.push_back(2788.2723335651900); + values.push_back(-22481.0927881701000); + values.push_back(68778.6851686236000); + values.push_back(-76092.8157632591000); + values.push_back(6391.97999909729003); + values.push_back(65930.1200169780000); + values.push_back(-27696.2320267235000); + values.push_back(HUGE_VAL); + values.push_back(HUGE_VAL); + values.push_back(96161.7546348456000); + values.push_back(73875.6716288563000); + values.push_back(80720.4378655615000); + values.push_back(-98649.8109937874000); + values.push_back(99372.9362079615000); + values.push_back(HUGE_VAL); + values.push_back(-57020.4389966513000); + + std::vector pValPos; + pValPos.push_back(10); + pValPos.push_back(40); + pValPos.push_back(50); + pValPos.push_back(90); + std::vector pVals = RigStatisticsMath::calculateNearestRankPercentiles(values, pValPos); + + EXPECT_DOUBLE_EQ( -76092.8157632591000, pVals[0]); + EXPECT_DOUBLE_EQ( 2788.2723335651900 , pVals[1]); + EXPECT_DOUBLE_EQ( 6391.979999097290 , pVals[2]); + EXPECT_DOUBLE_EQ( 96161.7546348456000 , pVals[3]); +} + + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigStatisticsMath, HistogramPercentiles) +{ + std::vector values; + values.push_back(HUGE_VAL); + values.push_back(2788.2723335651900); + values.push_back(-22481.0927881701000); + values.push_back(68778.6851686236000); + values.push_back(-76092.8157632591000); + values.push_back(6391.97999909729003); + values.push_back(65930.1200169780000); + values.push_back(-27696.2320267235000); + values.push_back(HUGE_VAL); + values.push_back(HUGE_VAL); + values.push_back(96161.7546348456000); + values.push_back(73875.6716288563000); + values.push_back(80720.4378655615000); + values.push_back(-98649.8109937874000); + values.push_back(99372.9362079615000); + values.push_back(HUGE_VAL); + values.push_back(-57020.4389966513000); + + + double min, max, range, mean, stdev; + RigStatisticsMath::calculateBasicStatistics(values, &min, &max, &range, &mean, &stdev); + + std::vector histogram; + RigHistogramCalculator histCalc(min, max, 100, &histogram); + histCalc.addData(values); + std::vector pVals; + double p10, p50, p90; + p10 = histCalc.calculatePercentil(0.1); + p50 = histCalc.calculatePercentil(0.5); + p90 = histCalc.calculatePercentil(0.9); + + EXPECT_DOUBLE_EQ( -76273.240559989776, p10); + EXPECT_DOUBLE_EQ( 5312.1312871307755 , p50); + EXPECT_DOUBLE_EQ( 94818.413022321271 , p90); +} diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/main.cpp b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/main.cpp index fcfac10e30..00d12ebca0 100644 --- a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/main.cpp +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/main.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cvfBase.h" diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp new file mode 100644 index 0000000000..486470c849 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp @@ -0,0 +1,188 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RigActiveCellInfo.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellInfo::RigActiveCellInfo() + : m_globalActiveCellCount(0), + m_activeCellPositionMin(cvf::Vec3d::ZERO), + m_activeCellPositionMax(cvf::Vec3d::ZERO) +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::setGlobalCellCount(size_t globalCellCount) +{ + m_cellIndexToResultIndex.resize(globalCellCount, cvf::UNDEFINED_SIZE_T); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigActiveCellInfo::isActive(size_t globalCellIndex) const +{ + if (m_cellIndexToResultIndex.size() == 0) + { + return true; + } + + CVF_TIGHT_ASSERT(globalCellIndex < m_cellIndexToResultIndex.size()); + + return m_cellIndexToResultIndex[globalCellIndex] != cvf::UNDEFINED_SIZE_T; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigActiveCellInfo::cellResultIndex(size_t globalCellIndex) const +{ + if (m_cellIndexToResultIndex.size() == 0) + { + return globalCellIndex; + } + + CVF_TIGHT_ASSERT(globalCellIndex < m_cellIndexToResultIndex.size()); + + return m_cellIndexToResultIndex[globalCellIndex]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::setCellResultIndex(size_t globalCellIndex, size_t globalActiveCellIndex) +{ + CVF_TIGHT_ASSERT(globalActiveCellIndex < m_cellIndexToResultIndex.size()); + + m_cellIndexToResultIndex[globalCellIndex] = globalActiveCellIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::setGridCount(size_t gridCount) +{ + m_perGridActiveCellInfo.resize(gridCount); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::setGridActiveCellCounts(size_t gridIndex, size_t activeCellCount) +{ + CVF_ASSERT(gridIndex < m_perGridActiveCellInfo.size()); + + m_perGridActiveCellInfo[gridIndex].setActiveCellCount(activeCellCount); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::computeDerivedData() +{ + m_globalActiveCellCount = 0; + + for (size_t i = 0; i < m_perGridActiveCellInfo.size(); i++) + { + m_globalActiveCellCount += m_perGridActiveCellInfo[i].activeCellCount(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigActiveCellInfo::globalActiveCellCount() const +{ + return m_globalActiveCellCount; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::setIJKBoundingBox(const cvf::Vec3st& min, const cvf::Vec3st& max) +{ + m_activeCellPositionMin = min; + m_activeCellPositionMax = max; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::IJKBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const +{ + min = m_activeCellPositionMin; + max = m_activeCellPositionMax; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::gridActiveCellCounts(size_t gridIndex, size_t& activeCellCount) +{ + activeCellCount = m_perGridActiveCellInfo[gridIndex].activeCellCount(); +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::BoundingBox RigActiveCellInfo::geometryBoundingBox() const +{ + return m_activeCellsBoundingBox; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::setGeometryBoundingBox(cvf::BoundingBox bb) +{ + m_activeCellsBoundingBox = bb; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::clear() +{ + m_perGridActiveCellInfo.clear(); + m_cellIndexToResultIndex.clear(); + m_globalActiveCellCount = 0; + m_activeCellPositionMin = cvf::Vec3st(0,0,0); + m_activeCellPositionMax = cvf::Vec3st(0,0,0); + m_activeCellsBoundingBox.reset(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigActiveCellInfo::GridActiveCellCounts::activeCellCount() const +{ + return m_activeCellCount; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::GridActiveCellCounts::setActiveCellCount(size_t activeCellCount) +{ + m_activeCellCount = activeCellCount; +} diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h new file mode 100644 index 0000000000..7086b87d4f --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfVector3.h" +#include "cvfBoundingBox.h" + +#include + + + +class RigActiveCellInfo : public cvf::Object +{ +public: + RigActiveCellInfo(); + + void setGlobalCellCount(size_t globalCellCount); + + bool isActive(size_t globalCellIndex) const; + size_t cellResultIndex(size_t globalCellIndex) const; + void setCellResultIndex(size_t globalCellIndex, size_t globalActiveCellIndex); + + void setGridCount(size_t gridCount); + void setGridActiveCellCounts(size_t gridIndex, size_t activeCellCount); + void gridActiveCellCounts(size_t gridIndex, size_t& activeCellCount); + void computeDerivedData(); + + size_t globalActiveCellCount() const; + + void setIJKBoundingBox(const cvf::Vec3st& min, const cvf::Vec3st& max); + void IJKBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const; + + cvf::BoundingBox geometryBoundingBox() const; + void setGeometryBoundingBox(cvf::BoundingBox bb); + + void clear(); + +private: + class GridActiveCellCounts + { + public: + size_t activeCellCount() const; + void setActiveCellCount(size_t activeCellCount); + + private: + size_t m_activeCellCount; + }; + + +private: + std::vector m_perGridActiveCellInfo; + + std::vector m_cellIndexToResultIndex; + + size_t m_globalActiveCellCount; + + cvf::Vec3st m_activeCellPositionMin; + cvf::Vec3st m_activeCellPositionMax; + + cvf::BoundingBox m_activeCellsBoundingBox; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirCellResults.cpp b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp similarity index 57% rename from ApplicationCode/ReservoirDataModel/RigReservoirCellResults.cpp rename to ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp index 1e0bfcea9f..465abd03f7 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirCellResults.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp @@ -16,28 +16,38 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" - -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "RifReaderInterface.h" #include "RigMainGrid.h" +#include "RigStatisticsMath.h" + #include +#include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigReservoirCellResults::RigReservoirCellResults(RigMainGrid* ownerGrid) +RigCaseCellResultsData::RigCaseCellResultsData(RigMainGrid* ownerGrid) { CVF_ASSERT(ownerGrid != NULL); m_ownerMainGrid = ownerGrid; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseCellResultsData::setMainGrid(RigMainGrid* ownerGrid) +{ + m_ownerMainGrid = ownerGrid; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::minMaxCellScalarValues( size_t scalarResultIndex, double& min, double& max ) +void RigCaseCellResultsData::minMaxCellScalarValues( size_t scalarResultIndex, double& min, double& max ) { min = HUGE_VAL; max = -HUGE_VAL; @@ -75,7 +85,7 @@ void RigReservoirCellResults::minMaxCellScalarValues( size_t scalarResultIndex, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max) +void RigCaseCellResultsData::minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max) { min = HUGE_VAL; max = -HUGE_VAL; @@ -129,7 +139,7 @@ void RigReservoirCellResults::minMaxCellScalarValues(size_t scalarResultIndex, s //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::vector& RigReservoirCellResults::cellScalarValuesHistogram(size_t scalarResultIndex) +const std::vector& RigCaseCellResultsData::cellScalarValuesHistogram(size_t scalarResultIndex) { CVF_ASSERT(scalarResultIndex < resultCount()); @@ -170,9 +180,11 @@ const std::vector& RigReservoirCellResults::cellScalarValuesHistogram(si //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90) +void RigCaseCellResultsData::p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90) { - const std::vector& histogr = cellScalarValuesHistogram( scalarResultIndex); + // 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; } @@ -180,7 +192,7 @@ void RigReservoirCellResults::p10p90CellScalarValues(size_t scalarResultIndex, d //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::meanCellScalarValues(size_t scalarResultIndex, double& meanValue) +void RigCaseCellResultsData::meanCellScalarValues(size_t scalarResultIndex, double& meanValue) { CVF_ASSERT(scalarResultIndex < resultCount()); @@ -216,7 +228,7 @@ void RigReservoirCellResults::meanCellScalarValues(size_t scalarResultIndex, dou //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::resultCount() const +size_t RigCaseCellResultsData::resultCount() const { return m_cellScalarResults.size(); } @@ -224,7 +236,7 @@ size_t RigReservoirCellResults::resultCount() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::timeStepCount(size_t scalarResultIndex) const +size_t RigCaseCellResultsData::timeStepCount(size_t scalarResultIndex) const { CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); @@ -234,7 +246,17 @@ size_t RigReservoirCellResults::timeStepCount(size_t scalarResultIndex) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector< std::vector > & RigReservoirCellResults::cellScalarResults( size_t scalarResultIndex ) +const std::vector< std::vector > & RigCaseCellResultsData::cellScalarResults( size_t scalarResultIndex ) const +{ + CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); + + return m_cellScalarResults[scalarResultIndex]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector< std::vector > & RigCaseCellResultsData::cellScalarResults( size_t scalarResultIndex ) { CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); @@ -244,7 +266,18 @@ std::vector< std::vector > & RigReservoirCellResults::cellScalarResults( //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RigReservoirCellResults::cellScalarResult(size_t timeStepIndex, size_t scalarResultIndex, size_t resultValueIndex) +std::vector& RigCaseCellResultsData::cellScalarResults(size_t scalarResultIndex, size_t timeStepIndex) +{ + CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); + CVF_TIGHT_ASSERT(timeStepIndex < m_cellScalarResults[scalarResultIndex].size()); + + return m_cellScalarResults[scalarResultIndex][timeStepIndex]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCaseCellResultsData::cellScalarResult( size_t scalarResultIndex, size_t timeStepIndex, size_t resultValueIndex) { if (scalarResultIndex < resultCount() && timeStepIndex < m_cellScalarResults[scalarResultIndex].size() && @@ -259,78 +292,11 @@ double RigReservoirCellResults::cellScalarResult(size_t timeStepIndex, size_t sc } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName) -{ - size_t resultGridIndex = cvf::UNDEFINED_SIZE_T; - - resultGridIndex = findScalarResultIndex(type, resultName); - - if (resultGridIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T; - - if (cellScalarResults(resultGridIndex).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_resultInfos[resultGridIndex].m_timeStepDates.size(); - - bool resultLoadingSucess = true; - - if (type == RimDefines::DYNAMIC_NATIVE && timeStepCount > 0) - { - m_cellScalarResults[resultGridIndex].resize(timeStepCount); - - size_t i; - for (i = 0; i < timeStepCount; i++) - { - std::vector& values = m_cellScalarResults[resultGridIndex][i]; - if (!m_readerInterface->dynamicResult(resultName, RifReaderInterface::MATRIX_RESULTS, i, &values)) - { - resultLoadingSucess = false; - } - } - } - else if (type == RimDefines::STATIC_NATIVE) - { - m_cellScalarResults[resultGridIndex].resize(1); - - std::vector& values = m_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_cellScalarResults[resultGridIndex].clear(); - } - } - - return resultGridIndex; -} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::setReaderInterface(RifReaderInterface* readerInterface) -{ - m_readerInterface = readerInterface; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::findScalarResultIndex(RimDefines::ResultCatType type, const QString& resultName) const +size_t RigCaseCellResultsData::findScalarResultIndex(RimDefines::ResultCatType type, const QString& resultName) const { std::vector::const_iterator it; for (it = m_resultInfos.begin(); it != m_resultInfos.end(); it++) @@ -347,7 +313,7 @@ size_t RigReservoirCellResults::findScalarResultIndex(RimDefines::ResultCatType //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::findScalarResultIndex(const QString& resultName) const +size_t RigCaseCellResultsData::findScalarResultIndex(const QString& resultName) const { size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; @@ -371,227 +337,11 @@ size_t RigReservoirCellResults::findScalarResultIndex(const QString& resultName) return scalarResultIndex; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::loadOrComputeSOIL() -{ - size_t soilResultGridIndex = findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); - - if (soilResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - size_t scalarIndexSWAT = findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); - size_t scalarIndexSGAS = findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); - - // Early exit if none of SWAT or SGAS is present - if (scalarIndexSWAT == cvf::UNDEFINED_SIZE_T && scalarIndexSGAS == cvf::UNDEFINED_SIZE_T) - { - return; - } - - soilResultGridIndex = addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); - - const std::vector< std::vector >* swat = NULL; - const std::vector< std::vector >* sgas = NULL; - if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T) - { - swat = &(cellScalarResults(scalarIndexSWAT)); - } - - if (scalarIndexSGAS != cvf::UNDEFINED_SIZE_T) - { - sgas = &(cellScalarResults(scalarIndexSGAS)); - } - - size_t soilResultValueCount = 0; - size_t soilTimeStepCount = 0; - if (swat) - { - soilResultValueCount = swat->at(0).size(); - soilTimeStepCount = m_resultInfos[scalarIndexSWAT].m_timeStepDates.size(); - } - - if (sgas) - { - soilResultValueCount = qMax(soilResultValueCount, sgas->at(0).size()); - - size_t sgasTimeStepCount = m_resultInfos[scalarIndexSGAS].m_timeStepDates.size(); - soilTimeStepCount = qMax(soilTimeStepCount, sgasTimeStepCount); - } - - m_cellScalarResults[soilResultGridIndex].resize(soilTimeStepCount); - - std::vector< std::vector >& soil = cellScalarResults(soilResultGridIndex); - - int timeStepIdx = 0; - for (timeStepIdx = 0; timeStepIdx < static_cast(soilTimeStepCount); timeStepIdx++) - { - soil[timeStepIdx].resize(soilResultValueCount); - -#pragma omp parallel for - for (int idx = 0; idx < static_cast(soilResultValueCount); idx++) - { - double soilValue = 1.0; - if (sgas) - { - soilValue -= sgas->at(timeStepIdx)[idx]; - } - - if (swat) - { - soilValue -= swat->at(timeStepIdx)[idx]; - } - - soil[timeStepIdx][idx] = soilValue; - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::computeDepthRelatedResults() -{ - 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 = addStaticScalarResult(RimDefines::STATIC_NATIVE, "DEPTH", resultValueCount); - computeDepth = true; - } - - if (dxResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - dxResultGridIndex = addStaticScalarResult(RimDefines::STATIC_NATIVE, "DX", resultValueCount); - computeDx = true; - } - - if (dyResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - dyResultGridIndex = addStaticScalarResult(RimDefines::STATIC_NATIVE, "DY", resultValueCount); - computeDy = true; - } - - if (dzResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - dzResultGridIndex = addStaticScalarResult(RimDefines::STATIC_NATIVE, "DZ", resultValueCount); - computeDz = true; - } - - if (topsResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - topsResultGridIndex = addStaticScalarResult(RimDefines::STATIC_NATIVE, "TOPS", resultValueCount); - computeTops = true; - } - - if (bottomResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - bottomResultGridIndex = addStaticScalarResult(RimDefines::STATIC_NATIVE, "BOTTOM", resultValueCount); - computeBottom = true; - } - - std::vector< std::vector >& depth = cellScalarResults(depthResultGridIndex); - std::vector< std::vector >& dx = cellScalarResults(dxResultGridIndex); - std::vector< std::vector >& dy = cellScalarResults(dyResultGridIndex); - std::vector< std::vector >& dz = cellScalarResults(dzResultGridIndex); - std::vector< std::vector >& tops = cellScalarResults(topsResultGridIndex); - std::vector< std::vector >& bottom = cellScalarResults(bottomResultGridIndex); - - bool computeValuesForActiveCellsOnly = m_ownerMainGrid->globalMatrixModelActiveCellCount() > 0; - - size_t cellIdx = 0; - for (cellIdx = 0; cellIdx < m_ownerMainGrid->cells().size(); cellIdx++) - { - const RigCell& cell = m_ownerMainGrid->cells()[cellIdx]; - - if (computeValuesForActiveCellsOnly && !cell.isActiveInMatrixModel()) - { - continue; - } - - 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 RigReservoirCellResults::findOrLoadScalarResult(const QString& resultName) -{ - 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 = this->findScalarResultIndex(RimDefines::GENERATED, resultName); - } - - if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) - { - scalarResultIndex = this->findScalarResultIndex(RimDefines::INPUT_PROPERTY, resultName); - } - - return scalarResultIndex; -} - //-------------------------------------------------------------------------------------------------- /// Adds an empty scalar set, and returns the scalarResultIndex to it. /// if resultName already exists, it returns the scalarResultIndex to the existing result. //-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::addEmptyScalarResult(RimDefines::ResultCatType type, const QString& resultName) +size_t RigCaseCellResultsData::addEmptyScalarResult(RimDefines::ResultCatType type, const QString& resultName, bool needsToBeStored) { size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; @@ -600,7 +350,7 @@ size_t RigReservoirCellResults::addEmptyScalarResult(RimDefines::ResultCatType t { scalarResultIndex = this->resultCount(); m_cellScalarResults.push_back(std::vector >()); - ResultInfo resInfo(type, resultName, scalarResultIndex); + ResultInfo resInfo(type, needsToBeStored, false, resultName, scalarResultIndex); m_resultInfos.push_back(resInfo); } @@ -610,7 +360,7 @@ size_t RigReservoirCellResults::addEmptyScalarResult(RimDefines::ResultCatType t //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QStringList RigReservoirCellResults::resultNames(RimDefines::ResultCatType resType) const +QStringList RigCaseCellResultsData::resultNames(RimDefines::ResultCatType resType) const { QStringList varList; std::vector::const_iterator it; @@ -627,7 +377,7 @@ QStringList RigReservoirCellResults::resultNames(RimDefines::ResultCatType resTy //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::recalculateMinMax(size_t scalarResultIndex) +void RigCaseCellResultsData::recalculateMinMax(size_t scalarResultIndex) { // Make sure cached max min values are recalculated next time asked for, since // the data could be changed. @@ -646,26 +396,22 @@ void RigReservoirCellResults::recalculateMinMax(size_t scalarResultIndex) //-------------------------------------------------------------------------------------------------- /// Returns whether the result data in question is addressed by Active Cell Index //-------------------------------------------------------------------------------------------------- -bool RigReservoirCellResults::isUsingGlobalActiveIndex(size_t scalarResultIndex) const +bool RigCaseCellResultsData::isUsingGlobalActiveIndex(size_t scalarResultIndex) const { CVF_TIGHT_ASSERT(scalarResultIndex < m_cellScalarResults.size()); if (!m_cellScalarResults[scalarResultIndex].size()) return true; size_t firstTimeStepResultValueCount = m_cellScalarResults[scalarResultIndex][0].size(); - if (firstTimeStepResultValueCount == m_ownerMainGrid->globalMatrixModelActiveCellCount()) return true; - if (firstTimeStepResultValueCount == m_ownerMainGrid->globalFractureModelActiveCellCount()) return true; if (firstTimeStepResultValueCount == m_ownerMainGrid->cells().size()) return false; - CVF_TIGHT_ASSERT(false); // Wrong number of results - - return false; + return true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QDateTime RigReservoirCellResults::timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const +QDateTime RigCaseCellResultsData::timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const { if (scalarResultIndex < m_resultInfos.size() && (size_t)(m_resultInfos[scalarResultIndex].m_timeStepDates.size()) > timeStepIndex) return m_resultInfos[scalarResultIndex].m_timeStepDates[static_cast(timeStepIndex)]; @@ -676,41 +422,56 @@ QDateTime RigReservoirCellResults::timeStepDate(size_t scalarResultIndex, size_t //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QList RigReservoirCellResults::timeStepDates(size_t scalarResultIndex) const +std::vector RigCaseCellResultsData::timeStepDates(size_t scalarResultIndex) const { if (scalarResultIndex < m_resultInfos.size() ) return m_resultInfos[scalarResultIndex].m_timeStepDates; else - return QList(); + return std::vector(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::setTimeStepDates(size_t scalarResultIndex, const QList& dates) +void RigCaseCellResultsData::setTimeStepDates(size_t scalarResultIndex, const std::vector& dates) { CVF_ASSERT(scalarResultIndex < m_resultInfos.size() ); m_resultInfos[scalarResultIndex].m_timeStepDates = dates; + + std::vector< std::vector >& dataValues = this->cellScalarResults(scalarResultIndex); + dataValues.resize(dates.size()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::maxTimeStepCount() const +size_t RigCaseCellResultsData::maxTimeStepCount(size_t* scalarResultIndexWithMostTimeSteps) const { size_t maxTsCount = 0; - for (size_t i = 0; i < m_cellScalarResults.size(); ++i) + size_t scalarResultIndexWithMaxTsCount = cvf::UNDEFINED_SIZE_T; + + for (size_t i = 0; i < m_resultInfos.size(); i++) { - maxTsCount = m_cellScalarResults[i].size() > maxTsCount ? m_cellScalarResults[i].size() : maxTsCount; + if (m_resultInfos[i].m_timeStepDates.size() > maxTsCount) + { + maxTsCount = m_resultInfos[i].m_timeStepDates.size(); + scalarResultIndexWithMaxTsCount = i; + } } + + if (scalarResultIndexWithMostTimeSteps) + { + *scalarResultIndexWithMostTimeSteps = scalarResultIndexWithMaxTsCount; + } + return maxTsCount; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RigReservoirCellResults::makeResultNameUnique(const QString& resultNameProposal) const +QString RigCaseCellResultsData::makeResultNameUnique(const QString& resultNameProposal) const { QString newResultName = resultNameProposal; size_t resultIndex = cvf::UNDEFINED_SIZE_T; @@ -732,7 +493,7 @@ QString RigReservoirCellResults::makeResultNameUnique(const QString& resultNameP //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::removeResult(const QString& resultName) +void RigCaseCellResultsData::removeResult(const QString& resultName) { size_t resultIdx = findScalarResultIndex(resultName); if (resultIdx == cvf::UNDEFINED_SIZE_T) return; @@ -745,20 +506,23 @@ void RigReservoirCellResults::removeResult(const QString& resultName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::clearAllResults() +void RigCaseCellResultsData::clearAllResults() { - for (size_t i = 0; i < m_cellScalarResults.size(); i++) - { - m_cellScalarResults[i].clear(); - } + m_cellScalarResults.clear(); + m_maxMinValues.clear(); + m_histograms.clear(); + m_p10p90.clear(); + m_meanValues.clear(); + m_maxMinValuesPrTs.clear(); + m_resultInfos.clear(); } //-------------------------------------------------------------------------------------------------- /// Add a result with given type and name, and allocate one result vector for the static result values //-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::addStaticScalarResult(RimDefines::ResultCatType type, const QString& resultName, size_t resultValueCount) +size_t RigCaseCellResultsData::addStaticScalarResult(RimDefines::ResultCatType type, const QString& resultName, bool needsToBeStored, size_t resultValueCount) { - size_t resultIdx = addEmptyScalarResult(type, resultName); + size_t resultIdx = addEmptyScalarResult(type, resultName, needsToBeStored); m_cellScalarResults[resultIdx].push_back(std::vector()); m_cellScalarResults[resultIdx][0].resize(resultValueCount, HUGE_VAL); @@ -769,10 +533,42 @@ size_t RigReservoirCellResults::addStaticScalarResult(RimDefines::ResultCatType //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifReaderInterface::PorosityModelResultType RigReservoirCellResults::convertFromProjectModelPorosityModel(RimDefines::PorosityModelType porosityModel) +RifReaderInterface::PorosityModelResultType RigCaseCellResultsData::convertFromProjectModelPorosityModel(RimDefines::PorosityModelType porosityModel) { if (porosityModel == RimDefines::MATRIX_MODEL) return RifReaderInterface::MATRIX_RESULTS; return RifReaderInterface::FRACTURE_RESULTS; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigCaseCellResultsData::mustBeCalculated(size_t scalarResultIndex) const +{ + std::vector::const_iterator it; + for (it = m_resultInfos.begin(); it != m_resultInfos.end(); it++) + { + if (it->m_gridScalarResultIndex == scalarResultIndex) + { + return it->m_mustBeCalculated; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseCellResultsData::setMustBeCalculated(size_t scalarResultIndex) +{ + std::vector::iterator it; + for (it = m_resultInfos.begin(); it != m_resultInfos.end(); it++) + { + if (it->m_gridScalarResultIndex == scalarResultIndex) + { + it->m_mustBeCalculated = true; + } + } +} + diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h new file mode 100644 index 0000000000..e87009b436 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h @@ -0,0 +1,123 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimDefines.h" +#include +#include +#include +#include "RifReaderInterface.h" + +class RifReaderInterface; +class RigMainGrid; + +//================================================================================================== +/// Class containing the results for the complete number of active cells. Both main grid and LGR's +//================================================================================================== +class RigCaseCellResultsData : public cvf::Object +{ +public: + RigCaseCellResultsData(RigMainGrid* ownerGrid); + + void setMainGrid(RigMainGrid* ownerGrid); + + // Max and min values of the results + void recalculateMinMax(size_t scalarResultIndex); + void minMaxCellScalarValues(size_t scalarResultIndex, double& min, double& max); + void minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max); + const std::vector& cellScalarValuesHistogram(size_t scalarResultIndex); + void p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90); + void meanCellScalarValues(size_t scalarResultIndex, double& meanValue); + + // Access meta-information about the results + size_t resultCount() const; + size_t timeStepCount(size_t scalarResultIndex) const; + size_t maxTimeStepCount(size_t* scalarResultIndex = NULL) const; + QStringList resultNames(RimDefines::ResultCatType type) const; + bool isUsingGlobalActiveIndex(size_t scalarResultIndex) const; + + QDateTime timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const; + std::vector timeStepDates(size_t scalarResultIndex) const; + void setTimeStepDates(size_t scalarResultIndex, const std::vector& dates); + + // Find or create a slot for the results + + size_t findScalarResultIndex(RimDefines::ResultCatType type, const QString& resultName) const; + size_t findScalarResultIndex(const QString& resultName) const; + + size_t addEmptyScalarResult(RimDefines::ResultCatType type, const QString& resultName, bool needsToBeStored); + QString makeResultNameUnique(const QString& resultNameProposal) const; + + void removeResult(const QString& resultName); + void clearAllResults(); + + // Access the results data + + const std::vector< std::vector > & cellScalarResults(size_t scalarResultIndex) const; + std::vector< std::vector > & cellScalarResults(size_t scalarResultIndex); + std::vector& cellScalarResults(size_t scalarResultIndex, size_t timeStepIndex); + double cellScalarResult(size_t scalarResultIndex, size_t timeStepIndex, size_t resultValueIndex); + + static RifReaderInterface::PorosityModelResultType convertFromProjectModelPorosityModel(RimDefines::PorosityModelType porosityModel); + +public: + class ResultInfo + { + public: + ResultInfo(RimDefines::ResultCatType resultType, bool needsToBeStored, bool mustBeCalculated, QString resultName, size_t gridScalarResultIndex) + : m_resultType(resultType), m_needsToBeStored(needsToBeStored), m_resultName(resultName), m_gridScalarResultIndex(gridScalarResultIndex), m_mustBeCalculated(mustBeCalculated) { } + + public: + RimDefines::ResultCatType m_resultType; + bool m_needsToBeStored; + bool m_mustBeCalculated; + QString m_resultName; + size_t m_gridScalarResultIndex; + std::vector m_timeStepDates; + }; + + const std::vector& infoForEachResultIndex() { return m_resultInfos;} + + bool mustBeCalculated(size_t scalarResultIndex) const; + void setMustBeCalculated(size_t scalarResultIndex); + + +public: + size_t addStaticScalarResult(RimDefines::ResultCatType type, + const QString& resultName, + bool needsToBeStored, + size_t resultValueCount); + +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::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 + + + +private: + std::vector m_resultInfos; + + RigMainGrid* m_ownerMainGrid; + +}; diff --git a/ApplicationCode/ReservoirDataModel/RigCaseData.cpp b/ApplicationCode/ReservoirDataModel/RigCaseData.cpp new file mode 100644 index 0000000000..ad45aca665 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseData.cpp @@ -0,0 +1,486 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RigCaseData.h" +#include "RigMainGrid.h" +#include "RigCaseCellResultsData.h" +#include "RigGridScalarDataAccess.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseData::RigCaseData() +{ + m_mainGrid = new RigMainGrid(); + + m_matrixModelResults = new RigCaseCellResultsData(m_mainGrid.p()); + m_fractureModelResults = new RigCaseCellResultsData(m_mainGrid.p()); + + m_activeCellInfo = new RigActiveCellInfo; + m_fractureActiveCellInfo = new RigActiveCellInfo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseData::~RigCaseData() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::setMainGrid(RigMainGrid* mainGrid) +{ + m_mainGrid = mainGrid; + + m_matrixModelResults->setMainGrid(m_mainGrid.p()); + m_fractureModelResults->setMainGrid(m_mainGrid.p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::allGrids(std::vector* grids) +{ + CVF_ASSERT(grids); + + if (m_mainGrid.isNull()) + { + return; + } + + size_t i; + for (i = 0; i < m_mainGrid->gridCount(); i++) + { + grids->push_back(m_mainGrid->gridByIndex(i)); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::allGrids(std::vector* grids) const +{ + CVF_ASSERT(grids); + + if (m_mainGrid.isNull()) + { + return; + } + + size_t i; + for (i = 0; i < m_mainGrid->gridCount(); i++) + { + grids->push_back(m_mainGrid->gridByIndex(i)); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Get grid by index. The main grid has index 0, so the first lgr has index 1 +//-------------------------------------------------------------------------------------------------- +const RigGridBase* RigCaseData::grid(size_t index) const +{ + CVF_ASSERT(m_mainGrid.notNull()); + return m_mainGrid->gridByIndex(index); +} + + +//-------------------------------------------------------------------------------------------------- +/// Get grid by index. The main grid has index 0, so the first lgr has index 1 +//-------------------------------------------------------------------------------------------------- +RigGridBase* RigCaseData::grid(size_t index) +{ + CVF_ASSERT(m_mainGrid.notNull()); + return m_mainGrid->gridByIndex(index); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigCaseData::gridCount() const +{ + CVF_ASSERT(m_mainGrid.notNull()); + return m_mainGrid->gridCount(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::computeWellCellsPrGrid() +{ + // If we have computed this already, return + if (m_wellCellsInGrid.size()) return; + + std::vector grids; + this->allGrids(&grids); + size_t gIdx; + + // Allocate and initialize the arrays + + m_wellCellsInGrid.resize(grids.size()); + + for (gIdx = 0; gIdx < grids.size(); ++gIdx) + { + if (m_wellCellsInGrid[gIdx].isNull() || m_wellCellsInGrid[gIdx]->size() != grids[gIdx]->cellCount()) + { + m_wellCellsInGrid[gIdx] = new cvf::UByteArray; + m_wellCellsInGrid[gIdx]->resize(grids[gIdx]->cellCount()); + + } + m_wellCellsInGrid[gIdx]->setAll(false); + } + + // Fill arrays with data + size_t wIdx; + for (wIdx = 0; wIdx < m_wellResults.size(); ++wIdx) + { + size_t tIdx; + for (tIdx = 0; tIdx < m_wellResults[wIdx]->m_wellCellsTimeSteps.size(); ++tIdx) + { + RigWellResultFrame& wellCells = m_wellResults[wIdx]->m_wellCellsTimeSteps[tIdx]; + + size_t gridIndex = wellCells.m_wellHead.m_gridIndex; + size_t gridCellIndex = wellCells.m_wellHead.m_gridCellIndex; + + CVF_ASSERT(gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size()); + m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true); + + size_t sIdx; + for (sIdx = 0; sIdx < wellCells.m_wellResultBranches.size(); ++sIdx) + { + RigWellResultBranch& wellSegment = wellCells.m_wellResultBranches[sIdx]; + size_t cdIdx; + for (cdIdx = 0; cdIdx < wellSegment.m_wellCells.size(); ++cdIdx) + { + gridIndex = wellSegment.m_wellCells[cdIdx].m_gridIndex; + gridCellIndex = wellSegment.m_wellCells[cdIdx].m_gridCellIndex; + + CVF_ASSERT(gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size()); + + m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true); + } + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::setWellResults(const cvf::Collection& data) +{ + m_wellResults = data; + m_wellCellsInGrid.clear(); + computeWellCellsPrGrid(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::UByteArray* RigCaseData::wellCellsInGrid(size_t gridIndex) +{ + computeWellCellsPrGrid(); + CVF_ASSERT(gridIndex < m_wellCellsInGrid.size()); + + return m_wellCellsInGrid[gridIndex].p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCell& RigCaseData::cellFromWellResultCell(const RigWellResultCell& wellResultCell) +{ + size_t gridIndex = wellResultCell.m_gridIndex; + size_t gridCellIndex = wellResultCell.m_gridCellIndex; + + std::vector grids; + allGrids(&grids); + + return grids[gridIndex]->cell(gridCellIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigCaseData::findSharedSourceFace(cvf::StructGridInterface::FaceType& sharedSourceFace,const RigWellResultCell& sourceWellCellResult, const RigWellResultCell& otherWellCellResult) const +{ + size_t gridIndex = sourceWellCellResult.m_gridIndex; + size_t gridCellIndex = sourceWellCellResult.m_gridCellIndex; + + size_t otherGridIndex = otherWellCellResult.m_gridIndex; + size_t otherGridCellIndex = otherWellCellResult.m_gridCellIndex; + + if (gridIndex != otherGridIndex) return false; + + std::vector grids; + allGrids(&grids); + + const RigGridBase* grid = grids[gridIndex]; + size_t i, j, k; + grid->ijkFromCellIndex(gridCellIndex, &i, &j, &k); + + size_t faceIdx; + for (faceIdx = 0; faceIdx < 6; faceIdx++) + { + cvf::StructGridInterface::FaceType sourceFace = static_cast(faceIdx); + + size_t ni, nj, nk; + grid->neighborIJKAtCellFace(i, j, k, sourceFace, &ni, &nj, &nk); + size_t neighborCellIndex = grid->cellIndexFromIJK(ni, nj, nk); + + if (neighborCellIndex == otherGridCellIndex) + { + sharedSourceFace = sourceFace; + return true; + } + } + + return false; +} + + + +//-------------------------------------------------------------------------------------------------- +/// Helper class used to find min/max range for valid and active cells +//-------------------------------------------------------------------------------------------------- +class CellRangeBB +{ +public: + CellRangeBB() + : m_min(cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T), + m_max(cvf::Vec3st::ZERO) + { + + } + + void add(size_t i, size_t j, size_t k) + { + if (i < m_min.x()) m_min.x() = i; + if (j < m_min.y()) m_min.y() = j; + if (k < m_min.z()) m_min.z() = k; + + if (i > m_max.x()) m_max.x() = i; + if (j > m_max.y()) m_max.y() = j; + if (k > m_max.z()) m_max.z() = k; + } + +public: + cvf::Vec3st m_min; + cvf::Vec3st m_max; +}; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::computeActiveCellIJKBBox() +{ + if (m_mainGrid.notNull() && m_activeCellInfo.notNull() && m_fractureActiveCellInfo.notNull()) + { + CellRangeBB matrixModelActiveBB; + CellRangeBB fractureModelActiveBB; + + size_t idx; + for (idx = 0; idx < m_mainGrid->cellCount(); idx++) + { + size_t i, j, k; + m_mainGrid->ijkFromCellIndex(idx, &i, &j, &k); + + if (m_activeCellInfo->isActive(idx)) + { + matrixModelActiveBB.add(i, j, k); + } + + if (m_fractureActiveCellInfo->isActive(idx)) + { + fractureModelActiveBB.add(i, j, k); + } + } + m_activeCellInfo->setIJKBoundingBox(matrixModelActiveBB.m_min, matrixModelActiveBB.m_max); + m_fractureActiveCellInfo->setIJKBoundingBox(fractureModelActiveBB.m_min, fractureModelActiveBB.m_max); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::computeActiveCellBoundingBoxes() +{ + computeActiveCellIJKBBox(); + computeActiveCellsGeometryBoundingBox(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellInfo* RigCaseData::activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel) +{ + if (porosityModel == RifReaderInterface::MATRIX_RESULTS) + { + return m_activeCellInfo.p(); + } + + return m_fractureActiveCellInfo.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigActiveCellInfo* RigCaseData::activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel) const +{ + if (porosityModel == RifReaderInterface::MATRIX_RESULTS) + { + return m_activeCellInfo.p(); + } + + return m_fractureActiveCellInfo.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::setActiveCellInfo(RifReaderInterface::PorosityModelResultType porosityModel, RigActiveCellInfo* activeCellInfo) +{ + if (porosityModel == RifReaderInterface::MATRIX_RESULTS) + { + m_activeCellInfo = activeCellInfo; + } + else + { + m_fractureActiveCellInfo = activeCellInfo; + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::computeActiveCellsGeometryBoundingBox() +{ + if (m_activeCellInfo.isNull() || m_fractureActiveCellInfo.isNull()) + { + return; + } + + if (m_mainGrid.isNull()) + { + cvf::BoundingBox bb; + m_activeCellInfo->setGeometryBoundingBox(bb); + m_fractureActiveCellInfo->setGeometryBoundingBox(bb); + return; + } + + RigActiveCellInfo* activeInfos[2]; + activeInfos[0] = m_fractureActiveCellInfo.p(); + activeInfos[1] = m_activeCellInfo.p(); // Last, to make this bb.min become display offset + + cvf::BoundingBox bb; + for (int acIdx = 0; acIdx < 2; ++acIdx) + { + bb.reset(); + if (m_mainGrid->nodes().size() == 0) + { + bb.add(cvf::Vec3d::ZERO); + } + else + { + for (size_t i = 0; i < m_mainGrid->cellCount(); i++) + { + if (activeInfos[acIdx]->isActive(i)) + { + const RigCell& c = m_mainGrid->cells()[i]; + const caf::SizeTArray8& indices = c.cornerIndices(); + + size_t idx; + for (idx = 0; idx < 8; idx++) + { + bb.add(m_mainGrid->nodes()[indices[idx]]); + } + } + } + } + + activeInfos[acIdx]->setGeometryBoundingBox(bb); + } + + m_mainGrid->setDisplayModelOffset(bb.min()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseCellResultsData* RigCaseData::results(RifReaderInterface::PorosityModelResultType porosityModel) +{ + if (porosityModel == RifReaderInterface::MATRIX_RESULTS) + { + return m_matrixModelResults.p(); + } + + return m_fractureModelResults.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigCaseCellResultsData* RigCaseData::results(RifReaderInterface::PorosityModelResultType porosityModel) const +{ + if (porosityModel == RifReaderInterface::MATRIX_RESULTS) + { + return m_matrixModelResults.p(); + } + + 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; + +} + + +/* +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::closeReaderInterface() +{ + RifReaderInterface* readerInterface = m_matrixModelResults->readerInterface(); + + if (readerInterface) + { + readerInterface->close(); + } +} +*/ diff --git a/ApplicationCode/ReservoirDataModel/RigCaseData.h b/ApplicationCode/ReservoirDataModel/RigCaseData.h new file mode 100644 index 0000000000..ce4f72dac0 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseData.h @@ -0,0 +1,88 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include "RigCell.h" +#include "cvfVector3.h" +#include "cvfAssert.h" +#include "cvfObject.h" +#include "RigMainGrid.h" +#include "RigSingleWellResultsData.h" +#include "RigActiveCellInfo.h" + +class RigCaseCellResultsData; + + +class RigCaseData: public cvf::Object +{ +public: + RigCaseData(); + ~RigCaseData(); + + RigMainGrid* mainGrid() { return m_mainGrid.p(); } + const RigMainGrid* mainGrid() const { return m_mainGrid.p(); } + void setMainGrid(RigMainGrid* mainGrid); + + void allGrids(std::vector* grids); // To be removed + void allGrids(std::vector* grids) const;// To be removed + const RigGridBase* grid(size_t index) const; + RigGridBase* grid(size_t index); + size_t gridCount() const; + + RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel); + const RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel) const; + + RigActiveCellInfo* activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel); + 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; } + + cvf::UByteArray* wellCellsInGrid(size_t gridIndex); + + RigCell& cellFromWellResultCell(const RigWellResultCell& wellResultCell); + bool findSharedSourceFace(cvf::StructGridInterface::FaceType& sharedSourceFace, const RigWellResultCell& sourceWellCellResult, const RigWellResultCell& otherWellCellResult) const; + + void computeActiveCellBoundingBoxes(); + +private: + void computeActiveCellIJKBBox(); + void computeWellCellsPrGrid(); + void computeActiveCellsGeometryBoundingBox(); + +private: + cvf::ref m_mainGrid; + + cvf::ref m_activeCellInfo; + cvf::ref m_fractureActiveCellInfo; + + cvf::ref m_matrixModelResults; + cvf::ref m_fractureModelResults; + + 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 +}; diff --git a/ApplicationCode/ReservoirDataModel/RigCell.cpp b/ApplicationCode/ReservoirDataModel/RigCell.cpp index 6c7bfd573c..7e0a83724d 100644 --- a/ApplicationCode/ReservoirDataModel/RigCell.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCell.cpp @@ -16,11 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" #include "RigCell.h" #include "RigMainGrid.h" #include "cvfPlane.h" +#include "cvfRay.h" + +#include static size_t undefinedCornersArray[8] = {cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T, @@ -39,9 +41,6 @@ RigCell::RigCell() : m_subGrid(NULL), m_hostGrid(NULL), m_isInvalid(false), - m_isWellCell(false), - m_activeIndexInMatrixModel(cvf::UNDEFINED_SIZE_T), - m_activeIndexInFractureModel(cvf::UNDEFINED_SIZE_T), m_cellIndex(cvf::UNDEFINED_SIZE_T), m_isInCoarseCell(false) { diff --git a/ApplicationCode/ReservoirDataModel/RigCell.h b/ApplicationCode/ReservoirDataModel/RigCell.h index 8e60ac1850..7e920a3bdf 100644 --- a/ApplicationCode/ReservoirDataModel/RigCell.h +++ b/ApplicationCode/ReservoirDataModel/RigCell.h @@ -37,24 +37,12 @@ public: caf::SizeTArray8& cornerIndices() { return m_cornerIndices;} const caf::SizeTArray8& cornerIndices() const { return m_cornerIndices;} - bool isActiveInMatrixModel() const { return m_activeIndexInMatrixModel != cvf::UNDEFINED_SIZE_T; } - size_t activeIndexInMatrixModel() const { return m_activeIndexInMatrixModel; } - void setActiveIndexInMatrixModel(size_t val) { m_activeIndexInMatrixModel = val; } - - bool isActiveInFractureModel() const { return m_activeIndexInFractureModel != cvf::UNDEFINED_SIZE_T; } - size_t activeIndexInFractureModel() const { return m_activeIndexInFractureModel; } - void setActiveIndexInFractureModel(size_t val) { m_activeIndexInFractureModel = val; } - bool isInvalid() const { return m_isInvalid; } void setInvalid( bool val ) { m_isInvalid = val; } - bool isWellCell() const { return m_isWellCell; } - void setAsWellCell(bool isWellCell) { m_isWellCell = isWellCell; } - size_t cellIndex() const { return m_cellIndex; } void setCellIndex(size_t val) { m_cellIndex = val; } - RigLocalGrid* subGrid() const { return m_subGrid; } void setSubGrid(RigLocalGrid* subGrid) { m_subGrid = subGrid; } @@ -89,11 +77,5 @@ private: bool m_cellFaceFaults[6]; - // Result case specific data bool m_isInvalid; - bool m_isWellCell; - - size_t m_activeIndexInMatrixModel; ///< This cell's running index of all the active calls (matrix) in the reservoir - size_t m_activeIndexInFractureModel; ///< This cell's running index of all the active calls (fracture) in the reservoir - }; diff --git a/ApplicationCode/ReservoirDataModel/RigGridBase.cpp b/ApplicationCode/ReservoirDataModel/RigGridBase.cpp index e806998c92..77946bd15e 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridBase.cpp +++ b/ApplicationCode/ReservoirDataModel/RigGridBase.cpp @@ -16,11 +16,10 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" #include "RigGridBase.h" #include "RigMainGrid.h" #include "RigCell.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "RigGridScalarDataAccess.h" #include "cvfAssert.h" @@ -29,9 +28,7 @@ RigGridBase::RigGridBase(RigMainGrid* mainGrid): m_gridPointDimensions(0,0,0), m_mainGrid(mainGrid), - m_indexToStartOfCells(0), - m_matrixModelActiveCellCount(cvf::UNDEFINED_SIZE_T), - m_fractureModelActiveCellCount(cvf::UNDEFINED_SIZE_T) + m_indexToStartOfCells(0) { if (mainGrid == NULL) { @@ -303,22 +300,6 @@ bool RigGridBase::isCellValid(size_t i, size_t j, size_t k) const return !c.isInvalid(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RigGridBase::isCellActive(size_t i, size_t j, size_t k) const -{ - size_t idx = cellIndexFromIJK(i, j, k); - const RigCell& c = cell(idx); - if (!c.isActiveInMatrixModel() || c.isInvalid()) - { - return false; - } - else - { - return true; - } -} //-------------------------------------------------------------------------------------------------- /// TODO: Use structgrid::neighborIJKAtCellFace @@ -452,18 +433,18 @@ cvf::Vec3d RigGridBase::displayModelOffset() const } //-------------------------------------------------------------------------------------------------- -/// Returns the max size of the charactristic cell sizes +/// Returns the min size of the I and J charactristic cell sizes //-------------------------------------------------------------------------------------------------- -double RigGridBase::characteristicCellSize() +double RigGridBase::characteristicIJCellSize() { - double characteristicCellSize = 0; + double characteristicCellSize = HUGE_VAL; double cellSizeI, cellSizeJ, cellSizeK; this->characteristicCellSizes(&cellSizeI, &cellSizeJ, &cellSizeK); - if (cellSizeI > characteristicCellSize) characteristicCellSize = cellSizeI; - if (cellSizeJ > characteristicCellSize) characteristicCellSize = cellSizeJ; - if (cellSizeK > characteristicCellSize) characteristicCellSize = cellSizeK; + if (cellSizeI < characteristicCellSize) characteristicCellSize = cellSizeI; + if (cellSizeJ < characteristicCellSize) characteristicCellSize = cellSizeJ; + return characteristicCellSize; } @@ -471,51 +452,11 @@ double RigGridBase::characteristicCellSize() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigGridBase::matrixModelActiveCellCount() const +size_t RigGridBase::globalGridCellIndex(size_t localGridCellIndex) const { - return m_matrixModelActiveCellCount; + return m_indexToStartOfCells + localGridCellIndex; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RigGridBase::fractureModelActiveCellCount() const -{ - return m_fractureModelActiveCellCount; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref RigGridBase::dataAccessObject(RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStepIndex, size_t scalarSetIndex) const -{ - if (timeStepIndex != cvf::UNDEFINED_SIZE_T && - scalarSetIndex != cvf::UNDEFINED_SIZE_T) - { - cvf::ref dataAccess = RigGridScalarDataAccess::createDataAccessObject(this, porosityModel, timeStepIndex, scalarSetIndex); - return dataAccess; - } - - return NULL; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigGridBase::setFractureModelActiveCellCount(size_t activeFractureModelCellCount) -{ - m_fractureModelActiveCellCount = activeFractureModelCellCount; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigGridBase::setMatrixModelActiveCellCount(size_t activeMatrixModelCellCount) -{ - m_matrixModelActiveCellCount = activeMatrixModelCellCount; -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigGridBase.h b/ApplicationCode/ReservoirDataModel/RigGridBase.h index c9233e82d6..364de6ae10 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridBase.h +++ b/ApplicationCode/ReservoirDataModel/RigGridBase.h @@ -34,6 +34,7 @@ class RigMainGrid; class RigCell; class RigGridScalarDataAccess; +class RigActiveCellInfo; class RigGridBase : public cvf::StructGridInterface { @@ -48,11 +49,13 @@ public: RigCell& cell(size_t gridCellIndex); const RigCell& cell(size_t gridCellIndex) const; + size_t globalGridCellIndex(size_t localGridCellIndex) const; void setIndexToStartOfCells(size_t indexToStartOfCells) { m_indexToStartOfCells = indexToStartOfCells; } + void setGridIndex(size_t index) { m_gridIndex = index; } - size_t gridIndex() { return m_gridIndex; } + size_t gridIndex() const { return m_gridIndex; } - double characteristicCellSize(); + double characteristicIJCellSize(); std::string gridName() const; void setGridName(const std::string& gridName); @@ -60,12 +63,7 @@ public: void computeFaults(); bool isMainGrid() const; RigMainGrid* mainGrid() const { return m_mainGrid; } - - size_t matrixModelActiveCellCount() const; - void setMatrixModelActiveCellCount(size_t activeMatrixModelCellCount); - size_t fractureModelActiveCellCount() const ; - void setFractureModelActiveCellCount(size_t activeFractureModelCellCount); - + protected: friend class RigMainGrid;//::initAllSubGridsParentGridPointer(); void initSubGridParentPointer(); @@ -93,12 +91,9 @@ public: virtual size_t gridPointIndexFromIJK( size_t i, size_t j, size_t k ) const; virtual cvf::Vec3d gridPointCoordinate( size_t i, size_t j, size_t k ) const; - virtual bool isCellActive( size_t i, size_t j, size_t k ) const; virtual bool isCellValid( size_t i, size_t j, size_t k ) const; virtual bool cellIJKNeighbor(size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex ) const; - cvf::ref dataAccessObject(RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStepIndex, size_t scalarSetIndex) const; - private: std::string m_gridName; cvf::Vec3st m_gridPointDimensions; @@ -106,9 +101,6 @@ private: size_t m_gridIndex; ///< The LGR index of this grid. Starts with 1. Main grid has index 0. RigMainGrid* m_mainGrid; - size_t m_matrixModelActiveCellCount; - size_t m_fractureModelActiveCellCount; - }; diff --git a/ApplicationCode/ReservoirDataModel/RigGridManager.cpp b/ApplicationCode/ReservoirDataModel/RigGridManager.cpp new file mode 100644 index 0000000000..e1b6eb459d --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigGridManager.cpp @@ -0,0 +1,129 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RigGridManager.h" +#include "RigCaseData.h" +#include "RigMainGrid.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGridManager::addCase(RigCaseData* eclipseCase) +{ + cvf::ref caseAndGrid = new CaseToGridMap(eclipseCase, eclipseCase->mainGrid()); + m_caseToGrid.push_back(caseAndGrid.p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGridManager::removeCase(RigCaseData* eclipseCase) +{ + size_t indexToErase = cvf::UNDEFINED_SIZE_T; + + for (size_t i = 0; i < m_caseToGrid.size(); i++) + { + if (m_caseToGrid[i]->m_eclipseCase == eclipseCase) + { + m_caseToGrid.eraseAt(i); + return; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigMainGrid* RigGridManager::findEqualGrid(RigMainGrid* candidateGrid) +{ + for (size_t i = 0; i < m_caseToGrid.size(); i++) + { + RigMainGrid* mainGrid = m_caseToGrid.at(i)->m_mainGrid; + if (RigGridManager::isEqual(mainGrid, candidateGrid)) + { + return mainGrid; + } + } + return NULL; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigGridManager::isEqual(RigMainGrid* gridA, RigMainGrid* gridB) +{ + if (gridA == NULL || gridB == NULL) return false; + + if (gridA == gridB) return true; + + if (gridA->gridCount() != gridB->gridCount()) return false; + + if (gridA->nodes().size() != gridB->nodes().size()) return false; + + for (size_t i = 0; i < gridA->nodes().size(); i++) + { + if (!gridA->nodes()[i].equals(gridB->nodes()[i])) + { + return false; + } + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGridManager::clear() +{ + m_caseToGrid.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigGridManager::isGridDimensionsEqual(const std::vector< std::vector >& mainCaseGridDimensions, const std::vector< std::vector >& caseGridDimensions) +{ + if (mainCaseGridDimensions.size() != caseGridDimensions.size()) + { + return false; + } + + for (size_t j = 0; j < mainCaseGridDimensions.size(); j++) + { + if (mainCaseGridDimensions[j].size() != 3) return false; + if (caseGridDimensions[j].size() != 3) return false; + + if (mainCaseGridDimensions[j][0] != caseGridDimensions[j][0]) return false; + if (mainCaseGridDimensions[j][1] != caseGridDimensions[j][1]) return false; + if (mainCaseGridDimensions[j][2] != caseGridDimensions[j][2]) return false; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigGridManager::CaseToGridMap::CaseToGridMap(RigCaseData* eclipseCase, RigMainGrid* mainGrid) : +m_eclipseCase(eclipseCase), + m_mainGrid(mainGrid) +{ +} diff --git a/ApplicationCode/ReservoirDataModel/RigGridManager.h b/ApplicationCode/ReservoirDataModel/RigGridManager.h new file mode 100644 index 0000000000..7f5f2adc45 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigGridManager.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfCollection.h" + +#include + +class RigMainGrid; +class RigCaseData; + +class RigGridManager : public cvf::Object +{ +public: + void addCase(RigCaseData* eclipseCase); + + void removeCase(RigCaseData* eclipseCase); + + RigMainGrid* findEqualGrid(RigMainGrid* candidateGrid); + + void clear(); + + static bool isEqual(RigMainGrid* gridA, RigMainGrid* gridB); + static bool isGridDimensionsEqual(const std::vector< std::vector >& mainCaseGridDimensions, const std::vector< std::vector >& caseGridDimensions); +private: + class CaseToGridMap : public cvf::Object + { + public: + CaseToGridMap(RigCaseData* eclipseCase, RigMainGrid* mainGrid); + + RigCaseData* m_eclipseCase; + RigMainGrid* m_mainGrid; + }; + + +private: + cvf::Collection m_caseToGrid; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp b/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp index bcdef620c9..04280e6c19 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp +++ b/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp @@ -1,58 +1,156 @@ -//################################################################################################## +///////////////////////////////////////////////////////////////////////////////// // -// Custom Visualization Core library -// Copyright (C) 2011-2012 Ceetron AS -// -// This library 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. -// -// This library 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. +// 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 "RigGridScalarDataAccess.h" #include "cvfLibCore.h" #include "cvfBase.h" +#include "cvfObject.h" #include "cvfAssert.h" #include "RigMainGrid.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" +#include "RigActiveCellInfo.h" +#include "RigGridBase.h" +#include "RigCaseData.h" +#include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigGridScalarDataAccess::RigGridScalarDataAccess(const RigGridBase* grid, bool useGlobalActiveIndex, std::vector* resultValues) : - m_grid(grid), - m_useGlobalActiveIndex(useGlobalActiveIndex), - m_resultValues(resultValues) +class RigGridAllCellsScalarDataAccess : public cvf::StructGridScalarDataAccess { +public: + RigGridAllCellsScalarDataAccess(const RigGridBase* grid, std::vector* reservoirResultValues); + + virtual double cellScalar(size_t gridLocalCellIndex) const; + virtual void setCellScalar(size_t cellIndex, double value); + +private: + const RigGridBase* m_grid; + std::vector* m_reservoirResultValues; +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigGridAllCellsScalarDataAccess::RigGridAllCellsScalarDataAccess(const RigGridBase* grid, std::vector* reservoirResultValues) + : m_grid(grid), + m_reservoirResultValues(reservoirResultValues) +{ + CVF_ASSERT(reservoirResultValues != NULL); + CVF_ASSERT(grid != NULL); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RigGridScalarDataAccess::createDataAccessObject(const RigGridBase* grid, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStepIndex, size_t scalarSetIndex) +double RigGridAllCellsScalarDataAccess::cellScalar(size_t gridLocalCellIndex) const { - CVF_ASSERT(grid); - CVF_ASSERT(grid->mainGrid()); - CVF_ASSERT(grid->mainGrid()->results(porosityModel)); + if (m_reservoirResultValues->size() == 0 ) return HUGE_VAL; - if (!grid || !grid->mainGrid() || !grid->mainGrid()->results(porosityModel)) + size_t globalGridCellIndex = m_grid->globalGridCellIndex(gridLocalCellIndex); + CVF_TIGHT_ASSERT(globalGridCellIndex < m_reservoirResultValues->size()); + + return m_reservoirResultValues->at(globalGridCellIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGridAllCellsScalarDataAccess::setCellScalar(size_t gridLocalCellIndex, double scalarValue) +{ + size_t globalGridCellIndex = m_grid->globalGridCellIndex(gridLocalCellIndex); + CVF_TIGHT_ASSERT(globalGridCellIndex < m_reservoirResultValues->size()); + + (*m_reservoirResultValues)[globalGridCellIndex] = scalarValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RigGridMatrixActiveCellsScalarDataAccess : public cvf::StructGridScalarDataAccess +{ +public: + RigGridMatrixActiveCellsScalarDataAccess(const RigGridBase* grid, std::vector* reservoirResultValues, const RigActiveCellInfo* activeCellInfo) + : m_grid(grid), + m_reservoirResultValues(reservoirResultValues), + m_activeCellInfo(activeCellInfo) + { + CVF_ASSERT(reservoirResultValues != NULL); + CVF_ASSERT(grid != NULL); + } + + virtual double cellScalar(size_t gridLocalCellIndex) const + { + if (m_reservoirResultValues->size() == 0 ) return HUGE_VAL; + + size_t globalGridCellIndex = m_grid->globalGridCellIndex(gridLocalCellIndex); + size_t resultValueIndex = m_activeCellInfo->cellResultIndex(globalGridCellIndex); + if (resultValueIndex == cvf::UNDEFINED_SIZE_T) return HUGE_VAL; + + CVF_TIGHT_ASSERT(resultValueIndex < m_reservoirResultValues->size()); + + return m_reservoirResultValues->at(resultValueIndex); + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + virtual void setCellScalar(size_t gridLocalCellIndex, double scalarValue) + { + size_t globalGridCellIndex = m_grid->globalGridCellIndex(gridLocalCellIndex); + size_t resultValueIndex = m_activeCellInfo->cellResultIndex(globalGridCellIndex); + + CVF_TIGHT_ASSERT(resultValueIndex < m_reservoirResultValues->size()); + + (*m_reservoirResultValues)[resultValueIndex] = scalarValue; + } + +private: + const RigActiveCellInfo* m_activeCellInfo; + const RigGridBase* m_grid; + std::vector* m_reservoirResultValues; +}; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RigGridScalarDataAccessFactory::createPerGridDataAccessObject(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t scalarSetIndex) +{ + 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; } - bool useGlobalActiveIndex = grid->mainGrid()->results(porosityModel)->isUsingGlobalActiveIndex(scalarSetIndex); - - std::vector< std::vector > & scalarSetResults = grid->mainGrid()->results(porosityModel)->cellScalarResults(scalarSetIndex); + std::vector< std::vector >& scalarSetResults = eclipseCase->results(porosityModel)->cellScalarResults(scalarSetIndex); if (timeStepIndex >= scalarSetResults.size()) { return NULL; @@ -60,72 +158,16 @@ cvf::ref RigGridScalarDataAccess::createDataAccessObjec std::vector* resultValues = &(scalarSetResults[timeStepIndex]); - cvf::ref object = new RigGridScalarDataAccess(grid, useGlobalActiveIndex, resultValues); - return object; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RigGridScalarDataAccess::cellScalar(size_t i, size_t j, size_t k) const -{ - size_t cellIndex = m_grid->cellIndexFromIJK(i, j, k); - - return cellScalar(cellIndex); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RigGridScalarDataAccess::cellScalar(size_t cellIndex) const -{ - if (m_resultValues->size() == 0 ) return HUGE_VAL; - - size_t resultValueIndex = cellIndex; - - if (m_useGlobalActiveIndex) + bool useGlobalActiveIndex = eclipseCase->results(porosityModel)->isUsingGlobalActiveIndex(scalarSetIndex); + if (useGlobalActiveIndex) { - resultValueIndex = m_grid->cell(cellIndex).activeIndexInMatrixModel(); - if (resultValueIndex == cvf::UNDEFINED_SIZE_T) return HUGE_VAL; + cvf::ref object = new RigGridMatrixActiveCellsScalarDataAccess(grid, resultValues, eclipseCase->activeCellInfo(porosityModel)); + return object; + } + else + { + cvf::ref object = new RigGridAllCellsScalarDataAccess(grid, resultValues); + return object; } - - if (m_resultValues->size() <= resultValueIndex) return HUGE_VAL; - - return m_resultValues->at(resultValueIndex); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RigGridScalarDataAccess::gridPointScalar(size_t i, size_t j, size_t k) const -{ - CVF_ASSERT(false); - return 0.0; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigGridScalarDataAccess::cellCornerScalars(size_t i, size_t j, size_t k, double scalars[8]) const -{ - CVF_ASSERT(false); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RigGridScalarDataAccess::pointScalar(const cvf::Vec3d& p, double* scalarValue) const -{ - CVF_ASSERT(false); - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const cvf::Vec3d* RigGridScalarDataAccess::cellVector(size_t i, size_t j, size_t k) const -{ - CVF_ASSERT(false); - return new cvf::Vec3d(); } diff --git a/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.h b/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.h index ad4f1fb46d..d098829f66 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.h +++ b/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.h @@ -1,51 +1,39 @@ -//################################################################################################## +///////////////////////////////////////////////////////////////////////////////// // -// Custom Visualization Core library -// Copyright (C) 2011-2012 Ceetron AS -// -// This library 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. -// -// This library 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. +// 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. // -//################################################################################################## +///////////////////////////////////////////////////////////////////////////////// #pragma once #include "cvfStructGridScalarDataAccess.h" -#include "RigGridBase.h" #include "RifReaderInterface.h" -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -class RigGridScalarDataAccess : public cvf::StructGridScalarDataAccess +class RigActiveCellInfo; +class RigGridBase; + +class RigGridScalarDataAccessFactory { -private: - RigGridScalarDataAccess(const RigGridBase* grid, bool useGlobalActiveIndex, std::vector* resultValues); - public: - static cvf::ref createDataAccessObject(const RigGridBase* grid, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStepIndex, size_t scalarSetIndex); - - virtual double cellScalar(size_t i, size_t j, size_t k) const; - virtual double cellScalar(size_t cellIndex) const; - virtual void cellCornerScalars(size_t i, size_t j, size_t k, double scalars[8]) const; - virtual double gridPointScalar(size_t i, size_t j, size_t k) const; - virtual bool pointScalar(const cvf::Vec3d& p, double* scalarValue) const; - - virtual const cvf::Vec3d* cellVector(size_t i, size_t j, size_t k) const; - -private: - cvf::cref m_grid; - bool m_useGlobalActiveIndex; - std::vector* m_resultValues; + static cvf::ref + createPerGridDataAccessObject(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t scalarSetIndex); }; + diff --git a/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp b/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp index c67e81bb66..9b4ebbe248 100644 --- a/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp +++ b/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp @@ -16,7 +16,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" #include "RigLocalGrid.h" diff --git a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp index d73b78f7e5..a5194dc79b 100644 --- a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp +++ b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp @@ -16,28 +16,17 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" - #include "RigMainGrid.h" -#include "RigReservoirCellResults.h" #include "cvfAssert.h" RigMainGrid::RigMainGrid(void) - : RigGridBase(this), - m_activeCellPositionMin(cvf::Vec3st::UNDEFINED), - m_activeCellPositionMax(cvf::Vec3st::UNDEFINED), - m_validCellPositionMin(cvf::Vec3st::UNDEFINED), - m_validCellPositionMax(cvf::Vec3st::UNDEFINED), - m_globalMatrixModelActiveCellCount(cvf::UNDEFINED_SIZE_T), - m_globalFractureModelActiveCellCount(cvf::UNDEFINED_SIZE_T) + : RigGridBase(this) { - m_matrixModelResults = new RigReservoirCellResults(this); - m_fractureModelResults = new RigReservoirCellResults(this); - - m_activeCellsBoundingBox.add(cvf::Vec3d::ZERO); + m_displayModelOffset = cvf::Vec3d::ZERO; + m_gridIndex = 0; -} +} RigMainGrid::~RigMainGrid(void) @@ -80,156 +69,22 @@ void RigMainGrid::initAllSubCellsMainGridCellIndex() } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RigMainGrid::globalMatrixModelActiveCellCount() const -{ - return m_globalMatrixModelActiveCellCount; - -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RigMainGrid::globalFractureModelActiveCellCount() const -{ - return m_globalFractureModelActiveCellCount; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigMainGrid::matrixModelActiveCellsBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const -{ - min = m_activeCellPositionMin; - max = m_activeCellPositionMax; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::BoundingBox RigMainGrid::matrixModelActiveCellsBoundingBox() const -{ - return m_activeCellsBoundingBox; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigMainGrid::validCellsBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const -{ - min = m_validCellPositionMin; - max = m_validCellPositionMax; -} - - - -//-------------------------------------------------------------------------------------------------- -/// Helper class used to find min/max range for valid and active cells -//-------------------------------------------------------------------------------------------------- -class CellRangeBB -{ -public: - CellRangeBB() - : m_min(cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T), - m_max(cvf::Vec3st::ZERO) - { - - } - - void add(size_t i, size_t j, size_t k) - { - if (i < m_min.x()) m_min.x() = i; - if (j < m_min.y()) m_min.y() = j; - if (k < m_min.z()) m_min.z() = k; - - if (i > m_max.x()) m_max.x() = i; - if (j > m_max.y()) m_max.y() = j; - if (k > m_max.z()) m_max.z() = k; - } - -public: - cvf::Vec3st m_min; - cvf::Vec3st m_max; -}; - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigMainGrid::computeActiveAndValidCellRanges() -{ - CellRangeBB validBB; - CellRangeBB activeBB; - - size_t idx; - for (idx = 0; idx < cellCount(); idx++) - { - const RigCell& c = cell(idx); - - size_t i, j, k; - ijkFromCellIndex(idx, &i, &j, &k); - - if (!c.isInvalid()) - { - validBB.add(i, j, k); - } - - if (c.isActiveInMatrixModel()) - { - activeBB.add(i, j, k); - } - } - - m_validCellPositionMin = validBB.m_min; - m_validCellPositionMax = validBB.m_max; - - m_activeCellPositionMin = activeBB.m_min; - m_activeCellPositionMax = activeBB.m_max; -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::Vec3d RigMainGrid::displayModelOffset() const { - return m_activeCellsBoundingBox.min(); + return m_displayModelOffset; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigMainGrid::computeBoundingBox() +void RigMainGrid::setDisplayModelOffset(cvf::Vec3d offset) { - m_activeCellsBoundingBox.reset(); - - if (m_nodes.size() == 0) - { - m_activeCellsBoundingBox.add(cvf::Vec3d::ZERO); - } - else - { - size_t i; - for (i = 0; i < cellCount(); i++) - { - const RigCell& c = cell(i); - if (c.isActiveInMatrixModel()) - { - const caf::SizeTArray8& indices = c.cornerIndices(); - - size_t idx; - for (idx = 0; idx < 8; idx++) - { - m_activeCellsBoundingBox.add(m_nodes[indices[idx]]); - } - } - } - } + m_displayModelOffset = offset; } - //-------------------------------------------------------------------------------------------------- /// Initialize pointers from grid to parent grid /// Compute cell ranges for active and valid cells @@ -239,83 +94,6 @@ void RigMainGrid::computeCachedData() { initAllSubGridsParentGridPointer(); initAllSubCellsMainGridCellIndex(); - computeActiveAndValidCellRanges(); - computeBoundingBox(); -} - -//-------------------------------------------------------------------------------------------------- -/// -/// -/// -//-------------------------------------------------------------------------------------------------- -void RigMainGrid::calculateMatrixModelActiveCellInfo(std::vector &gridNumber, - std::vector &cellI, - std::vector &cellJ, - std::vector &cellK, - std::vector &parentGridNumber, - std::vector &hostCellI, - std::vector &hostCellJ, - std::vector &hostCellK) -{ - size_t numMatrixModelActiveCells = this->globalMatrixModelActiveCellCount(); - - gridNumber.clear(); - cellI.clear(); - cellJ.clear(); - cellK.clear(); - parentGridNumber.clear(); - hostCellI.clear(); - hostCellJ.clear(); - hostCellK.clear(); - - gridNumber.reserve(numMatrixModelActiveCells); - cellI.reserve(numMatrixModelActiveCells); - cellJ.reserve(numMatrixModelActiveCells); - cellK.reserve(numMatrixModelActiveCells); - parentGridNumber.reserve(numMatrixModelActiveCells); - hostCellI.reserve(numMatrixModelActiveCells); - hostCellJ.reserve(numMatrixModelActiveCells); - hostCellK.reserve(numMatrixModelActiveCells); - - for (size_t cIdx = 0; cIdx < m_cells.size(); ++cIdx) - { - if (m_cells[cIdx].isActiveInMatrixModel()) - { - RigGridBase* grid = m_cells[cIdx].hostGrid(); - CVF_ASSERT(grid != NULL); - size_t cellIndex = m_cells[cIdx].cellIndex(); - - size_t i, j, k; - grid->ijkFromCellIndex(cellIndex, &i, &j, &k); - - size_t pi, pj, pk; - RigGridBase* parentGrid = NULL; - - if (grid->isMainGrid()) - { - pi = i; - pj = j; - pk = k; - parentGrid = grid; - } - else - { - size_t parentCellIdx = m_cells[cIdx].parentCellIndex(); - parentGrid = (static_cast(grid))->parentGrid(); - CVF_ASSERT(parentGrid != NULL); - parentGrid->ijkFromCellIndex(parentCellIdx, &pi, &pj, &pk); - } - - gridNumber.push_back(static_cast(grid->gridIndex())); - cellI.push_back(static_cast(i)); - cellJ.push_back(static_cast(j)); - cellK.push_back(static_cast(k)); - parentGridNumber.push_back(static_cast(parentGrid->gridIndex())); - hostCellI.push_back(static_cast(pi)); - hostCellJ.push_back(static_cast(pj)); - hostCellK.push_back(static_cast(pk)); - } - } } //-------------------------------------------------------------------------------------------------- @@ -338,29 +116,3 @@ const RigGridBase* RigMainGrid::gridByIndex(size_t localGridIndex) const return m_localGrids[localGridIndex-1].p(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigReservoirCellResults* RigMainGrid::results(RifReaderInterface::PorosityModelResultType porosityModel) -{ - if (porosityModel == RifReaderInterface::MATRIX_RESULTS) - { - return m_matrixModelResults.p(); - } - - return m_fractureModelResults.p(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const RigReservoirCellResults* RigMainGrid::results(RifReaderInterface::PorosityModelResultType porosityModel) const -{ - if (porosityModel == RifReaderInterface::MATRIX_RESULTS) - { - return m_matrixModelResults.p(); - } - - return m_fractureModelResults.p(); -} - diff --git a/ApplicationCode/ReservoirDataModel/RigMainGrid.h b/ApplicationCode/ReservoirDataModel/RigMainGrid.h index aa9d19919f..32ef9258bf 100644 --- a/ApplicationCode/ReservoirDataModel/RigMainGrid.h +++ b/ApplicationCode/ReservoirDataModel/RigMainGrid.h @@ -27,8 +27,6 @@ #include -class RigReservoirCellResults; - class RigMainGrid : public RigGridBase { public: @@ -42,59 +40,29 @@ public: std::vector& cells() {return m_cells;} const std::vector& cells() const {return m_cells;} - RigReservoirCellResults* results(RifReaderInterface::PorosityModelResultType porosityModel); - const RigReservoirCellResults* results(RifReaderInterface::PorosityModelResultType porosityModel) const; - - size_t globalMatrixModelActiveCellCount() const; - size_t globalFractureModelActiveCellCount() const; - void setGlobalMatrixModelActiveCellCount (size_t globalMatrixModelActiveCellCount) { m_globalMatrixModelActiveCellCount = globalMatrixModelActiveCellCount; } - void setGlobalFractureModelActiveCellCount(size_t globalFractureModelActiveCellCount) { m_globalFractureModelActiveCellCount = globalFractureModelActiveCellCount;} - - void matrixModelActiveCellsBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const; - void validCellsBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const; - void addLocalGrid(RigLocalGrid* localGrid); size_t gridCount() const { return m_localGrids.size() + 1; } RigGridBase* gridByIndex(size_t localGridIndex); const RigGridBase* gridByIndex(size_t localGridIndex) const; - void calculateMatrixModelActiveCellInfo(std::vector& gridNumber, - std::vector& i, - std::vector& j, - std::vector& k, - std::vector& parentGridNumber, - std::vector& hostCellI, - std::vector& hostCellJ, - std::vector& hostCellK); void computeCachedData(); cvf::BoundingBox matrixModelActiveCellsBoundingBox() const; // Overrides virtual cvf::Vec3d displayModelOffset() const; + void setDisplayModelOffset(cvf::Vec3d offset); private: void initAllSubGridsParentGridPointer(); void initAllSubCellsMainGridCellIndex(); void computeActiveAndValidCellRanges(); - void computeBoundingBox(); private: std::vector m_nodes; ///< Global vertex table std::vector m_cells; ///< Global array of all cells in the reservoir (including the ones in LGR's) cvf::Collection m_localGrids; ///< List of all the LGR's in this reservoir - cvf::ref m_matrixModelResults; - cvf::ref m_fractureModelResults; - - size_t m_globalMatrixModelActiveCellCount; - size_t m_globalFractureModelActiveCellCount; - - cvf::Vec3st m_activeCellPositionMin; - cvf::Vec3st m_activeCellPositionMax; - cvf::Vec3st m_validCellPositionMin; - cvf::Vec3st m_validCellPositionMax; - - cvf::BoundingBox m_activeCellsBoundingBox; + cvf::Vec3d m_displayModelOffset; }; diff --git a/ApplicationCode/ReservoirDataModel/RigReservoir.cpp b/ApplicationCode/ReservoirDataModel/RigReservoir.cpp deleted file mode 100644 index cfaa91f668..0000000000 --- a/ApplicationCode/ReservoirDataModel/RigReservoir.cpp +++ /dev/null @@ -1,224 +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 "RIStdInclude.h" -#include "RigReservoir.h" -#include "RigMainGrid.h" - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigReservoir::RigReservoir() -{ - m_mainGrid = new RigMainGrid(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigReservoir::~RigReservoir() -{ - -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoir::computeFaults() -{ - std::vector grids; - allGrids(&grids); - - size_t i; - for (i = 0; i < grids.size(); i++) - { - grids[i]->computeFaults(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoir::allGrids(std::vector* grids) -{ - CVF_ASSERT(grids); - - size_t i; - for (i = 0; i < m_mainGrid->gridCount(); i++) - { - grids->push_back(m_mainGrid->gridByIndex(i)); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoir::allGrids(std::vector* grids) const -{ - CVF_ASSERT(grids); - size_t i; - for (i = 0; i < m_mainGrid->gridCount(); i++) - { - grids->push_back(m_mainGrid->gridByIndex(i)); - } -} - -//-------------------------------------------------------------------------------------------------- -/// Get grid by index. The main grid has index 0, so the first lgr has index 1 -//-------------------------------------------------------------------------------------------------- -const RigGridBase* RigReservoir::grid(size_t index) const -{ - return m_mainGrid->gridByIndex(index); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoir::computeWellCellsPrGrid() -{ - // If we have computed this already, return - if (m_wellCellsInGrid.size()) return; - - std::vector grids; - this->allGrids(&grids); - size_t gIdx; - - // Allocate and initialize the arrays - - m_wellCellsInGrid.resize(grids.size()); - - for (gIdx = 0; gIdx < grids.size(); ++gIdx) - { - if (m_wellCellsInGrid[gIdx].isNull() || m_wellCellsInGrid[gIdx]->size() != grids[gIdx]->cellCount()) - { - m_wellCellsInGrid[gIdx] = new cvf::UByteArray; - m_wellCellsInGrid[gIdx]->resize(grids[gIdx]->cellCount()); - - } - m_wellCellsInGrid[gIdx]->setAll(false); - } - - // Fill arrays with data - size_t wIdx; - for (wIdx = 0; wIdx < m_wellResults.size(); ++wIdx) - { - size_t tIdx; - for (tIdx = 0; tIdx < m_wellResults[wIdx]->m_wellCellsTimeSteps.size(); ++tIdx) - { - RigWellResultFrame& wellCells = m_wellResults[wIdx]->m_wellCellsTimeSteps[tIdx]; - - size_t gridIndex = wellCells.m_wellHead.m_gridIndex; - size_t gridCellIndex = wellCells.m_wellHead.m_gridCellIndex; - - CVF_ASSERT(gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size()); - grids[gridIndex]->cell(gridCellIndex).setAsWellCell(true); - m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true); - - size_t sIdx; - for (sIdx = 0; sIdx < wellCells.m_wellResultBranches.size(); ++sIdx) - { - RigWellResultBranch& wellSegment = wellCells.m_wellResultBranches[sIdx]; - size_t cdIdx; - for (cdIdx = 0; cdIdx < wellSegment.m_wellCells.size(); ++cdIdx) - { - gridIndex = wellSegment.m_wellCells[cdIdx].m_gridIndex; - gridCellIndex = wellSegment.m_wellCells[cdIdx].m_gridCellIndex; - - CVF_ASSERT(gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size()); - - grids[gridIndex]->cell(gridCellIndex).setAsWellCell(true); - m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true); - } - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoir::setWellResults(const cvf::Collection& data) -{ - m_wellResults = data; - m_wellCellsInGrid.clear(); - computeWellCellsPrGrid(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::UByteArray* RigReservoir::wellCellsInGrid(size_t gridIndex) -{ - computeWellCellsPrGrid(); - CVF_ASSERT(gridIndex < m_wellCellsInGrid.size()); - - return m_wellCellsInGrid[gridIndex].p(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigCell& RigReservoir::cellFromWellResultCell(const RigWellResultCell& wellResultCell) -{ - size_t gridIndex = wellResultCell.m_gridIndex; - size_t gridCellIndex = wellResultCell.m_gridCellIndex; - - std::vector grids; - allGrids(&grids); - - return grids[gridIndex]->cell(gridCellIndex); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RigReservoir::findSharedSourceFace(cvf::StructGridInterface::FaceType& sharedSourceFace,const RigWellResultCell& sourceWellCellResult, const RigWellResultCell& otherWellCellResult) const -{ - size_t gridIndex = sourceWellCellResult.m_gridIndex; - size_t gridCellIndex = sourceWellCellResult.m_gridCellIndex; - - size_t otherGridIndex = otherWellCellResult.m_gridIndex; - size_t otherGridCellIndex = otherWellCellResult.m_gridCellIndex; - - if (gridIndex != otherGridIndex) return false; - - std::vector grids; - allGrids(&grids); - - const RigGridBase* grid = grids[gridIndex]; - size_t i, j, k; - grid->ijkFromCellIndex(gridCellIndex, &i, &j, &k); - - size_t faceIdx; - for (faceIdx = 0; faceIdx < 6; faceIdx++) - { - cvf::StructGridInterface::FaceType sourceFace = static_cast(faceIdx); - - size_t ni, nj, nk; - grid->neighborIJKAtCellFace(i, j, k, sourceFace, &ni, &nj, &nk); - size_t neighborCellIndex = grid->cellIndexFromIJK(ni, nj, nk); - - if (neighborCellIndex == otherGridCellIndex) - { - sharedSourceFace = sourceFace; - return true; - } - } - - return false; -} diff --git a/ApplicationCode/ReservoirDataModel/RigReservoir.h b/ApplicationCode/ReservoirDataModel/RigReservoir.h deleted file mode 100644 index d7518d1245..0000000000 --- a/ApplicationCode/ReservoirDataModel/RigReservoir.h +++ /dev/null @@ -1,61 +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. -// -///////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include -#include "RigCell.h" -#include "cvfVector3.h" -#include "cvfAssert.h" -#include "cvfObject.h" -#include "RigMainGrid.h" -#include "RigWellResults.h" - - -class RigReservoir: public cvf::Object -{ -public: - RigReservoir(); - ~RigReservoir(); - - RigMainGrid* mainGrid() { return m_mainGrid.p(); } - const RigMainGrid* mainGrid() const { return m_mainGrid.p(); } - - void allGrids(std::vector* grids); - void allGrids(std::vector* grids) const; - const RigGridBase* grid(size_t index) const; - - void setWellResults(const cvf::Collection& data); - const cvf::Collection& wellResults() { return m_wellResults; } - - - cvf::UByteArray* wellCellsInGrid(size_t gridIndex); - void computeFaults(); - - RigCell& cellFromWellResultCell(const RigWellResultCell& wellResultCell); - bool findSharedSourceFace(cvf::StructGridInterface::FaceType& sharedSourceFace, const RigWellResultCell& sourceWellCellResult, const RigWellResultCell& otherWellCellResult) const; - - -private: - void computeWellCellsPrGrid(); - - cvf::ref m_mainGrid; - - cvf::Collection m_wellResults; - cvf::Collection m_wellCellsInGrid; -}; diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index 8a2679c2d4..74671abf98 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -16,10 +16,9 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" - #include "RigReservoirBuilderMock.h" -#include "RigReservoir.h" +#include "RigCaseData.h" +#include "RigActiveCellInfo.h" /* rand example: guess the number */ @@ -154,6 +153,8 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun riCell.setParentCellIndex(0); + //TODO: Rewrite active cell info in mock models + /* if (!(i % 5)) { riCell.setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); @@ -162,6 +163,7 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun { riCell.setActiveIndexInMatrixModel(activeCellIndex++); } + */ cells.push_back(riCell); } @@ -170,15 +172,15 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirBuilderMock::populateReservoir(RigReservoir* reservoir) +void RigReservoirBuilderMock::populateReservoir(RigCaseData* eclipseCase) { - std::vector& mainGridNodes = reservoir->mainGrid()->nodes(); + std::vector& mainGridNodes = eclipseCase->mainGrid()->nodes(); appendNodes(m_minWorldCoordinate, m_maxWorldCoordinate, cellDimension(), mainGridNodes); size_t mainGridNodeCount = mainGridNodes.size(); size_t mainGridCellCount = mainGridNodeCount / 8; // Must create cells in main grid here, as this information is used when creating LGRs - appendCells(0, mainGridCellCount, reservoir->mainGrid(), reservoir->mainGrid()->cells()); + appendCells(0, mainGridCellCount, eclipseCase->mainGrid(), eclipseCase->mainGrid()->cells()); size_t totalCellCount = mainGridCellCount; @@ -206,9 +208,9 @@ void RigReservoirBuilderMock::populateReservoir(RigReservoir* reservoir) } // Create local grid and set local grid dimensions - RigLocalGrid* localGrid = new RigLocalGrid(reservoir->mainGrid()); - reservoir->mainGrid()->addLocalGrid(localGrid); - localGrid->setParentGrid(reservoir->mainGrid()); + RigLocalGrid* localGrid = new RigLocalGrid(eclipseCase->mainGrid()); + eclipseCase->mainGrid()->addLocalGrid(localGrid); + localGrid->setParentGrid(eclipseCase->mainGrid()); localGrid->setIndexToStartOfCells(mainGridNodes.size() / 8); cvf::Vec3st gridPointDimensions( @@ -221,13 +223,13 @@ void RigReservoirBuilderMock::populateReservoir(RigReservoir* reservoir) size_t cellIdx; for (cellIdx = 0; cellIdx < mainGridIndicesWithSubGrid.size(); cellIdx++) { - RigCell& cell = reservoir->mainGrid()->cells()[mainGridIndicesWithSubGrid[cellIdx]]; + RigCell& cell = eclipseCase->mainGrid()->cells()[mainGridIndicesWithSubGrid[cellIdx]]; caf::SizeTArray8& indices = cell.cornerIndices(); int nodeIdx; for (nodeIdx = 0; nodeIdx < 8; nodeIdx++) { - bb.add(reservoir->mainGrid()->nodes()[indices[nodeIdx]]); + bb.add(eclipseCase->mainGrid()->nodes()[indices[nodeIdx]]); } // Deactivate cell in main grid cell.setSubGrid(localGrid); @@ -237,13 +239,21 @@ void RigReservoirBuilderMock::populateReservoir(RigReservoir* reservoir) appendNodes(bb.min(), bb.max(), lgrCellDimensions, mainGridNodes); size_t subGridCellCount = (mainGridNodes.size() / 8) - totalCellCount; - appendCells(totalCellCount*8, subGridCellCount, localGrid, reservoir->mainGrid()->cells()); + appendCells(totalCellCount*8, subGridCellCount, localGrid, eclipseCase->mainGrid()->cells()); totalCellCount += subGridCellCount; } - reservoir->mainGrid()->setGridPointDimensions(m_gridPointDimensions); + eclipseCase->mainGrid()->setGridPointDimensions(m_gridPointDimensions); - addWellData(reservoir, reservoir->mainGrid()); + addWellData(eclipseCase, eclipseCase->mainGrid()); + + // Set all cells active + RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); + activeCellInfo->setGlobalCellCount(eclipseCase->mainGrid()->cells().size()); + for (size_t i = 0; i < eclipseCase->mainGrid()->cells().size(); i++) + { + activeCellInfo->setCellResultIndex(i, i); + } } @@ -268,7 +278,7 @@ void RigReservoirBuilderMock::setWorldCoordinates(cvf::Vec3d minWorldCoordinate, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigReservoirBuilderMock::inputProperty(RigReservoir* reservoir, const QString& propertyName, std::vector* values) +bool RigReservoirBuilderMock::inputProperty(RigCaseData* eclipseCase, const QString& propertyName, std::vector* values) { size_t k; @@ -278,7 +288,7 @@ bool RigReservoirBuilderMock::inputProperty(RigReservoir* reservoir, const QStri /* generate secret number: */ int iSecret = rand() % 20 + 1; - for (k = 0; k < reservoir->mainGrid()->cells().size(); k++) + for (k = 0; k < eclipseCase->mainGrid()->cells().size(); k++) { values->push_back(k * iSecret); } @@ -289,23 +299,14 @@ bool RigReservoirBuilderMock::inputProperty(RigReservoir* reservoir, const QStri //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigReservoirBuilderMock::staticResult(RigReservoir* reservoir, const QString& result, std::vector* values) +bool RigReservoirBuilderMock::staticResult(RigCaseData* eclipseCase, const QString& result, std::vector* values) { size_t k; - for (k = 0; k < reservoir->mainGrid()->cells().size(); k++) + for (k = 0; k < eclipseCase->mainGrid()->cells().size(); k++) { - RigCell& cell = reservoir->mainGrid()->cells()[k]; - if (cell.isActiveInMatrixModel()) { - if (cell.hostGrid() == reservoir->mainGrid()) - { - values->push_back((k * 2) % reservoir->mainGrid()->cells().size()); - } - else - { - values->push_back(500); - } + values->push_back((k * 2) % eclipseCase->mainGrid()->cells().size()); } } @@ -315,7 +316,7 @@ bool RigReservoirBuilderMock::staticResult(RigReservoir* reservoir, const QStrin //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigReservoirBuilderMock::dynamicResult(RigReservoir* reservoir, const QString& result, size_t stepIndex, std::vector* values) +bool RigReservoirBuilderMock::dynamicResult(RigCaseData* eclipseCase, const QString& result, size_t stepIndex, std::vector* values) { int resultIndex = 1; @@ -330,20 +331,12 @@ bool RigReservoirBuilderMock::dynamicResult(RigReservoir* reservoir, const QStri double offsetValue = 100 * resultIndex; size_t k; - for (k = 0; k < reservoir->mainGrid()->cells().size(); k++) + for (k = 0; k < eclipseCase->mainGrid()->cells().size(); k++) { - RigCell& cell = reservoir->mainGrid()->cells()[k]; - if (cell.isActiveInMatrixModel()) + RigCell& cell = eclipseCase->mainGrid()->cells()[k]; { - if (cell.hostGrid() == reservoir->mainGrid()) - { - double val = offsetValue + scaleValue * ( (stepIndex * 1000 + k) % reservoir->mainGrid()->cells().size() ); - values->push_back(val); - } - else - { - values->push_back(500); - } + double val = offsetValue + scaleValue * ( (stepIndex * 1000 + k) % eclipseCase->mainGrid()->cells().size() ); + values->push_back(val); } } @@ -359,19 +352,19 @@ bool RigReservoirBuilderMock::dynamicResult(RigReservoir* reservoir, const QStri //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirBuilderMock::addWellData(RigReservoir* reservoir, RigGridBase* grid) +void RigReservoirBuilderMock::addWellData(RigCaseData* eclipseCase, RigGridBase* grid) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); CVF_ASSERT(grid); cvf::Vec3st dim = grid->gridPointDimensions(); - cvf::Collection wells; + cvf::Collection wells; int wellIdx; for (wellIdx = 0; wellIdx < 1; wellIdx++) { - cvf::ref wellCellsTimeHistory = new RigWellResults; + cvf::ref wellCellsTimeHistory = new RigSingleWellResultsData; wellCellsTimeHistory->m_wellName = QString("Well %1").arg(wellIdx); wellCellsTimeHistory->m_wellCellsTimeSteps.resize(m_timeStepCount); @@ -469,6 +462,6 @@ void RigReservoirBuilderMock::addWellData(RigReservoir* reservoir, RigGridBase* wells.push_back(wellCellsTimeHistory.p()); } - reservoir->setWellResults(wells); + eclipseCase->setWellResults(wells); } diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h index 2d802b03d5..d6c0f0fec4 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h @@ -23,7 +23,7 @@ #include "cvfArray.h" #include "cvfVector3.h" #include "RigCell.h" -#include "RigReservoir.h" +#include "RigCaseData.h" class LocalGridRefinement { @@ -55,14 +55,14 @@ public: void addLocalGridRefinement(const cvf::Vec3st& minCellPosition, const cvf::Vec3st& maxCellPosition, const cvf::Vec3st& singleCellRefinementFactors); - void populateReservoir(RigReservoir* reservoir); + void populateReservoir(RigCaseData* eclipseCase); - bool inputProperty(RigReservoir* reservoir, const QString& propertyName, std::vector* values ); - bool staticResult(RigReservoir* reservoir, const QString& result, std::vector* values ); - bool dynamicResult(RigReservoir* reservoir, const QString& result, size_t stepIndex, std::vector* values ); + bool inputProperty(RigCaseData* eclipseCase, const QString& propertyName, std::vector* values ); + bool staticResult(RigCaseData* eclipseCase, const QString& result, std::vector* values ); + bool dynamicResult(RigCaseData* eclipseCase, const QString& result, size_t stepIndex, std::vector* values ); private: - void addWellData(RigReservoir* reservoir, RigGridBase* grid); + void addWellData(RigCaseData* eclipseCase, RigGridBase* grid); static void appendCells(size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector& cells); static void appendNodes(const cvf::Vec3d& min, const cvf::Vec3d& max, const cvf::Vec3st& cubeDimension, std::vector& nodes); diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirCellResults.h b/ApplicationCode/ReservoirDataModel/RigReservoirCellResults.h deleted file mode 100644 index 577f681039..0000000000 --- a/ApplicationCode/ReservoirDataModel/RigReservoirCellResults.h +++ /dev/null @@ -1,191 +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. -// -///////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "RimDefines.h" -#include -#include -#include -#include "RifReaderInterface.h" - -class RifReaderInterface; -class RigMainGrid; - -//================================================================================================== -/// Class containing the results for the complete number of active cells. Both main grid and LGR's -//================================================================================================== -class RigReservoirCellResults : public cvf::Object -{ -public: - RigReservoirCellResults(RigMainGrid* ownerGrid); - - void setReaderInterface(RifReaderInterface* readerInterface); - - // Max and min values of the results - void recalculateMinMax(size_t scalarResultIndex); - void minMaxCellScalarValues(size_t scalarResultIndex, double& min, double& max); - void minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max); - const std::vector& cellScalarValuesHistogram(size_t scalarResultIndex); - void p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90); - void meanCellScalarValues(size_t scalarResultIndex, double& meanValue); - - // Access meta-information about the results - size_t resultCount() const; - size_t timeStepCount(size_t scalarResultIndex) const; - size_t maxTimeStepCount() const; - QStringList resultNames(RimDefines::ResultCatType type) const; - bool isUsingGlobalActiveIndex(size_t scalarResultIndex) const; - - QDateTime timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const; - QList timeStepDates(size_t scalarResultIndex) const; - void setTimeStepDates(size_t scalarResultIndex, const QList& dates); - - // Find or create a slot for the results - size_t findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName); - size_t findOrLoadScalarResult(const QString& resultName); ///< Simplified search. Assumes unique names across types. - size_t findScalarResultIndex(RimDefines::ResultCatType type, const QString& resultName) const; - size_t findScalarResultIndex(const QString& resultName) const; - size_t addEmptyScalarResult(RimDefines::ResultCatType type, const QString& resultName); - QString makeResultNameUnique(const QString& resultNameProposal) const; - - void removeResult(const QString& resultName); - void clearAllResults(); - - void loadOrComputeSOIL(); - void computeDepthRelatedResults(); - - // Access the results data - std::vector< std::vector > & cellScalarResults(size_t scalarResultIndex); - double cellScalarResult(size_t timeStepIndex, size_t scalarResultIndex, size_t resultValueIndex); - - static RifReaderInterface::PorosityModelResultType convertFromProjectModelPorosityModel(RimDefines::PorosityModelType porosityModel); - -private: - size_t addStaticScalarResult(RimDefines::ResultCatType type, const QString& resultName, size_t resultValueCount); - -private: - std::vector< std::vector< std::vector > > m_cellScalarResults; ///< Scalar results for each timestep for each Result index (ResultVariable) - std::vector< std::pair > m_maxMinValues; ///< Max min values for each Result index - 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 timestep and Result index - - class ResultInfo - { - public: - ResultInfo(RimDefines::ResultCatType resultType, QString resultName, size_t gridScalarResultIndex) - : m_resultType(resultType), m_resultName(resultName), m_gridScalarResultIndex(gridScalarResultIndex) { } - - public: - RimDefines::ResultCatType m_resultType; - QString m_resultName; - size_t m_gridScalarResultIndex; - QList m_timeStepDates; - }; - - std::vector m_resultInfos; - cvf::ref m_readerInterface; - RigMainGrid* m_ownerMainGrid; - -}; - -class RigHistogramCalculator -{ -public: - RigHistogramCalculator(double min, double max, size_t nBins, std::vector* histogram) - { - CVF_ASSERT(histogram); - CVF_ASSERT(nBins > 0); - - if (max == min) { nBins = 1; } // Avoid dividing on 0 range - - m_histogram = histogram; - m_min = min; - m_observationCount = 0; - - // Initialize bins - m_histogram->resize(nBins); - for (size_t i = 0; i < m_histogram->size(); ++i) (*m_histogram)[i] = 0; - - m_range = max - min; - maxIndex = nBins-1; - } - - void addData(const std::vector& data) - { - CVF_ASSERT(m_histogram); - for (size_t i = 0; i < data.size(); ++i) - { - if (data[i] == HUGE_VAL) - { - continue; - } - - size_t index = 0; - - if (maxIndex > 0) index = (size_t)(maxIndex*(data[i] - m_min)/m_range); - - if(index < m_histogram->size()) // Just clip to the max min range (-index will overflow to positive ) - { - (*m_histogram)[index]++; - m_observationCount++; - } - } - } - - /// Calculates the estimated percentile from the histogram. - /// the percentile is the domain value at which pVal of the observations are below it. - /// Will only consider observed values between min and max, as all other values are discarded from the histogram - - double calculatePercentil(double pVal) - { - CVF_ASSERT(m_histogram); - CVF_ASSERT(m_histogram->size()); - CVF_ASSERT( 0.0 <= pVal && pVal <= 1.0); - - double pValObservationCount = pVal*m_observationCount; - if (pValObservationCount == 0.0) return m_min; - - size_t accObsCount = 0; - double binWidth = m_range/m_histogram->size(); - for (size_t binIdx = 0; binIdx < m_histogram->size(); ++binIdx) - { - size_t binObsCount = (*m_histogram)[binIdx]; - - accObsCount += binObsCount; - if (accObsCount >= pValObservationCount) - { - double domainValueAtEndOfBin = m_min + (binIdx+1) * binWidth; - double unusedFractionOfLastBin = (double)(accObsCount - pValObservationCount)/binObsCount; - return domainValueAtEndOfBin - unusedFractionOfLastBin*binWidth; - } - } - CVF_ASSERT(false); - return HUGE_VAL; - } - -private: - size_t maxIndex; - double m_range; - double m_min; - size_t m_observationCount; - std::vector* m_histogram; -}; diff --git a/ApplicationCode/ReservoirDataModel/RigWellResults.cpp b/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.cpp similarity index 94% rename from ApplicationCode/ReservoirDataModel/RigWellResults.cpp rename to ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.cpp index e577d2dc6d..a36cf5752f 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellResults.cpp +++ b/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.cpp @@ -16,16 +16,15 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" - -#include "RigWellResults.h" +#include "RigSingleWellResultsData.h" #include +#include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const RigWellResultFrame& RigWellResults::wellResultFrame(size_t resultTimeStepIndex) const +const RigWellResultFrame& RigSingleWellResultsData::wellResultFrame(size_t resultTimeStepIndex) const { CVF_ASSERT(resultTimeStepIndex < m_resultTimeStepIndexToWellTimeStepIndex.size()); @@ -38,7 +37,7 @@ const RigWellResultFrame& RigWellResults::wellResultFrame(size_t resultTimeStepI //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigWellResults::computeMappingFromResultTimeIndicesToWellTimeIndices(const QList& resultTimes) +void RigSingleWellResultsData::computeMappingFromResultTimeIndicesToWellTimeIndices(const std::vector& resultTimes) { m_resultTimeStepIndexToWellTimeStepIndex.clear(); if (m_wellCellsTimeSteps.size() == 0) return; @@ -55,7 +54,7 @@ void RigWellResults::computeMappingFromResultTimeIndicesToWellTimeIndices(const } qDebug() << "Result TimeStamps"; - for (int i = 0; i < resultTimes.size(); i++) + for (size_t i = 0; i < resultTimes.size(); i++) { qDebug() << resultTimes[i].toString(); } @@ -66,7 +65,7 @@ void RigWellResults::computeMappingFromResultTimeIndicesToWellTimeIndices(const size_t wellIdx = 0; size_t activeWellIdx = cvf::UNDEFINED_SIZE_T; - while (wellIdx <= m_wellCellsTimeSteps.size() && resultIdx < resultTimes.size()) + while (wellIdx <= m_wellCellsTimeSteps.size() && resultIdx < static_cast(resultTimes.size())) { if (wellIdx < m_wellCellsTimeSteps.size() && m_wellCellsTimeSteps[wellIdx].m_timestamp <= resultTimes[resultIdx]) { @@ -84,7 +83,7 @@ void RigWellResults::computeMappingFromResultTimeIndicesToWellTimeIndices(const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigWellResults::hasWellResult(size_t resultTimeStepIndex) const +bool RigSingleWellResultsData::hasWellResult(size_t resultTimeStepIndex) const { size_t wellTimeStepIndex = m_resultTimeStepIndexToWellTimeStepIndex[resultTimeStepIndex]; @@ -94,7 +93,7 @@ bool RigWellResults::hasWellResult(size_t resultTimeStepIndex) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigWellResults::firstResultTimeStep() const +size_t RigSingleWellResultsData::firstResultTimeStep() const { size_t i = 0; for(i = 0; i < m_resultTimeStepIndexToWellTimeStepIndex.size(); ++i) @@ -109,7 +108,7 @@ size_t RigWellResults::firstResultTimeStep() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigWellResults::computeStaticWellCellPath() +void RigSingleWellResultsData::computeStaticWellCellPath() { if (m_wellCellsTimeSteps.size() == 0) return; diff --git a/ApplicationCode/ReservoirDataModel/RigWellResults.h b/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.h similarity index 95% rename from ApplicationCode/ReservoirDataModel/RigWellResults.h rename to ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.h index 9c247c4cf9..7e27f23073 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellResults.h +++ b/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.h @@ -18,8 +18,13 @@ #pragma once +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfMath.h" + #include "RimDefines.h" #include +#include struct RigWellResultCell { @@ -94,7 +99,7 @@ public: //================================================================================================== /// //================================================================================================== -class RigWellResults : public cvf::Object +class RigSingleWellResultsData : public cvf::Object { public: bool hasWellResult(size_t resultTimeStepIndex) const; @@ -104,7 +109,7 @@ public: void computeStaticWellCellPath(); - void computeMappingFromResultTimeIndicesToWellTimeIndices(const QList& resultTimes); + void computeMappingFromResultTimeIndicesToWellTimeIndices(const std::vector& resultTimes); public: QString m_wellName; diff --git a/ApplicationCode/ReservoirDataModel/RigStatisticsMath.cpp b/ApplicationCode/ReservoirDataModel/RigStatisticsMath.cpp new file mode 100644 index 0000000000..4abdd28e0b --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigStatisticsMath.cpp @@ -0,0 +1,192 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RigStatisticsMath.h" +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// A function to do basic statistical calculations +//-------------------------------------------------------------------------------------------------- + +void RigStatisticsMath::calculateBasicStatistics(const std::vector& values, double* min, double* max, double* range, double* mean, double* dev) +{ + double m_min(HUGE_VAL); + double m_max(-HUGE_VAL); + double m_mean(HUGE_VAL); + double m_dev(HUGE_VAL); + + double sum = 0.0; + double sumSquared = 0.0; + + size_t validValueCount = 0; + + for (size_t i = 0; i < values.size(); i++) + { + double val = values[i]; + if (val == HUGE_VAL) continue; + + validValueCount++; + + if (val < m_min) m_min = val; + if (val > m_max) m_max = val; + + sum += val; + sumSquared += (val * val); + } + + if (validValueCount > 0) + { + m_mean = sum / validValueCount; + + + // http://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods + // Running standard deviation + + double s0 = static_cast(validValueCount); + double s1 = sum; + double s2 = sumSquared; + + m_dev = sqrt( (s0 * s2) - (s1 * s1) ) / s0; + } + + if (min) *min = m_min; + if (max) *max = m_max; + if (range) *range = m_max - m_min; + + if (mean) *mean = m_mean; + if (dev) *dev = m_dev; +} + + +//-------------------------------------------------------------------------------------------------- +/// Calculate the percentiles of /a inputValues at the pValPosition percentages using the "Nearest Rank" +/// method. This method treats HUGE_VAL as "undefined" values, and ignores these. Will return HUGE_VAL if +/// the inputValues does not contain any valid values +//-------------------------------------------------------------------------------------------------- + +std::vector RigStatisticsMath::calculateNearestRankPercentiles(const std::vector & inputValues, const std::vector& pValPositions) +{ + std::vector sortedValues; + sortedValues.reserve(inputValues.size()); + + for (size_t i = 0; i < inputValues.size(); ++i) + { + if (inputValues[i] != HUGE_VAL) + { + sortedValues.push_back(inputValues[i]); + } + } + + std::sort(sortedValues.begin(), sortedValues.end()); + + std::vector percentiles(pValPositions.size(), HUGE_VAL); + if (sortedValues.size()) + { + for (size_t i = 0; i < pValPositions.size(); ++i) + { + double pVal = HUGE_VAL; + + size_t pValIndex = static_cast(sortedValues.size() * fabs(pValPositions[i]) / 100); + + if (pValIndex >= sortedValues.size() ) pValIndex = sortedValues.size() - 1; + + pVal = sortedValues[pValIndex]; + percentiles[i] = pVal; + } + } + + return percentiles; +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigHistogramCalculator::RigHistogramCalculator(double min, double max, size_t nBins, std::vector* histogram) +{ + assert(histogram); + assert(nBins > 0); + + if (max == min) { nBins = 1; } // Avoid dividing on 0 range + + m_histogram = histogram; + m_min = min; + m_observationCount = 0; + + // Initialize bins + m_histogram->resize(nBins); + for (size_t i = 0; i < m_histogram->size(); ++i) (*m_histogram)[i] = 0; + + m_range = max - min; + maxIndex = nBins-1; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigHistogramCalculator::addData(const std::vector& data) +{ + assert(m_histogram); + for (size_t i = 0; i < data.size(); ++i) + { + if (data[i] == HUGE_VAL) + { + continue; + } + + size_t index = 0; + + if (maxIndex > 0) index = (size_t)(maxIndex*(data[i] - m_min)/m_range); + + if(index < m_histogram->size()) // Just clip to the max min range (-index will overflow to positive ) + { + (*m_histogram)[index]++; + m_observationCount++; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigHistogramCalculator::calculatePercentil(double pVal) +{ + assert(m_histogram); + assert(m_histogram->size()); + assert( 0.0 <= pVal && pVal <= 1.0); + + double pValObservationCount = pVal*m_observationCount; + if (pValObservationCount == 0.0) return m_min; + + size_t accObsCount = 0; + double binWidth = m_range/m_histogram->size(); + for (size_t binIdx = 0; binIdx < m_histogram->size(); ++binIdx) + { + size_t binObsCount = (*m_histogram)[binIdx]; + + accObsCount += binObsCount; + if (accObsCount >= pValObservationCount) + { + double domainValueAtEndOfBin = m_min + (binIdx+1) * binWidth; + double unusedFractionOfLastBin = (double)(accObsCount - pValObservationCount)/binObsCount; + return domainValueAtEndOfBin - unusedFractionOfLastBin*binWidth; + } + } + assert(false); + return HUGE_VAL; +} diff --git a/ApplicationCode/ReservoirDataModel/RigStatisticsMath.h b/ApplicationCode/ReservoirDataModel/RigStatisticsMath.h new file mode 100644 index 0000000000..b8fb91a8a1 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigStatisticsMath.h @@ -0,0 +1,54 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include +#include +#include + +class RigStatisticsMath +{ +public: + static void calculateBasicStatistics(const std::vector& values, double* min, double* max, double* range, double* mean, double* dev); + static std::vector calculateNearestRankPercentiles(const std::vector & inputValues, const std::vector& pValPositions); +}; + +//================================================================================================== +/// Class to calculate a histogram, and histogram based p-value estimates +//================================================================================================== + +class RigHistogramCalculator +{ +public: + RigHistogramCalculator(double min, double max, size_t nBins, std::vector* histogram); + + void addData(const std::vector& data); + + /// Calculates the estimated percentile from the histogram. + /// the percentile is the domain value at which pVal of the observations are below it. + /// Will only consider observed values between min and max, as all other values are discarded from the histogram + + double calculatePercentil(double pVal); + +private: + size_t maxIndex; + double m_range; + double m_min; + size_t m_observationCount; + std::vector* m_histogram; +}; diff --git a/ApplicationCode/Resources/AppLogo48x48.ico b/ApplicationCode/Resources/AppLogo48x48.ico new file mode 100644 index 0000000000..70cbfee6f9 Binary files /dev/null and b/ApplicationCode/Resources/AppLogo48x48.ico differ diff --git a/ApplicationCode/Resources/AppLogo48x48.png b/ApplicationCode/Resources/AppLogo48x48.png index ec13d014fc..8015d06ea7 100644 Binary files a/ApplicationCode/Resources/AppLogo48x48.png and b/ApplicationCode/Resources/AppLogo48x48.png differ diff --git a/ApplicationCode/Resources/Cases16x16.png b/ApplicationCode/Resources/Cases16x16.png new file mode 100644 index 0000000000..843e4d95a5 Binary files /dev/null and b/ApplicationCode/Resources/Cases16x16.png differ diff --git a/ApplicationCode/Resources/CreateGridCaseGroup16x16.png b/ApplicationCode/Resources/CreateGridCaseGroup16x16.png new file mode 100644 index 0000000000..65bb871267 Binary files /dev/null and b/ApplicationCode/Resources/CreateGridCaseGroup16x16.png differ diff --git a/ApplicationCode/Resources/GridCaseGroup16x16.png b/ApplicationCode/Resources/GridCaseGroup16x16.png new file mode 100644 index 0000000000..ed3a90af25 Binary files /dev/null and b/ApplicationCode/Resources/GridCaseGroup16x16.png differ diff --git a/ApplicationCode/Resources/Histogram16x16.png b/ApplicationCode/Resources/Histogram16x16.png new file mode 100644 index 0000000000..0a500bb997 Binary files /dev/null and b/ApplicationCode/Resources/Histogram16x16.png differ diff --git a/ApplicationCode/Resources/Histograms16x16.png b/ApplicationCode/Resources/Histograms16x16.png new file mode 100644 index 0000000000..08b0aa9f81 Binary files /dev/null and b/ApplicationCode/Resources/Histograms16x16.png differ diff --git a/ApplicationCode/Resources/ResInsight.qrc b/ApplicationCode/Resources/ResInsight.qrc index 2028c1cff5..4bb322cec7 100644 --- a/ApplicationCode/Resources/ResInsight.qrc +++ b/ApplicationCode/Resources/ResInsight.qrc @@ -23,7 +23,13 @@ octave.png Folder.png EclipseInput48x48.png - + Cases16x16.png + CreateGridCaseGroup16x16.png + GridCaseGroup16x16.png + Histogram16x16.png + Histograms16x16.png + ZoomAll16x16.png + fs_CellFace.glsl vs_CellFace.glsl diff --git a/ApplicationCode/Resources/ResInsight.rc b/ApplicationCode/Resources/ResInsight.rc new file mode 100644 index 0000000000..c39e833bbb --- /dev/null +++ b/ApplicationCode/Resources/ResInsight.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON "AppLogo48x48.ico" diff --git a/ApplicationCode/Resources/ZoomAll16x16.png b/ApplicationCode/Resources/ZoomAll16x16.png new file mode 100644 index 0000000000..9970c772ee Binary files /dev/null and b/ApplicationCode/Resources/ZoomAll16x16.png differ diff --git a/ApplicationCode/Resources/new16x16.png b/ApplicationCode/Resources/new16x16.png new file mode 100644 index 0000000000..7acec898d2 Binary files /dev/null and b/ApplicationCode/Resources/new16x16.png differ diff --git a/ApplicationCode/RIMain.cpp b/ApplicationCode/RiaMain.cpp similarity index 88% rename from ApplicationCode/RIMain.cpp rename to ApplicationCode/RiaMain.cpp index 1c877ae238..5804647de9 100644 --- a/ApplicationCode/RIMain.cpp +++ b/ApplicationCode/RiaMain.cpp @@ -16,18 +16,18 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RIApplication.h" -#include "RIMainWindow.h" +#include "RiaStdInclude.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" int main(int argc, char *argv[]) { - RIApplication app(argc, argv); + RiaApplication app(argc, argv); QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); - RIMainWindow window; + RiuMainWindow window; QString platform = cvf::System::is64Bit() ? "(64bit)" : "(32bit)"; window.setWindowTitle("ResInsight " + platform); window.resize(1000, 800); diff --git a/ApplicationCode/RIStdInclude.cpp b/ApplicationCode/RiaStdInclude.cpp similarity index 96% rename from ApplicationCode/RIStdInclude.cpp rename to ApplicationCode/RiaStdInclude.cpp index e14a6d73e2..2c78f30884 100644 --- a/ApplicationCode/RIStdInclude.cpp +++ b/ApplicationCode/RiaStdInclude.cpp @@ -16,5 +16,5 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" diff --git a/ApplicationCode/RIStdInclude.h b/ApplicationCode/RiaStdInclude.h similarity index 100% rename from ApplicationCode/RIStdInclude.h rename to ApplicationCode/RiaStdInclude.h diff --git a/ApplicationCode/SocketInterface/RiaSocketServer.cpp b/ApplicationCode/SocketInterface/RiaSocketServer.cpp index e5de2c2e25..ad676d6462 100644 --- a/ApplicationCode/SocketInterface/RiaSocketServer.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketServer.cpp @@ -1,4 +1,3 @@ -///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2011-2012 Statoil ASA, Ceetron AS // @@ -16,7 +15,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include #include @@ -24,13 +23,13 @@ #include #include "RiaSocketServer.h" -#include "RIApplication.h" -#include "RIMainWindow.h" -#include "RimReservoir.h" -#include "RigReservoir.h" -#include "RigReservoirCellResults.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" +#include "RimCase.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" #include "RimInputProperty.h" -#include "RimInputReservoir.h" +#include "RimInputCase.h" #include "RimUiTreeModelPdm.h" //-------------------------------------------------------------------------------------------------- @@ -48,7 +47,7 @@ RiaSocketServer::RiaSocketServer(QObject* parent) m_invalidActiveCellCountDetected(false), m_readState(ReadingCommand) { - m_errorMessageDialog = new QErrorMessage(RIMainWindow::instance()); + m_errorMessageDialog = new QErrorMessage(RiuMainWindow::instance()); // TCP server setup @@ -152,18 +151,18 @@ void RiaSocketServer::handleClientConnection(QTcpSocket* clientToHandle) //-------------------------------------------------------------------------------------------------- /// Find the requested reservoir: Current, by index or by name //-------------------------------------------------------------------------------------------------- -RimReservoir* RiaSocketServer::findReservoir(const QString& caseName) +RimCase* RiaSocketServer::findReservoir(const QString& caseName) { if (caseName.isEmpty()) { - if (RIApplication::instance()->activeReservoirView()) + if (RiaApplication::instance()->activeReservoirView()) { - return RIApplication::instance()->activeReservoirView()->eclipseCase(); + return RiaApplication::instance()->activeReservoirView()->eclipseCase(); } } else { - RimProject* project = RIApplication::instance()->project(); + RimProject* project = RiaApplication::instance()->project(); if (!project) return NULL; bool isInt = false; @@ -180,7 +179,7 @@ RimReservoir* RiaSocketServer::findReservoir(const QString& caseName) { for (size_t cIdx = 0; cIdx < project->reservoirs.size(); ++cIdx) { - if (project->reservoirs[cIdx] && project->reservoirs[cIdx]->caseName() == caseName ) + if (project->reservoirs[cIdx] && project->reservoirs[cIdx]->caseUserDescription() == caseName ) { return project->reservoirs[cIdx]; } @@ -242,7 +241,7 @@ void RiaSocketServer::readCommandFromOctave() QString caseName; QString propertyName; - RimReservoir* reservoir = NULL; + RimCase* reservoir = NULL; // Find the correct arguments @@ -281,18 +280,18 @@ void RiaSocketServer::readCommandFromOctave() size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; std::vector< std::vector >* scalarResultFrames = NULL; - if (reservoir && reservoir->reservoirData() && reservoir->reservoirData()->mainGrid() && reservoir->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)) + if (reservoir && reservoir->results(RifReaderInterface::MATRIX_RESULTS)) { - scalarResultIndex = reservoir->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResult(propertyName); + scalarResultIndex = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResult(propertyName); if (scalarResultIndex == cvf::UNDEFINED_SIZE_T && isSetProperty) { - scalarResultIndex = reservoir->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::GENERATED, propertyName); + scalarResultIndex = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->addEmptyScalarResult(RimDefines::GENERATED, propertyName, true); } if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) { - scalarResultFrames = &(reservoir->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(scalarResultIndex)); + scalarResultFrames = &(reservoir->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->cellScalarResults(scalarResultIndex)); m_currentScalarIndex = scalarResultIndex; m_currentPropertyName = propertyName; } @@ -368,8 +367,14 @@ void RiaSocketServer::readCommandFromOctave() return; } - reservoir->reservoirData()->mainGrid()->calculateMatrixModelActiveCellInfo(activeCellInfo[0], activeCellInfo[1], activeCellInfo[2], activeCellInfo[3], - activeCellInfo[4], activeCellInfo[5], activeCellInfo[6], activeCellInfo[7]); + calculateMatrixModelActiveCellInfo(activeCellInfo[0], + activeCellInfo[1], + activeCellInfo[2], + activeCellInfo[3], + activeCellInfo[4], + activeCellInfo[5], + activeCellInfo[6], + activeCellInfo[7]); // First write timestep count quint64 timestepCount = (quint64)8; @@ -441,15 +446,15 @@ void RiaSocketServer::readPropertyDataFromOctave() size_t cellCountFromOctave = m_bytesPerTimeStepToRead / sizeof(double); - size_t gridActiveCellCount = m_currentReservoir->reservoirData()->mainGrid()->globalMatrixModelActiveCellCount(); + size_t gridActiveCellCount = m_currentReservoir->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->globalActiveCellCount(); size_t gridTotalCellCount = m_currentReservoir->reservoirData()->mainGrid()->cellCount(); if (cellCountFromOctave != gridActiveCellCount && cellCountFromOctave != gridTotalCellCount) { m_errorMessageDialog->showMessage(tr("ResInsight SocketServer: \n") + - tr("The number of cells in the data coming from octave does not match the case") + ":\"" + m_currentReservoir->caseName() + "\"\n" + 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->caseName() + ": Active cell count: " + QString::number(gridActiveCellCount) + " Total cell count: " + QString::number(gridTotalCellCount)) ; + " " + m_currentReservoir->caseUserDescription() + ": Active cell count: " + QString::number(gridActiveCellCount) + " Total cell count: " + QString::number(gridTotalCellCount)) ; cellCountFromOctave = 0; m_invalidActiveCellCountDetected = true; @@ -497,7 +502,7 @@ void RiaSocketServer::readPropertyDataFromOctave() if (m_currentReservoir != NULL) { // Create a new input property if we have an input reservoir - RimInputReservoir* inputRes = dynamic_cast(m_currentReservoir); + RimInputCase* inputRes = dynamic_cast(m_currentReservoir); if (inputRes) { RimInputProperty* inputProperty = NULL; @@ -509,7 +514,7 @@ void RiaSocketServer::readPropertyDataFromOctave() inputProperty->eclipseKeyword = ""; inputProperty->fileName = ""; inputRes->m_inputPropertyCollection->inputProperties.push_back(inputProperty); - RimUiTreeModelPdm* treeModel = RIMainWindow::instance()->uiPdmModel(); + RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); treeModel->rebuildUiSubTree(inputRes->m_inputPropertyCollection()); } inputProperty->resolvedState = RimInputProperty::RESOLVED_NOT_SAVED; @@ -517,10 +522,9 @@ void RiaSocketServer::readPropertyDataFromOctave() if( m_currentScalarIndex != cvf::UNDEFINED_SIZE_T && m_currentReservoir->reservoirData() && - m_currentReservoir->reservoirData()->mainGrid() && - m_currentReservoir->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS) ) + m_currentReservoir->reservoirData()->results(RifReaderInterface::MATRIX_RESULTS) ) { - m_currentReservoir->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->recalculateMinMax(m_currentScalarIndex); + m_currentReservoir->reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)->recalculateMinMax(m_currentScalarIndex); } for (size_t i = 0; i < m_currentReservoir->reservoirViews.size(); ++i) @@ -611,3 +615,77 @@ void RiaSocketServer::slotReadyRead() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaSocketServer::calculateMatrixModelActiveCellInfo(std::vector& gridNumber, std::vector& cellI, std::vector& cellJ, std::vector& cellK, std::vector& parentGridNumber, std::vector& hostCellI, std::vector& hostCellJ, std::vector& hostCellK) +{ + gridNumber.clear(); + cellI.clear(); + cellJ.clear(); + cellK.clear(); + parentGridNumber.clear(); + hostCellI.clear(); + hostCellJ.clear(); + hostCellK.clear(); + + if (!m_currentReservoir || !m_currentReservoir->reservoirData() || !m_currentReservoir->reservoirData()->mainGrid()) + { + return; + } + + RigActiveCellInfo* actCellInfo = m_currentReservoir->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); + size_t numMatrixModelActiveCells = actCellInfo->globalActiveCellCount(); + + gridNumber.reserve(numMatrixModelActiveCells); + cellI.reserve(numMatrixModelActiveCells); + cellJ.reserve(numMatrixModelActiveCells); + cellK.reserve(numMatrixModelActiveCells); + parentGridNumber.reserve(numMatrixModelActiveCells); + hostCellI.reserve(numMatrixModelActiveCells); + hostCellJ.reserve(numMatrixModelActiveCells); + hostCellK.reserve(numMatrixModelActiveCells); + + const std::vector& globalCells = m_currentReservoir->reservoirData()->mainGrid()->cells(); + + for (size_t cIdx = 0; cIdx < globalCells.size(); ++cIdx) + { + if (actCellInfo->isActive(cIdx)) + { + RigGridBase* grid = globalCells[cIdx].hostGrid(); + CVF_ASSERT(grid != NULL); + size_t cellIndex = globalCells[cIdx].cellIndex(); + + size_t i, j, k; + grid->ijkFromCellIndex(cellIndex, &i, &j, &k); + + size_t pi, pj, pk; + RigGridBase* parentGrid = NULL; + + if (grid->isMainGrid()) + { + pi = i; + pj = j; + pk = k; + parentGrid = grid; + } + else + { + size_t parentCellIdx = globalCells[cIdx].parentCellIndex(); + parentGrid = (static_cast(grid))->parentGrid(); + CVF_ASSERT(parentGrid != NULL); + parentGrid->ijkFromCellIndex(parentCellIdx, &pi, &pj, &pk); + } + + gridNumber.push_back(static_cast(grid->gridIndex())); + cellI.push_back(static_cast(i)); + cellJ.push_back(static_cast(j)); + cellK.push_back(static_cast(k)); + parentGridNumber.push_back(static_cast(parentGrid->gridIndex())); + hostCellI.push_back(static_cast(pi)); + hostCellJ.push_back(static_cast(pj)); + hostCellK.push_back(static_cast(pk)); + } + } +} + diff --git a/ApplicationCode/SocketInterface/RiaSocketServer.h b/ApplicationCode/SocketInterface/RiaSocketServer.h index e6e0d54553..6e19a1bb74 100644 --- a/ApplicationCode/SocketInterface/RiaSocketServer.h +++ b/ApplicationCode/SocketInterface/RiaSocketServer.h @@ -27,7 +27,7 @@ class QTcpServer; class QTcpSocket; class QNetworkSession; class QErrorMessage; -class RimReservoir; +class RimCase; class RiaSocketServer : public QObject @@ -53,9 +53,19 @@ private: void handleClientConnection( QTcpSocket* clientToHandle); - RimReservoir* findReservoir(const QString &casename); + RimCase* findReservoir(const QString &casename); void terminateCurrentConnection(); + void calculateMatrixModelActiveCellInfo(std::vector& gridNumber, + std::vector& cellI, + std::vector& cellJ, + std::vector& cellK, + std::vector& parentGridNumber, + std::vector& hostCellI, + std::vector& hostCellJ, + std::vector& hostCellK); + + private: QTcpServer* m_tcpServer; QErrorMessage* m_errorMessageDialog; @@ -70,7 +80,7 @@ private: quint64 m_bytesPerTimeStepToRead; size_t m_currentTimeStepToRead; std::vector< std::vector >* m_scalarResultsToAdd; - RimReservoir* m_currentReservoir; + RimCase* m_currentReservoir; size_t m_currentScalarIndex; QString m_currentPropertyName; bool m_invalidActiveCellCountDetected; diff --git a/ApplicationCode/UserInterface/RICursors.cpp b/ApplicationCode/UserInterface/RiuCursors.cpp similarity index 92% rename from ApplicationCode/UserInterface/RICursors.cpp rename to ApplicationCode/UserInterface/RiuCursors.cpp index bdf913ec2a..bc84b95511 100644 --- a/ApplicationCode/UserInterface/RICursors.cpp +++ b/ApplicationCode/UserInterface/RiuCursors.cpp @@ -16,9 +16,9 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" -#include "RICursors.h" +#include "RiuCursors.h" #include #include @@ -35,7 +35,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RICursors::RICursors() +RiuCursors::RiuCursors() { m_cursors[FILTER_BOX] = cursorFromFile(":/Cursors/curFilterBox.bmp", 10, 10); m_cursors[NORMAL] = cursorFromFile(":/Cursors/curNormal.bmp", 10, 10); @@ -53,10 +53,10 @@ RICursors::RICursors() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QCursor RICursors::get(CursorIndex cursorIdx) +QCursor RiuCursors::get(CursorIndex cursorIdx) { // Create our single instance in a local static variable - static RICursors myStaticInstance; + static RiuCursors myStaticInstance; return myStaticInstance.m_cursors[cursorIdx]; } @@ -65,7 +65,7 @@ QCursor RICursors::get(CursorIndex cursorIdx) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QCursor RICursors::cursorFromFile(const QString& fileName, int hotspotX, int hotspotY) +QCursor RiuCursors::cursorFromFile(const QString& fileName, int hotspotX, int hotspotY) { QImage image(fileName); if (image.width() == 0 || image.height() == 0) diff --git a/ApplicationCode/UserInterface/RICursors.h b/ApplicationCode/UserInterface/RiuCursors.h similarity index 97% rename from ApplicationCode/UserInterface/RICursors.h rename to ApplicationCode/UserInterface/RiuCursors.h index 136642c9fd..61fb559a01 100644 --- a/ApplicationCode/UserInterface/RICursors.h +++ b/ApplicationCode/UserInterface/RiuCursors.h @@ -27,7 +27,7 @@ // Singleton for getting the cursors // //================================================================================================== -class RICursors +class RiuCursors { public: enum CursorIndex @@ -48,7 +48,7 @@ public: static QCursor get(CursorIndex cursorIdx); private: - RICursors(); + RiuCursors(); static QCursor cursorFromFile(const QString& fileName, int hotspotX = -1, int hotspotY = -1); private: diff --git a/ApplicationCode/UserInterface/RIMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp similarity index 79% rename from ApplicationCode/UserInterface/RIMainWindow.cpp rename to ApplicationCode/UserInterface/RiuMainWindow.cpp index d26340fb8f..07d8e3e145 100644 --- a/ApplicationCode/UserInterface/RIMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -16,20 +16,20 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RIBaseDefs.h" +#include "RiaStdInclude.h" +#include "RiaBaseDefs.h" -#include "RIApplication.h" -#include "RIMainWindow.h" -#include "RIViewer.h" -#include "RIResultInfoPanel.h" -#include "RIProcessMonitor.h" -#include "RIPreferences.h" -#include "RIPreferencesDialog.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" +#include "RiuViewer.h" +#include "RiuResultInfoPanel.h" +#include "RiuProcessMonitor.h" +#include "RiaPreferences.h" +#include "RiuPreferencesDialog.h" -#include "RigReservoir.h" -#include "RigReservoirCellResults.h" -#include "RimReservoir.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" +#include "RimCase.h" #include "RimUiTreeModelPdm.h" #include "cvfqtBasicAboutDialog.h" @@ -40,24 +40,25 @@ #include "cafPdmUiPropertyView.h" #include "RimUiTreeView.h" +#include "RiuMultiCaseImportDialog.h" //================================================================================================== /// -/// \class RIMainWindow +/// \class RiuMainWindow /// /// Contains our main window /// //================================================================================================== -RIMainWindow* RIMainWindow::sm_mainWindowInstance = NULL; +RiuMainWindow* RiuMainWindow::sm_mainWindowInstance = NULL; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIMainWindow::RIMainWindow() +RiuMainWindow::RiuMainWindow() : m_treeView(NULL), m_pdmRoot(NULL), m_mainViewer(NULL), @@ -95,14 +96,14 @@ RIMainWindow::RIMainWindow() slotRefreshEditActions(); // Set pdm root so scripts are displayed - setPdmRoot(RIApplication::instance()->project()); + setPdmRoot(RiaApplication::instance()->project()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIMainWindow* RIMainWindow::instance() +RiuMainWindow* RiuMainWindow::instance() { return sm_mainWindowInstance; } @@ -110,18 +111,18 @@ RIMainWindow* RIMainWindow::instance() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::initializeGuiNewProjectLoaded() +void RiuMainWindow::initializeGuiNewProjectLoaded() { slotRefreshFileActions(); slotRefreshEditActions(); refreshAnimationActions(); - setPdmRoot(RIApplication::instance()->project()); + setPdmRoot(RiaApplication::instance()->project()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::cleanupGuiBeforeProjectClose() +void RiuMainWindow::cleanupGuiBeforeProjectClose() { setPdmRoot(NULL); setResultInfo(""); @@ -137,7 +138,7 @@ void RIMainWindow::cleanupGuiBeforeProjectClose() //-------------------------------------------------------------------------------------------------- /// Lightweight refresh of GUI (mainly toolbar actions). Called during idle processing //-------------------------------------------------------------------------------------------------- -void RIMainWindow::refreshGuiLightweight() +void RiuMainWindow::refreshGuiLightweight() { refreshToolbars(); } @@ -145,7 +146,7 @@ void RIMainWindow::refreshGuiLightweight() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::refreshToolbars() +void RiuMainWindow::refreshToolbars() { slotRefreshFileActions(); slotRefreshViewActions(); @@ -154,9 +155,9 @@ void RIMainWindow::refreshToolbars() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::closeEvent(QCloseEvent* event) +void RiuMainWindow::closeEvent(QCloseEvent* event) { - if (!RIApplication::instance()->closeProject(true)) + if (!RiaApplication::instance()->closeProject(true)) { event->ignore(); return; @@ -172,11 +173,13 @@ void RIMainWindow::closeEvent(QCloseEvent* event) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::createActions() +void RiuMainWindow::createActions() { // File actions m_openAction = new QAction(QIcon(":/AppLogo48x48.png"), "&Open Eclipse Case", this); m_openInputEclipseFileAction= new QAction(QIcon(":/EclipseInput48x48.png"), "&Open Input Eclipse Case", this); + m_openMultipleEclipseCasesAction = new QAction(QIcon(":/CreateGridCaseGroup16x16.png"), "&Create Grid Case Group from Files", this); + m_openProjectAction = new QAction(style()->standardIcon(QStyle::SP_DirOpenIcon), "&Open Project", this); m_openLastUsedProjectAction = new QAction("Open &Last Used Project", this); @@ -197,6 +200,7 @@ void RIMainWindow::createActions() connect(m_openAction, SIGNAL(triggered()), SLOT(slotOpenBinaryGridFiles())); connect(m_openInputEclipseFileAction,SIGNAL(triggered()), SLOT(slotOpenInputFiles())); + connect(m_openMultipleEclipseCasesAction,SIGNAL(triggered()), SLOT(slotOpenMultipleCases())); connect(m_openProjectAction, SIGNAL(triggered()), SLOT(slotOpenProject())); connect(m_openLastUsedProjectAction,SIGNAL(triggered()), SLOT(slotOpenLastUsedProject())); @@ -234,7 +238,7 @@ void RIMainWindow::createActions() m_viewFromBelow = new QAction(QIcon(":/UpViewArrow.png"),"Look Up", this); m_viewFromBelow->setToolTip("Look Up"); - m_zoomAll = new QAction(QIcon(),"Zoom all", this); + m_zoomAll = new QAction(QIcon(":/ZoomAll16x16.png"),"Zoom all", this); m_zoomAll->setToolTip("Zoom to view all"); connect(m_viewFromNorth, SIGNAL(triggered()), SLOT(slotViewFromNorth())); @@ -258,12 +262,13 @@ void RIMainWindow::createActions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::createMenus() +void RiuMainWindow::createMenus() { // File menu QMenu* fileMenu = menuBar()->addMenu("&File"); fileMenu->addAction(m_openAction); fileMenu->addAction(m_openInputEclipseFileAction); + fileMenu->addAction(m_openMultipleEclipseCasesAction); fileMenu->addAction(m_openProjectAction); fileMenu->addAction(m_openLastUsedProjectAction); @@ -325,7 +330,7 @@ void RIMainWindow::createMenus() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::createToolBars() +void RiuMainWindow::createToolBars() { m_standardToolBar = addToolBar(tr("Standard")); @@ -345,6 +350,7 @@ void RIMainWindow::createToolBars() // View toolbar m_viewToolBar = addToolBar(tr("View")); m_viewToolBar->setObjectName(m_viewToolBar->windowTitle()); + m_viewToolBar->addAction(m_zoomAll); m_viewToolBar->addAction(m_viewFromNorth); m_viewToolBar->addAction(m_viewFromSouth); m_viewToolBar->addAction(m_viewFromEast); @@ -360,7 +366,7 @@ void RIMainWindow::createToolBars() /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::createDockPanels() +void RiuMainWindow::createDockPanels() { { QDockWidget* dockWidget = new QDockWidget("Project", this); @@ -369,6 +375,13 @@ void RIMainWindow::createDockPanels() m_treeView = new RimUiTreeView(dockWidget); m_treeView->setModel(m_treeModelPdm); + m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); + + // Drag and drop configuration + m_treeView->setDragEnabled(true); + m_treeView->viewport()->setAcceptDrops(true); + m_treeView->setDropIndicatorShown(true); + m_treeView->setDragDropMode(QAbstractItemView::DragDrop); dockWidget->setWidget(m_treeView); @@ -379,7 +392,7 @@ void RIMainWindow::createDockPanels() QDockWidget* dockPanel = new QDockWidget("Result Info", this); dockPanel->setObjectName("dockResultInfoPanel"); dockPanel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); - m_resultInfoPanel = new RIResultInfoPanel(dockPanel); + m_resultInfoPanel = new RiuResultInfoPanel(dockPanel); dockPanel->setWidget(m_resultInfoPanel); addDockWidget(Qt::BottomDockWidgetArea, dockPanel); @@ -389,7 +402,7 @@ void RIMainWindow::createDockPanels() QDockWidget* dockPanel = new QDockWidget("Process Monitor", this); dockPanel->setObjectName("dockProcessMonitor"); dockPanel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); - m_processMonitor = new RIProcessMonitor(dockPanel); + m_processMonitor = new RiuProcessMonitor(dockPanel); dockPanel->setWidget(m_processMonitor); addDockWidget(Qt::BottomDockWidgetArea, dockPanel); @@ -416,7 +429,7 @@ void RIMainWindow::createDockPanels() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::saveWinGeoAndDockToolBarLayout() +void RiuMainWindow::saveWinGeoAndDockToolBarLayout() { // Company and appname set through QCoreApplication QSettings settings; @@ -432,7 +445,7 @@ void RIMainWindow::saveWinGeoAndDockToolBarLayout() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::loadWinGeoAndDockToolBarLayout() +void RiuMainWindow::loadWinGeoAndDockToolBarLayout() { // Company and appname set through QCoreApplication QSettings settings; @@ -455,7 +468,7 @@ void RIMainWindow::loadWinGeoAndDockToolBarLayout() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::setResultInfo(const QString& info) const +void RiuMainWindow::setResultInfo(const QString& info) const { m_resultInfoPanel->setInfo(info); } @@ -471,9 +484,9 @@ void RIMainWindow::setResultInfo(const QString& info) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotRefreshFileActions() +void RiuMainWindow::slotRefreshFileActions() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); bool projectExists = true; m_saveProjectAction->setEnabled(projectExists); @@ -485,9 +498,9 @@ void RIMainWindow::slotRefreshFileActions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotRefreshEditActions() +void RiuMainWindow::slotRefreshEditActions() { -// RIApplication* app = RIApplication::instance(); +// RiaApplication* app = RiaApplication::instance(); // RISceneManager* proj = app->project(); } @@ -495,9 +508,9 @@ void RIMainWindow::slotRefreshEditActions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotRefreshViewActions() +void RiuMainWindow::slotRefreshViewActions() { -// RIApplication* app = RIApplication::instance(); +// RiaApplication* app = RiaApplication::instance(); // RISceneManager* proj = app->project(); bool enabled = true; @@ -512,12 +525,12 @@ void RIMainWindow::slotRefreshViewActions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::refreshAnimationActions() +void RiuMainWindow::refreshAnimationActions() { caf::FrameAnimationControl* ac = NULL; - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - ac = RIApplication::instance()->activeReservoirView()->viewer()->animationControl(); + ac = RiaApplication::instance()->activeReservoirView()->viewer()->animationControl(); } m_animationToolBar->connectAnimationControl(ac); @@ -525,7 +538,7 @@ void RIMainWindow::refreshAnimationActions() QStringList timeStepStrings; int currentTimeStepIndex = 0; - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); bool enableAnimControls = false; if (app->activeReservoirView() && @@ -534,15 +547,15 @@ void RIMainWindow::refreshAnimationActions() { enableAnimControls = true; - if (app->activeReservoirView()->gridCellResults()) + if (app->activeReservoirView()->currentGridCellResults()) { if (app->activeReservoirView()->cellResult()->hasDynamicResult() || app->activeReservoirView()->propertyFilterCollection()->hasActiveDynamicFilters() || app->activeReservoirView()->wellCollection()->hasVisibleWellPipes()) { - QList timeStepDates = app->activeReservoirView()->gridCellResults()->timeStepDates(0); + std::vector timeStepDates = app->activeReservoirView()->currentGridCellResults()->cellResults()->timeStepDates(0); bool showHoursAndMinutes = false; - for (int i = 0; i < timeStepDates.size(); i++) + for (size_t i = 0; i < timeStepDates.size(); i++) { if (timeStepDates[i].time().hour() != 0.0 || timeStepDates[i].time().minute() != 0.0) { @@ -556,17 +569,24 @@ void RIMainWindow::refreshAnimationActions() formatString += " - hh:mm"; } - for (int i = 0; i < timeStepDates.size(); i++) + for (size_t i = 0; i < timeStepDates.size(); i++) { timeStepStrings += timeStepDates[i].toString(formatString); } - currentTimeStepIndex = RIApplication::instance()->activeReservoirView()->currentTimeStep(); + currentTimeStepIndex = RiaApplication::instance()->activeReservoirView()->currentTimeStep(); } else { timeStepStrings.push_back(tr("Static Property")); } } + + // Animation control is only relevant for more than one time step + if (timeStepStrings.size() < 2) + { + enableAnimControls = false; + } + m_animationToolBar->setFrameRate(app->activeReservoirView()->maximumFrameRate()); } @@ -580,12 +600,12 @@ void RIMainWindow::refreshAnimationActions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotAbout() +void RiuMainWindow::slotAbout() { cvfqt::BasicAboutDialog dlg(this); dlg.setApplicationName(RI_APPLICATION_NAME); - dlg.setApplicationVersion(RIApplication::getVersionStringApp(true)); + dlg.setApplicationVersion(RiaApplication::getVersionStringApp(true)); dlg.setCopyright("Copyright 2012 Statoil ASA, Ceetron AS"); dlg.showCeeVizVersion(false); @@ -613,11 +633,11 @@ void RIMainWindow::slotAbout() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotOpenBinaryGridFiles() +void RiuMainWindow::slotOpenBinaryGridFiles() { if (checkForDocumentModifications()) { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString defaultDir = app->defaultFileDialogDirectory("BINARY_GRID"); QStringList fileNames = QFileDialog::getOpenFileNames(this, "Open Eclipse File", defaultDir, "Eclipse Grid Files (*.GRID *.EGRID)"); @@ -641,11 +661,11 @@ void RIMainWindow::slotOpenBinaryGridFiles() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotOpenInputFiles() +void RiuMainWindow::slotOpenInputFiles() { if (checkForDocumentModifications()) { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString defaultDir = app->defaultFileDialogDirectory("INPUT_FILES"); QStringList fileNames = QFileDialog::getOpenFileNames(this, "Open Eclipse Input Files", defaultDir, "Eclipse Input Files and Input Properties (*.GRDECL *)"); @@ -662,11 +682,11 @@ void RIMainWindow::slotOpenInputFiles() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotOpenProject() +void RiuMainWindow::slotOpenProject() { if (checkForDocumentModifications()) { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString defaultDir = app->defaultFileDialogDirectory("BINARY_GRID"); QString fileName = QFileDialog::getOpenFileName(this, "Open ResInsight Project", defaultDir, "ResInsight project (*.rip)"); @@ -684,18 +704,18 @@ void RIMainWindow::slotOpenProject() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotOpenLastUsedProject() +void RiuMainWindow::slotOpenLastUsedProject() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->loadLastUsedProject(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotMockModel() +void RiuMainWindow::slotMockModel() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->createMockModel(); //m_mainViewer->setDefaultView(); @@ -704,9 +724,9 @@ void RIMainWindow::slotMockModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotMockResultsModel() +void RiuMainWindow::slotMockResultsModel() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->createResultsMockModel(); //m_mainViewer->setDefaultView(); @@ -716,9 +736,9 @@ void RIMainWindow::slotMockResultsModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotMockLargeResultsModel() +void RiuMainWindow::slotMockLargeResultsModel() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->createLargeResultsMockModel(); } @@ -726,9 +746,9 @@ void RIMainWindow::slotMockLargeResultsModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotInputMockModel() +void RiuMainWindow::slotInputMockModel() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->createInputMockModel(); } @@ -736,18 +756,18 @@ void RIMainWindow::slotInputMockModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSetCurrentFrame(int frameIndex) +void RiuMainWindow::slotSetCurrentFrame(int frameIndex) { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); // app->setTimeStep(frameIndex); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIMainWindow::checkForDocumentModifications() +bool RiuMainWindow::checkForDocumentModifications() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); // RISceneManager* project = app->sceneManager(); // if (project && project->isModified()) // { @@ -775,9 +795,9 @@ bool RIMainWindow::checkForDocumentModifications() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotCloseProject() +void RiuMainWindow::slotCloseProject() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); bool ret = app->closeProject(true); } @@ -785,7 +805,7 @@ void RIMainWindow::slotCloseProject() /// //-------------------------------------------------------------------------------------------------- -QMdiSubWindow* RIMainWindow::findMdiSubWindow(RIViewer* viewer) +QMdiSubWindow* RiuMainWindow::findMdiSubWindow(RiuViewer* viewer) { QList subws = m_mdiArea->subWindowList(); int i; @@ -804,7 +824,7 @@ QMdiSubWindow* RIMainWindow::findMdiSubWindow(RIViewer* viewer) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::removeViewer(RIViewer* viewer) +void RiuMainWindow::removeViewer(RiuViewer* viewer) { #if 0 m_CentralFrame->layout()->removeWidget(viewer->layoutWidget()); @@ -816,7 +836,7 @@ void RIMainWindow::removeViewer(RIViewer* viewer) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::addViewer(RIViewer* viewer) +void RiuMainWindow::addViewer(RiuViewer* viewer) { #if 0 m_CentralFrame->layout()->addWidget(viewer->layoutWidget()); @@ -839,9 +859,9 @@ void RIMainWindow::addViewer(RIViewer* viewer) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSaveProject() +void RiuMainWindow::slotSaveProject() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->saveProject(); } @@ -849,9 +869,9 @@ void RIMainWindow::slotSaveProject() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSaveProjectAs() +void RiuMainWindow::slotSaveProjectAs() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->saveProjectPromptForFileName(); } @@ -860,7 +880,7 @@ void RIMainWindow::slotSaveProjectAs() //-------------------------------------------------------------------------------------------------- /// This method needs to handle memory deallocation !!! //-------------------------------------------------------------------------------------------------- -void RIMainWindow::setPdmRoot(caf::PdmObject* pdmRoot) +void RiuMainWindow::setPdmRoot(caf::PdmObject* pdmRoot) { m_pdmRoot = pdmRoot; @@ -878,92 +898,92 @@ void RIMainWindow::setPdmRoot(caf::PdmObject* pdmRoot) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotViewFromNorth() +void RiuMainWindow::slotViewFromNorth() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,-1,0), cvf::Vec3d(0,0,1)); + RiaApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,-1,0), cvf::Vec3d(0,0,1)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotViewFromSouth() +void RiuMainWindow::slotViewFromSouth() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,1,0), cvf::Vec3d(0,0,1)); + RiaApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,1,0), cvf::Vec3d(0,0,1)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotViewFromEast() +void RiuMainWindow::slotViewFromEast() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(-1,0,0), cvf::Vec3d(0,0,1)); + RiaApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(-1,0,0), cvf::Vec3d(0,0,1)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotViewFromWest() +void RiuMainWindow::slotViewFromWest() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(1,0,0), cvf::Vec3d(0,0,1)); + RiaApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(1,0,0), cvf::Vec3d(0,0,1)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotViewFromAbove() +void RiuMainWindow::slotViewFromAbove() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,0,-1), cvf::Vec3d(0,1,0)); + RiaApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,0,-1), cvf::Vec3d(0,1,0)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotViewFromBelow() +void RiuMainWindow::slotViewFromBelow() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,0,1), cvf::Vec3d(0,1,0)); + RiaApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,0,1), cvf::Vec3d(0,1,0)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotZoomAll() +void RiuMainWindow::slotZoomAll() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->zoomAll(); + RiaApplication::instance()->activeReservoirView()->viewer()->zoomAll(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) +void RiuMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) { - RimProject * proj = RIApplication::instance()->project(); + RimProject * proj = RiaApplication::instance()->project(); if (!proj) return; size_t i; for (i = 0; i < proj->reservoirs().size(); ++i) { - RimReservoir* ri = proj->reservoirs()[i]; + RimCase* ri = proj->reservoirs()[i]; if (!ri) continue; size_t j; @@ -976,8 +996,8 @@ void RIMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) riv->viewer()->layoutWidget() && riv->viewer()->layoutWidget()->parent() == subWindow) { - RimReservoirView* previousActiveReservoirView = RIApplication::instance()->activeReservoirView(); - RIApplication::instance()->setActiveReservoirView(riv); + RimReservoirView* previousActiveReservoirView = RiaApplication::instance()->activeReservoirView(); + RiaApplication::instance()->setActiveReservoirView(riv); if (previousActiveReservoirView && previousActiveReservoirView != riv) { QModelIndex previousViewModelIndex = m_treeModelPdm->getModelIndexFromPdmObject(previousActiveReservoirView); @@ -1037,34 +1057,34 @@ void RIMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotUseShaders(bool enable) +void RiuMainWindow::slotUseShaders(bool enable) { - RIApplication::instance()->setUseShaders(enable); + RiaApplication::instance()->setUseShaders(enable); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotShowPerformanceInfo(bool enable) +void RiuMainWindow::slotShowPerformanceInfo(bool enable) { - RIApplication::instance()->setShowPerformanceInfo(enable); + RiaApplication::instance()->setShowPerformanceInfo(enable); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotRefreshDebugActions() +void RiuMainWindow::slotRefreshDebugActions() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotEditPreferences() +void RiuMainWindow::slotEditPreferences() { - RIApplication* app = RIApplication::instance(); - RIPreferencesDialog preferencesDialog(this, app->preferences(), "Preferences"); + RiaApplication* app = RiaApplication::instance(); + RiuPreferencesDialog preferencesDialog(this, app->preferences(), "Preferences"); if (preferencesDialog.exec() == QDialog::Accepted) { // Write preferences using QSettings and apply them to the application @@ -1081,7 +1101,7 @@ void RIMainWindow::slotEditPreferences() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::setActiveViewer(RIViewer* viewer) +void RiuMainWindow::setActiveViewer(RiuViewer* viewer) { QMdiSubWindow * swin = findMdiSubWindow(viewer); if (swin) m_mdiArea->setActiveSubWindow(swin); @@ -1090,18 +1110,18 @@ void RIMainWindow::setActiveViewer(RIViewer* viewer) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotFramerateChanged(double frameRate) +void RiuMainWindow::slotFramerateChanged(double frameRate) { - if (RIApplication::instance()->activeReservoirView() != NULL) + if (RiaApplication::instance()->activeReservoirView() != NULL) { - RIApplication::instance()->activeReservoirView()->maximumFrameRate.setValueFromUi(QVariant(frameRate)); + RiaApplication::instance()->activeReservoirView()->maximumFrameRate.setValueFromUi(QVariant(frameRate)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIProcessMonitor* RIMainWindow::processMonitor() +RiuProcessMonitor* RiuMainWindow::processMonitor() { return m_processMonitor; } @@ -1109,7 +1129,7 @@ RIProcessMonitor* RIMainWindow::processMonitor() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotBuildWindowActions() +void RiuMainWindow::slotBuildWindowActions() { m_windowMenu->clear(); @@ -1126,9 +1146,9 @@ void RIMainWindow::slotBuildWindowActions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous) +void RiuMainWindow::slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous) { - RimReservoirView* activeReservoirView = RIApplication::instance()->activeReservoirView(); + RimReservoirView* activeReservoirView = RiaApplication::instance()->activeReservoirView(); QModelIndex activeViewModelIndex = m_treeModelPdm->getModelIndexFromPdmObject(activeReservoirView); QModelIndex tmp = current; @@ -1146,7 +1166,7 @@ void RIMainWindow::slotCurrentChanged(const QModelIndex & current, const QModelI // show new reservoir view and set this as activate view if (rimReservoirView != activeReservoirView) { - RIApplication::instance()->setActiveReservoirView(rimReservoirView); + RiaApplication::instance()->setActiveReservoirView(rimReservoirView); // Set focus in MDI area to this window if it exists if (rimReservoirView->viewer()) @@ -1172,7 +1192,7 @@ void RIMainWindow::slotCurrentChanged(const QModelIndex & current, const QModelI //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotNewObjectPropertyView() +void RiuMainWindow::slotNewObjectPropertyView() { if (!m_treeModelPdm) return; @@ -1210,9 +1230,9 @@ void RIMainWindow::slotNewObjectPropertyView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSnapshotToFile() +void RiuMainWindow::slotSnapshotToFile() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->saveSnapshotPromtpForFilename(); } @@ -1220,9 +1240,9 @@ void RIMainWindow::slotSnapshotToFile() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSnapshotToClipboard() +void RiuMainWindow::slotSnapshotToClipboard() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->copySnapshotToClipboard(); } @@ -1230,9 +1250,9 @@ void RIMainWindow::slotSnapshotToClipboard() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSnapshotAllViewsToFile() +void RiuMainWindow::slotSnapshotAllViewsToFile() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->saveSnapshotForAllViews("snapshots"); } @@ -1240,7 +1260,7 @@ void RIMainWindow::slotSnapshotAllViewsToFile() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::hideAllDockWindows() +void RiuMainWindow::hideAllDockWindows() { QList dockWidgets = findChildren(); @@ -1249,3 +1269,43 @@ void RIMainWindow::hideAllDockWindows() dockWidgets[i]->close(); } } + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::slotOpenMultipleCases() +{ +#if 1 + RiaApplication* app = RiaApplication::instance(); + RiuMultiCaseImportDialog dialog; + int action = dialog.exec(); + if (action == QDialog::Accepted) + { + QStringList gridFileNames = dialog.eclipseCaseFileNames(); + app->addEclipseCases(gridFileNames); + } + +#else // Code to fast generate a test project + RiaApplication* app = RiaApplication::instance(); + + QStringList gridFileNames; + + if (1) + { + gridFileNames += "Result Mock Debug Model With Results"; + gridFileNames += "Result Mock Debug Model With Results"; + gridFileNames += "Result Mock Debug Model With Results"; + } + else + { + gridFileNames += "d:/Models/Statoil/MultipleRealisations/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID"; + gridFileNames += "d:/Models/Statoil/MultipleRealisations/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID"; + gridFileNames += "d:/Models/Statoil/MultipleRealisations/Case_with_10_timesteps/Real30/BRUGGE_0030.EGRID"; + gridFileNames += "d:/Models/Statoil/MultipleRealisations/Case_with_10_timesteps/Real40/BRUGGE_0040.EGRID"; + } + + app->addEclipseCases(gridFileNames); +#endif + +} diff --git a/ApplicationCode/UserInterface/RIMainWindow.h b/ApplicationCode/UserInterface/RiuMainWindow.h similarity index 89% rename from ApplicationCode/UserInterface/RIMainWindow.h rename to ApplicationCode/UserInterface/RiuMainWindow.h index 0f133900bd..463599aa36 100644 --- a/ApplicationCode/UserInterface/RIMainWindow.h +++ b/ApplicationCode/UserInterface/RiuMainWindow.h @@ -32,9 +32,9 @@ class QLabel; class QLineEdit; class QItemSelection; -class RIViewer; -class RIResultInfoPanel; -class RIProcessMonitor; +class RiuViewer; +class RiuResultInfoPanel; +class RiuProcessMonitor; class RimUiTreeModelPdm; namespace caf @@ -52,13 +52,13 @@ namespace caf // // //================================================================================================== -class RIMainWindow : public QMainWindow +class RiuMainWindow : public QMainWindow { Q_OBJECT public: - RIMainWindow(); - static RIMainWindow* instance(); + RiuMainWindow(); + static RiuMainWindow* instance(); void initializeGuiNewProjectLoaded(); void cleanupGuiBeforeProjectClose(); @@ -66,9 +66,9 @@ public: void refreshGuiLightweight(); void refreshToolbars(); - void removeViewer( RIViewer* viewer ); - void addViewer(RIViewer* viewer); - void setActiveViewer(RIViewer* subWindow); + void removeViewer( RiuViewer* viewer ); + void addViewer(RiuViewer* viewer); + void setActiveViewer(RiuViewer* subWindow); void setResultInfo(const QString& info) const; @@ -76,7 +76,7 @@ public: RimUiTreeModelPdm* uiPdmModel() { return m_treeModelPdm;} - RIProcessMonitor* processMonitor(); + RiuProcessMonitor* processMonitor(); void hideAllDockWindows(); @@ -95,10 +95,10 @@ private: void updateMRUList(const QString &fileName, bool remove = false); - QMdiSubWindow* findMdiSubWindow(RIViewer* viewer); + QMdiSubWindow* findMdiSubWindow(RiuViewer* viewer); private: - static RIMainWindow* sm_mainWindowInstance; + static RiuMainWindow* sm_mainWindowInstance; QByteArray m_initialDockAndToolbarLayout; // Initial dock window and toolbar layout, used to reset GUI @@ -106,6 +106,7 @@ private: // File actions QAction* m_openAction; QAction* m_openInputEclipseFileAction; + QAction* m_openMultipleEclipseCasesAction; QAction* m_openProjectAction; QAction* m_openLastUsedProjectAction; QAction* m_saveProjectAction; @@ -149,9 +150,9 @@ private: QFrame* m_CentralFrame; QMdiArea* m_mdiArea; - RIViewer* m_mainViewer; - RIResultInfoPanel* m_resultInfoPanel; - RIProcessMonitor* m_processMonitor; + RiuViewer* m_mainViewer; + RiuResultInfoPanel* m_resultInfoPanel; + RiuProcessMonitor* m_processMonitor; QMenu* m_windowMenu; @@ -162,6 +163,7 @@ private slots: // File slots void slotOpenBinaryGridFiles(); void slotOpenInputFiles(); + void slotOpenMultipleCases(); void slotOpenProject(); void slotOpenLastUsedProject(); void slotSaveProject(); diff --git a/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.cpp b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.cpp new file mode 100644 index 0000000000..e6014f07a1 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.cpp @@ -0,0 +1,262 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RiuMultiCaseImportDialog.h" +#include "ui_RiuMultiCaseImportDialog.h" +#include +#include +#include +#include +#include "RiaApplication.h" + +class FileListModel: public QStringListModel +{ +public: + FileListModel(QObject *parent = 0) : m_isItemsEditable(false), QStringListModel(parent) + { + } + + virtual Qt::ItemFlags flags (const QModelIndex& index) const + { + if (m_isItemsEditable) + return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; + else + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; + } + + virtual QVariant data ( const QModelIndex & index, int role ) const + { + if (role == Qt::DecorationRole) + { + QFileInfo fileInfo(stringList()[index.row()]); + QFileIconProvider iconProv; + return QVariant(iconProv.icon(fileInfo)); + } + else + { + return QStringListModel::data(index, role); + } + } + + + void setItemsEditable(bool isEditable) + { + m_isItemsEditable = isEditable; + } + +private: + bool m_isItemsEditable; +}; + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuMultiCaseImportDialog::RiuMultiCaseImportDialog(QWidget *parent /*= 0*/) + : QDialog(parent) +{ + ui = new Ui::RiuMultiCaseImportDialog; + ui->setupUi(this); + + m_searchFolders = new FileListModel(this); + ui->m_searchFolderList->setModel(m_searchFolders); + + m_eclipseGridFiles = new FileListModel(this); + ui->m_eclipseCasesList->setModel(m_eclipseGridFiles); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuMultiCaseImportDialog::~RiuMultiCaseImportDialog() +{ + delete ui; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMultiCaseImportDialog::on_m_addSearchFolderButton_clicked() +{ + QString selectedFolder = QFileDialog::getExistingDirectory(this, "Select an Eclipse case search folder", RiaApplication::instance()->defaultFileDialogDirectory("MULTICASEIMPORT")); + QStringList folderNames = m_searchFolders->stringList(); + + if (!folderNames.contains(selectedFolder)) + { + folderNames.push_back(selectedFolder); + m_searchFolders->setStringList(folderNames); + updateGridFileList(); + } + + RiaApplication::instance()->setDefaultFileDialogDirectory("MULTICASEIMPORT", selectedFolder); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMultiCaseImportDialog::on_m_removeSearchFolderButton_clicked() +{ + QModelIndexList selection = ui->m_searchFolderList->selectionModel()->selectedIndexes(); + QStringList folderNames = m_searchFolders->stringList(); + + QStringList searchFoldersToRemove; + + for (int i = 0; i < selection.size(); ++i) + { + searchFoldersToRemove.push_back(folderNames[selection[i].row()]); + } + + for (int i = 0; i < searchFoldersToRemove.size(); ++i) + { + folderNames.removeOne(searchFoldersToRemove[i]); + } + + m_searchFolders->setStringList(folderNames); + + if (selection.size()) + { + updateGridFileList(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMultiCaseImportDialog::updateGridFileList() +{ + + QStringList folderNames = m_searchFolders->stringList(); + QStringList gridFileNames; + + + // Filter the search folders to remove subfolders of existing roots' + + bool okToAdd = true; + QStringList searchFoldersToRemove; + + for (int i = 0; i < folderNames.size(); ++i) + for (int j = 0; j < folderNames.size(); ++j) + { + if ( i != j) + { + if (folderNames[i].startsWith(folderNames[j])) + { + // Remove folderNames[i] + searchFoldersToRemove.push_back(folderNames[i]); + } + } + } + + // Remove the subfolders when adding a root + + for (int i = 0; i < searchFoldersToRemove.size(); ++i) + { + folderNames.removeOne(searchFoldersToRemove[i]); + } + + for (int i = 0; i < folderNames.size(); i++) + { + QString folderName = folderNames[i]; + + appendEGRIDFilesRecursively(folderName, gridFileNames); + } + + m_eclipseGridFiles->setStringList(gridFileNames); +} + + +void RiuMultiCaseImportDialog::appendEGRIDFilesRecursively(const QString& folderName, QStringList& gridFileNames) +{ + { + QDir baseDir(folderName); + baseDir.setFilter(QDir::Files); + + QStringList nameFilters; + nameFilters << "*.egrid" << ".EGRID"; + baseDir.setNameFilters(nameFilters); + + QStringList fileNames = baseDir.entryList(); + + for (int i = 0; i < fileNames.size(); ++i) + { + QString fileName = fileNames[i]; + + QString absoluteFolderName = baseDir.absoluteFilePath(fileName); + + gridFileNames.append(absoluteFolderName); + } + } + + + { + QDir baseDir(folderName); + baseDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); + + QStringList subFolders = baseDir.entryList(); + + for (int i = 0; i < subFolders.size(); ++i) + { + QString folderName = subFolders[i]; + + QString absoluteFolderName = baseDir.absoluteFilePath(folderName); + appendEGRIDFilesRecursively(absoluteFolderName, gridFileNames); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RiuMultiCaseImportDialog::eclipseCaseFileNames() const +{ + return m_eclipseGridFiles->stringList(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMultiCaseImportDialog::on_m_removeEclipseCaseButton_clicked() +{ + QModelIndexList selection = ui->m_eclipseCasesList->selectionModel()->selectedIndexes(); + if (selection.size()) + { + for (int i = 0; i < selection.size(); ++i) + { + ui->m_eclipseCasesList->model()->removeRow(selection[i].row(), selection[i].parent()); + } + + QModelIndexList selection = ui->m_eclipseCasesList->selectionModel()->selectedIndexes(); + QStringList fileNames = m_eclipseGridFiles->stringList(); + + QStringList filenamesToRemove; + + for (int i = 0; i < selection.size(); ++i) + { + filenamesToRemove.push_back(fileNames[selection[i].row()]); + } + + for (int i = 0; i < filenamesToRemove.size(); ++i) + { + fileNames.removeOne(filenamesToRemove[i]); + } + + m_eclipseGridFiles->setStringList(fileNames); + } +} diff --git a/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.h b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.h new file mode 100644 index 0000000000..815628d147 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +namespace Ui { + class RiuMultiCaseImportDialog; +}; + +class FileListModel; + +//================================================================================================== +// +// +// +//================================================================================================== + +class RiuMultiCaseImportDialog: public QDialog +{ + Q_OBJECT + +public: + RiuMultiCaseImportDialog(QWidget *parent = 0); + virtual ~RiuMultiCaseImportDialog(); + + QStringList eclipseCaseFileNames() const; + +protected slots: + void on_m_addSearchFolderButton_clicked(); + void on_m_removeSearchFolderButton_clicked(); + void on_m_removeEclipseCaseButton_clicked(); +private: + void updateGridFileList(); + static void appendEGRIDFilesRecursively(const QString& folderName, QStringList& gridFileNames); + Ui::RiuMultiCaseImportDialog* ui; + + FileListModel *m_searchFolders; + FileListModel *m_eclipseGridFiles; +}; diff --git a/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.ui b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.ui new file mode 100644 index 0000000000..ca27248841 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.ui @@ -0,0 +1,186 @@ + + + RiuMultiCaseImportDialog + + + + 0 + 0 + 755 + 736 + + + + Create Grid Case Group From Files + + + true + + + + + + Qt::Horizontal + + + + + + + QAbstractItemView::ExtendedSelection + + + + + + + Remove + + + + + + + Add + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Search Folders + + + + + + + Qt::Vertical + + + + 20 + 222 + + + + + + + + + + + + + 0 + 0 + + + + QAbstractItemView::ExtendedSelection + + + + + + + Selected Eclipse Cases + + + + + + + Remove + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 400 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + m_dialogButtons + accepted() + RiuMultiCaseImportDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + m_dialogButtons + rejected() + RiuMultiCaseImportDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/ApplicationCode/UserInterface/RIPreferencesDialog.cpp b/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp similarity index 90% rename from ApplicationCode/UserInterface/RIPreferencesDialog.cpp rename to ApplicationCode/UserInterface/RiuPreferencesDialog.cpp index c77785a99d..7a094776c8 100644 --- a/ApplicationCode/UserInterface/RIPreferencesDialog.cpp +++ b/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp @@ -16,8 +16,8 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RIPreferencesDialog.h" +#include "RiaStdInclude.h" +#include "RiuPreferencesDialog.h" #include "cafAppEnum.h" #include "cafPdmObject.h" @@ -30,7 +30,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIPreferencesDialog::RIPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle) +RiuPreferencesDialog::RiuPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle) : QDialog(parent) { CVF_ASSERT(object); @@ -44,7 +44,7 @@ RIPreferencesDialog::RIPreferencesDialog(QWidget* parent, caf::PdmObject* object //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIPreferencesDialog::setupUi() +void RiuPreferencesDialog::setupUi() { setWindowTitle(m_windowTitle); diff --git a/ApplicationCode/UserInterface/RIPreferencesDialog.h b/ApplicationCode/UserInterface/RiuPreferencesDialog.h similarity index 90% rename from ApplicationCode/UserInterface/RIPreferencesDialog.h rename to ApplicationCode/UserInterface/RiuPreferencesDialog.h index b33c4924d2..3751e108fb 100644 --- a/ApplicationCode/UserInterface/RIPreferencesDialog.h +++ b/ApplicationCode/UserInterface/RiuPreferencesDialog.h @@ -32,12 +32,12 @@ namespace caf // // //================================================================================================== -class RIPreferencesDialog : public QDialog +class RiuPreferencesDialog : public QDialog { Q_OBJECT public: - RIPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle); + RiuPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle); private: void setupUi(); diff --git a/ApplicationCode/UserInterface/RIProcessMonitor.cpp b/ApplicationCode/UserInterface/RiuProcessMonitor.cpp similarity index 89% rename from ApplicationCode/UserInterface/RIProcessMonitor.cpp rename to ApplicationCode/UserInterface/RiuProcessMonitor.cpp index c46a6a3fc9..4c4396954b 100644 --- a/ApplicationCode/UserInterface/RIProcessMonitor.cpp +++ b/ApplicationCode/UserInterface/RiuProcessMonitor.cpp @@ -16,17 +16,17 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" -#include "RIProcessMonitor.h" +#include "RiuProcessMonitor.h" #include "cafUiProcess.h" -#include "RIApplication.h" +#include "RiaApplication.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIProcessMonitor::RIProcessMonitor(QDockWidget* pParent) +RiuProcessMonitor::RiuProcessMonitor(QDockWidget* pParent) : QWidget(pParent) { m_monitoredProcess = NULL; @@ -70,7 +70,7 @@ RIProcessMonitor::RIProcessMonitor(QDockWidget* pParent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIProcessMonitor::~RIProcessMonitor() +RiuProcessMonitor::~RiuProcessMonitor() { } @@ -79,7 +79,7 @@ RIProcessMonitor::~RIProcessMonitor() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::startMonitorWorkProcess(caf::UiProcess* pProcess) +void RiuProcessMonitor::startMonitorWorkProcess(caf::UiProcess* pProcess) { setStatusMsg("N/A", caf::PROCESS_STATE_NORMAL); @@ -102,7 +102,7 @@ void RIProcessMonitor::startMonitorWorkProcess(caf::UiProcess* pProcess) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::stopMonitorWorkProcess() +void RiuProcessMonitor::stopMonitorWorkProcess() { m_monitoredProcess = NULL; @@ -118,7 +118,7 @@ void RIProcessMonitor::stopMonitorWorkProcess() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::setStatusMsg(const QString& sStatusMsg, int iStatusMsgType) +void RiuProcessMonitor::setStatusMsg(const QString& sStatusMsg, int iStatusMsgType) { if (!m_labelStatus) return; @@ -138,7 +138,7 @@ void RIProcessMonitor::setStatusMsg(const QString& sStatusMsg, int iStatusMsgTyp //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::addStringToLog(const QString& sTxt) +void RiuProcessMonitor::addStringToLog(const QString& sTxt) { m_textEdit->moveCursor(QTextCursor::End); m_textEdit->insertPlainText(sTxt); @@ -150,7 +150,7 @@ void RIProcessMonitor::addStringToLog(const QString& sTxt) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::slotShowProcStatusMsg(const QString& sMsg, int iStatusMsgType) +void RiuProcessMonitor::slotShowProcStatusMsg(const QString& sMsg, int iStatusMsgType) { setStatusMsg(sMsg, iStatusMsgType); } @@ -159,7 +159,7 @@ void RIProcessMonitor::slotShowProcStatusMsg(const QString& sMsg, int iStatusMsg //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::slotProcReadyReadStdOut() +void RiuProcessMonitor::slotProcReadyReadStdOut() { if (!m_monitoredProcess) return; @@ -174,7 +174,7 @@ void RIProcessMonitor::slotProcReadyReadStdOut() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::slotProcReadyReadStdErr() +void RiuProcessMonitor::slotProcReadyReadStdErr() { if (!m_monitoredProcess) return; @@ -188,18 +188,18 @@ void RIProcessMonitor::slotProcReadyReadStdErr() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::slotTerminateProcess() +void RiuProcessMonitor::slotTerminateProcess() { addStringToLog("Process terminated by user\n"); - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->terminateProcess(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::slotClearTextEdit() +void RiuProcessMonitor::slotClearTextEdit() { m_textEdit->clear(); } diff --git a/ApplicationCode/UserInterface/RIProcessMonitor.h b/ApplicationCode/UserInterface/RiuProcessMonitor.h similarity index 94% rename from ApplicationCode/UserInterface/RIProcessMonitor.h rename to ApplicationCode/UserInterface/RiuProcessMonitor.h index 7a421ac1e0..8a58d66ca2 100644 --- a/ApplicationCode/UserInterface/RIProcessMonitor.h +++ b/ApplicationCode/UserInterface/RiuProcessMonitor.h @@ -34,7 +34,7 @@ namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -class RIProcessMonitor : public QWidget +class RiuProcessMonitor : public QWidget { Q_OBJECT @@ -46,8 +46,8 @@ private: caf::UiProcess* m_monitoredProcess; // Pointer to the process we're monitoring. Needed to fetch text public: - RIProcessMonitor(QDockWidget* pParent); - ~RIProcessMonitor(); + RiuProcessMonitor(QDockWidget* pParent); + ~RiuProcessMonitor(); void startMonitorWorkProcess(caf::UiProcess* process); void stopMonitorWorkProcess(); diff --git a/ApplicationCode/UserInterface/RIResultInfoPanel.cpp b/ApplicationCode/UserInterface/RiuResultInfoPanel.cpp similarity index 88% rename from ApplicationCode/UserInterface/RIResultInfoPanel.cpp rename to ApplicationCode/UserInterface/RiuResultInfoPanel.cpp index 56ac7195ca..124f96f632 100644 --- a/ApplicationCode/UserInterface/RIResultInfoPanel.cpp +++ b/ApplicationCode/UserInterface/RiuResultInfoPanel.cpp @@ -16,14 +16,14 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RIResultInfoPanel.h" +#include "RiaStdInclude.h" +#include "RiuResultInfoPanel.h" //================================================================================================== /// -/// \class RIResultInfoPanel +/// \class RiuResultInfoPanel /// \ingroup ResInsight /// /// @@ -33,7 +33,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIResultInfoPanel::RIResultInfoPanel(QDockWidget* parent) +RiuResultInfoPanel::RiuResultInfoPanel(QDockWidget* parent) : QWidget(parent) { m_textEdit = new QTextEdit(this); @@ -49,7 +49,7 @@ RIResultInfoPanel::RIResultInfoPanel(QDockWidget* parent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIResultInfoPanel::setInfo(const QString& info) +void RiuResultInfoPanel::setInfo(const QString& info) { QString tmp(info); @@ -62,7 +62,7 @@ void RIResultInfoPanel::setInfo(const QString& info) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIResultInfoPanel::convertStringToHTML(QString* str) +void RiuResultInfoPanel::convertStringToHTML(QString* str) { str->replace("\n", "
"); str->replace(" ", " "); @@ -72,7 +72,7 @@ void RIResultInfoPanel::convertStringToHTML(QString* str) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QSize RIResultInfoPanel::sizeHint () const +QSize RiuResultInfoPanel::sizeHint () const { // As small as possible fow now return QSize(20, 20); diff --git a/ApplicationCode/UserInterface/RIResultInfoPanel.h b/ApplicationCode/UserInterface/RiuResultInfoPanel.h similarity index 92% rename from ApplicationCode/UserInterface/RIResultInfoPanel.h rename to ApplicationCode/UserInterface/RiuResultInfoPanel.h index 3c753b3e86..9ee0ba1b24 100644 --- a/ApplicationCode/UserInterface/RIResultInfoPanel.h +++ b/ApplicationCode/UserInterface/RiuResultInfoPanel.h @@ -27,15 +27,15 @@ class QTextEdit; //================================================================================================== // -// RIResultInfoPanel +// RiuResultInfoPanel // //================================================================================================== -class RIResultInfoPanel : public QWidget +class RiuResultInfoPanel : public QWidget { Q_OBJECT public: - RIResultInfoPanel(QDockWidget* parent); + RiuResultInfoPanel(QDockWidget* parent); void setInfo(const QString& info); diff --git a/ApplicationCode/UserInterface/RIViewer.cpp b/ApplicationCode/UserInterface/RiuViewer.cpp similarity index 86% rename from ApplicationCode/UserInterface/RIViewer.cpp rename to ApplicationCode/UserInterface/RiuViewer.cpp index f612fc6aee..551f86df9e 100644 --- a/ApplicationCode/UserInterface/RIViewer.cpp +++ b/ApplicationCode/UserInterface/RiuViewer.cpp @@ -16,19 +16,19 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" -#include "RIViewer.h" -#include "RIApplication.h" -#include "RIMainWindow.h" +#include "RiuViewer.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" #include "cvfqtOpenGLContext.h" #include "cvfqtPerformanceInfoHud.h" #include "cvfCamera.h" #include "cvfRendering.h" #include "cvfDrawableGeo.h" -#include "RICursors.h" -#include "RigReservoir.h" +#include "RiuCursors.h" +#include "RigCaseData.h" #include "cafUtils.h" #include "cafFrameAnimationControl.h" @@ -44,7 +44,7 @@ const double RI_MIN_NEARPLANE_DISTANCE = 0.1; //================================================================================================== /// -/// \class RIViewer +/// \class RiuViewer /// \ingroup ResInsight /// /// @@ -54,7 +54,7 @@ const double RI_MIN_NEARPLANE_DISTANCE = 0.1; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIViewer::RIViewer(const QGLFormat& format, QWidget* parent) +RiuViewer::RiuViewer(const QGLFormat& format, QWidget* parent) : caf::Viewer(format, parent) { cvf::FixedAtlasFont* font = new cvf::FixedAtlasFont(cvf::FixedAtlasFont::STANDARD); @@ -62,12 +62,18 @@ RIViewer::RIViewer(const QGLFormat& format, QWidget* parent) axisCross->setAxisLabels("E", "N", "Z"); m_mainRendering->addOverlayItem(axisCross, cvf::OverlayItem::BOTTOM_LEFT, cvf::OverlayItem::VERTICAL); - setReleaseOGLResourcesEachFrame(true); + this->enableOverlyPainting(true); + this->setReleaseOGLResourcesEachFrame(true); QColor c; QPalette p = QApplication::palette(); - QColor frameAndTextColor(255, 255, 255, 200); - p.setColor(QPalette::Window, QColor(144, 173, 208, 180)); + //QColor frameAndTextColor(255, 255, 255, 255); + QColor frameAndTextColor(0, 0, 0, 255); + QColor progressAndHistogramColor(0,0,90,70); // Also Progressbar dark text color + + //p.setColor(QPalette::Window, QColor(144, 173, 208, 180)); + p.setColor(QPalette::Window, QColor(255, 255, 255, 50)); + p.setColor(QPalette::WindowText, frameAndTextColor); c = p.color(QPalette::Base ); @@ -79,11 +85,14 @@ RIViewer::RIViewer(const QGLFormat& format, QWidget* parent) //p.setColor(QPalette::AlternateBase, c); - p.setColor(QPalette::Highlight, QColor(20, 20, 130, 100)); + //p.setColor(QPalette::Highlight, QColor(20, 20, 130, 40)); + p.setColor(QPalette::Highlight, progressAndHistogramColor); - p.setColor(QPalette::HighlightedText, frameAndTextColor); + //p.setColor(QPalette::HighlightedText, frameAndTextColor); + p.setColor(QPalette::HighlightedText, QColor(255, 255, 255, 255)); //Progressbar light text color - p.setColor(QPalette::Dark, QColor(230, 250, 255, 100)); + //p.setColor(QPalette::Dark, QColor(230, 250, 255, 100)); + p.setColor(QPalette::Dark, progressAndHistogramColor); // Info Text m_InfoLabel = new QLabel(); @@ -112,7 +121,7 @@ RIViewer::RIViewer(const QGLFormat& format, QWidget* parent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIViewer::~RIViewer() +RiuViewer::~RiuViewer() { m_reservoirView->showWindow = false; m_reservoirView->cameraPosition = m_mainCamera->viewMatrix(); @@ -127,7 +136,7 @@ RIViewer::~RIViewer() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setColorLegend1(cvf::OverlayScalarMapperLegend* legend) +void RiuViewer::setColorLegend1(cvf::OverlayScalarMapperLegend* legend) { m_mainRendering->removeOverlayItem(m_legend1.p()); @@ -140,7 +149,7 @@ void RIViewer::setColorLegend1(cvf::OverlayScalarMapperLegend* legend) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setColorLegend2(cvf::OverlayScalarMapperLegend* legend) +void RiuViewer::setColorLegend2(cvf::OverlayScalarMapperLegend* legend) { m_mainRendering->removeOverlayItem(m_legend2.p()); @@ -152,7 +161,7 @@ void RIViewer::setColorLegend2(cvf::OverlayScalarMapperLegend* legend) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::updateLegends() +void RiuViewer::updateLegends() { cvf::Rendering* firstRendering = m_renderingSequence->firstRendering(); CVF_ASSERT(firstRendering); @@ -174,7 +183,7 @@ void RIViewer::updateLegends() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setDefaultView() +void RiuViewer::setDefaultView() { cvf::BoundingBox bb; @@ -210,7 +219,7 @@ void RIViewer::setDefaultView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::mouseReleaseEvent(QMouseEvent* event) +void RiuViewer::mouseReleaseEvent(QMouseEvent* event) { m_mouseState.updateFromMouseEvent(event); @@ -218,7 +227,7 @@ void RIViewer::mouseReleaseEvent(QMouseEvent* event) // Get the currently set button press action // We get it here since left click performs it, while we let a clean right click cancel it - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); // Picking if (event->button() == Qt::LeftButton) @@ -232,7 +241,7 @@ void RIViewer::mouseReleaseEvent(QMouseEvent* event) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::keyPressEvent(QKeyEvent* event) +void RiuViewer::keyPressEvent(QKeyEvent* event) { // Trap escape key so we can get out of direct button press actions if (event->key() == Qt::Key_Escape) @@ -245,11 +254,11 @@ void RIViewer::keyPressEvent(QKeyEvent* event) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::handlePickAction(int winPosX, int winPosY) +void RiuViewer::handlePickAction(int winPosX, int winPosY) { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); if (!mainWnd) return; QString pickInfo = "No hits"; @@ -309,7 +318,7 @@ void RIViewer::handlePickAction(int winPosX, int winPosY) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::slotEndAnimation() +void RiuViewer::slotEndAnimation() { cvf::Rendering* firstRendering = m_renderingSequence->firstRendering(); CVF_ASSERT(firstRendering); @@ -327,7 +336,7 @@ void RIViewer::slotEndAnimation() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::slotSetCurrentFrame(int frameIndex) +void RiuViewer::slotSetCurrentFrame(int frameIndex) { cvf::Rendering* firstRendering = m_renderingSequence->firstRendering(); CVF_ASSERT(firstRendering); @@ -342,7 +351,7 @@ void RIViewer::slotSetCurrentFrame(int frameIndex) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::Vec3d RIViewer::pointOfInterest() +cvf::Vec3d RiuViewer::pointOfInterest() { return m_navigationPolicy->pointOfInterest(); } @@ -350,7 +359,7 @@ cvf::Vec3d RIViewer::pointOfInterest() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setPointOfInterest(cvf::Vec3d poi) +void RiuViewer::setPointOfInterest(cvf::Vec3d poi) { m_navigationPolicy->setPointOfInterest(poi); } @@ -358,7 +367,7 @@ void RIViewer::setPointOfInterest(cvf::Vec3d poi) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setOwnerReservoirView(RimReservoirView * owner) +void RiuViewer::setOwnerReservoirView(RimReservoirView * owner) { m_reservoirView = owner; } @@ -366,7 +375,7 @@ void RIViewer::setOwnerReservoirView(RimReservoirView * owner) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setEnableMask(unsigned int mask) +void RiuViewer::setEnableMask(unsigned int mask) { m_mainRendering->setEnableMask(mask); } @@ -374,7 +383,7 @@ void RIViewer::setEnableMask(unsigned int mask) //-------------------------------------------------------------------------------------------------- /// Perform picking and return the index of the face that was hit, if a drawable geo was hit //-------------------------------------------------------------------------------------------------- -cvf::Part* RIViewer::pickPointAndFace(int winPosX, int winPosY, uint* faceHit, cvf::Vec3d* localIntersectionPoint) +cvf::Part* RiuViewer::pickPointAndFace(int winPosX, int winPosY, uint* faceHit, cvf::Vec3d* localIntersectionPoint) { CVF_ASSERT(faceHit); @@ -424,13 +433,13 @@ cvf::Part* RIViewer::pickPointAndFace(int winPosX, int winPosY, uint* faceHit, c //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::paintOverlayItems(QPainter* painter) +void RiuViewer::paintOverlayItems(QPainter* painter) { // No support for overlay items using SW rendering yet. - if (!isShadersSupported()) - { - return; - } + //if (!isShadersSupported()) + //{ + // return; + //} int columnWidth = 200; int margin = 5; @@ -474,7 +483,7 @@ void RIViewer::paintOverlayItems(QPainter* painter) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setInfoText(QString text) +void RiuViewer::setInfoText(QString text) { m_InfoLabel->setText(text); } @@ -482,7 +491,7 @@ void RIViewer::setInfoText(QString text) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::showInfoText(bool enable) +void RiuViewer::showInfoText(bool enable) { m_showInfoText = enable; } @@ -490,7 +499,7 @@ void RIViewer::showInfoText(bool enable) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setHistogram(double min, double max, const std::vector& histogram) +void RiuViewer::setHistogram(double min, double max, const std::vector& histogram) { m_histogramWidget->setHistogramData(min, max, histogram); } @@ -498,7 +507,7 @@ void RIViewer::setHistogram(double min, double max, const std::vector& h //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setHistogramPercentiles(double pmin, double pmax, double mean) +void RiuViewer::setHistogramPercentiles(double pmin, double pmax, double mean) { m_histogramWidget->setPercentiles(pmin, pmax); m_histogramWidget->setMean(mean); @@ -507,7 +516,7 @@ void RIViewer::setHistogramPercentiles(double pmin, double pmax, double mean) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::showAnimationProgress(bool enable) +void RiuViewer::showAnimationProgress(bool enable) { m_showAnimProgress = enable; } @@ -515,7 +524,7 @@ void RIViewer::showAnimationProgress(bool enable) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::showHistogram(bool enable) +void RiuViewer::showHistogram(bool enable) { m_showHistogram = enable; } diff --git a/ApplicationCode/UserInterface/RIViewer.h b/ApplicationCode/UserInterface/RiuViewer.h similarity index 96% rename from ApplicationCode/UserInterface/RIViewer.h rename to ApplicationCode/UserInterface/RiuViewer.h index b09ce90448..71c7b32790 100644 --- a/ApplicationCode/UserInterface/RIViewer.h +++ b/ApplicationCode/UserInterface/RiuViewer.h @@ -38,16 +38,16 @@ namespace cvf //================================================================================================== // -// RIViewer +// RiuViewer // //================================================================================================== -class RIViewer : public caf::Viewer +class RiuViewer : public caf::Viewer { Q_OBJECT public: - RIViewer(const QGLFormat& format, QWidget* parent); - ~RIViewer(); + RiuViewer(const QGLFormat& format, QWidget* parent); + ~RiuViewer(); void setColorLegend1(cvf::OverlayScalarMapperLegend* legend); void setColorLegend2(cvf::OverlayScalarMapperLegend* legend); @@ -95,6 +95,7 @@ private: cvf::ref m_legend1; cvf::ref m_legend2; + caf::PdmPointer m_reservoirView; }; diff --git a/CMakeLists.txt b/CMakeLists.txt index e09c59183a..d99ac20fb8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ project (ResInsight) set (VIZ_MODULES_FOLDER_NAME VisualizationModules) + # Setup the main platform defines #----------------------------------------------------- if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -37,6 +38,11 @@ include (ResInsightVersion.cmake) ################################################################################ # ERT ################################################################################ + +# Disable install of ERT libs and headers, as Ert code is compiled and linked directly +# into ResInsight +SET(INSTALL_ERT OFF CACHE BOOL "Build ERT without installing") + add_subdirectory(ThirdParty/Ert/devel) include_directories( diff --git a/CommonCode/cvfStructGrid.cpp b/CommonCode/cvfStructGrid.cpp index 6cc7830321..a268228b9a 100644 --- a/CommonCode/cvfStructGrid.cpp +++ b/CommonCode/cvfStructGrid.cpp @@ -230,25 +230,25 @@ void StructGridInterface::characteristicCellSizes(double* iSize, double* jSize, size_t i; for (i = 0; i < cellCountI(); i += 10) // NB! Evaluate every n-th cell { - if (isCellActive(i, j, k)) + if (isCellValid(i, j, k)) { size_t cellIndex = cellIndexFromIJK(i, j, k); cellCornerVertices(cellIndex, cornerVerts); iSize += (cornerVerts[faceConnPosI[0]] - cornerVerts[faceConnNegI[0]]).lengthSquared(); - iSize += (cornerVerts[faceConnPosI[1]] - cornerVerts[faceConnNegI[1]]).lengthSquared(); + iSize += (cornerVerts[faceConnPosI[1]] - cornerVerts[faceConnNegI[3]]).lengthSquared(); iSize += (cornerVerts[faceConnPosI[2]] - cornerVerts[faceConnNegI[2]]).lengthSquared(); - iSize += (cornerVerts[faceConnPosI[3]] - cornerVerts[faceConnNegI[3]]).lengthSquared(); + iSize += (cornerVerts[faceConnPosI[3]] - cornerVerts[faceConnNegI[1]]).lengthSquared(); jSize += (cornerVerts[faceConnPosJ[0]] - cornerVerts[faceConnNegJ[0]]).lengthSquared(); - jSize += (cornerVerts[faceConnPosJ[1]] - cornerVerts[faceConnNegJ[1]]).lengthSquared(); + jSize += (cornerVerts[faceConnPosJ[1]] - cornerVerts[faceConnNegJ[3]]).lengthSquared(); jSize += (cornerVerts[faceConnPosJ[2]] - cornerVerts[faceConnNegJ[2]]).lengthSquared(); - jSize += (cornerVerts[faceConnPosJ[3]] - cornerVerts[faceConnNegJ[3]]).lengthSquared(); + jSize += (cornerVerts[faceConnPosJ[3]] - cornerVerts[faceConnNegJ[1]]).lengthSquared(); kSize += (cornerVerts[faceConnPosK[0]] - cornerVerts[faceConnNegK[0]]).lengthSquared(); - kSize += (cornerVerts[faceConnPosK[1]] - cornerVerts[faceConnNegK[1]]).lengthSquared(); + kSize += (cornerVerts[faceConnPosK[1]] - cornerVerts[faceConnNegK[3]]).lengthSquared(); kSize += (cornerVerts[faceConnPosK[2]] - cornerVerts[faceConnNegK[2]]).lengthSquared(); - kSize += (cornerVerts[faceConnPosK[3]] - cornerVerts[faceConnNegK[3]]).lengthSquared(); + kSize += (cornerVerts[faceConnPosK[3]] - cornerVerts[faceConnNegK[1]]).lengthSquared(); cellCount++; } diff --git a/CommonCode/cvfStructGrid.h b/CommonCode/cvfStructGrid.h index a08e67e2f1..4353192b74 100644 --- a/CommonCode/cvfStructGrid.h +++ b/CommonCode/cvfStructGrid.h @@ -57,7 +57,6 @@ public: size_t cellCountK() const; virtual bool isCellValid(size_t i, size_t j, size_t k) const = 0; - virtual bool isCellActive(size_t i, size_t j, size_t k) const = 0; virtual cvf::Vec3d minCoordinate() const = 0; virtual cvf::Vec3d maxCoordinate() const = 0; diff --git a/CommonCode/cvfStructGridScalarDataAccess.h b/CommonCode/cvfStructGridScalarDataAccess.h index 226a821357..cbdac5ee4e 100644 --- a/CommonCode/cvfStructGridScalarDataAccess.h +++ b/CommonCode/cvfStructGridScalarDataAccess.h @@ -30,16 +30,8 @@ namespace cvf { class StructGridScalarDataAccess : public Object { public: - virtual double cellScalar(size_t i, size_t j, size_t k) const = 0; - virtual double cellScalar(size_t cellIndex) const = 0; - virtual void cellCornerScalars(size_t i, size_t j, size_t k, double scalars[8]) const = 0; - - // Trenger vi denne? Kan erstattes av cellCornerScalars for kuttplan - virtual double gridPointScalar(size_t i, size_t j, size_t k) const = 0; - virtual bool pointScalar(const cvf::Vec3d& p, double* scalarValue) const = 0; - - // Vector results - virtual const cvf::Vec3d* cellVector(size_t i, size_t j, size_t k) const = 0; + virtual double cellScalar(size_t cellIndex) const = 0; + virtual void setCellScalar(size_t cellIndex, double value) = 0; }; diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index 29995e5fee..496e427c4b 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -1,7 +1,7 @@ set(CMAKE_MAJOR_VERSION 0) set(CMAKE_MINOR_VERSION 9) -set(CMAKE_PATCH_VERSION 2) +set(CMAKE_PATCH_VERSION 4) set(PRODUCTVER ${CMAKE_MAJOR_VERSION},${CMAKE_MINOR_VERSION},0,${CMAKE_PATCH_VERSION}) set(STRPRODUCTVER ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}) diff --git a/ThirdParty/Ert/devel/CMakeLists.txt b/ThirdParty/Ert/devel/CMakeLists.txt index 263f31744a..5e984c5cf0 100644 --- a/ThirdParty/Ert/devel/CMakeLists.txt +++ b/ThirdParty/Ert/devel/CMakeLists.txt @@ -4,12 +4,14 @@ project( ERT C CXX ) set( ERT_VERSION_MAJOR 1 ) set( ERT_VERSION_MINOR 0 ) -option( BUILD_ERT "Build the full ERT application - Linux only" OFF) -option( BUILD_ENS_PLOT "Build small Eclipse plotting program - no" OFF) -option( BUILD_TESTS "Should the tests be built" OFF) -option( BUILD_APPLICATONS "Should we build small utility applications" OFF) -option( BUILD_ECL_SUMMARY "Build the commandline application ecl_summary" OFF) -option( BUILD_PYTHON "Run py_compile on the python wrappers" OFF) +option( BUILD_ERT "Build the full ERT application - Linux only" OFF) +option( BUILD_ENS_PLOT "Build small Eclipse plotting program - no" OFF) +option( BUILD_TESTS "Should the tests be built" OFF) +option( BUILD_APPLICATIONS "Should we build small utility applications" OFF) +option( BUILD_ECL_SUMMARY "Build the commandline application ecl_summary" OFF) +option( BUILD_PYTHON "Run py_compile on the python wrappers" OFF) +option( INSTALL_ERT "Should anything be installed when issuing make install?" ON) + include( CheckFunctionExists ) ENABLE_TESTING() @@ -17,13 +19,15 @@ ENABLE_TESTING() if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(ERT_LINUX TRUE ) add_definitions( -DERT_LINUX ) + set( CMAKE_C_FLAGS "-g -O2 -Wall -std=gnu99" ) + set( CMAKE_CXX_FLAGS "-g -O2 -Wall" ) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") set(ERT_WINDOWS TRUE) add_definitions( -DERT_WINDOWS ) + set( CMAKE_C_FLAGS "-O2" ) + set( CMAKE_CXX_FLAGS "-O2" ) endif() -set( CMAKE_C_FLAGS "-g -O2 -Wall -std=gnu99 -fno-leading-underscore" ) -set( CMAKE_CXX_FLAGS "-g -O2 -Wall" ) include(cmake/ert_check.cmake) include(cmake/ert_find.cmake) @@ -35,16 +39,18 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin) if (MSVC) - set(SHARED_LIB OFF) -else() - option( SHARED_LIB "Build shared libraries" ON) -endif() - -if (SHARED_LIB) - set( LIBRARY_TYPE SHARED ) -else() set( LIBRARY_TYPE STATIC ) -endif() + set( SHARED_LIB OFF ) +else() + if (INSTALL_ERT) + set( LIBRARY_TYPE SHARED ) + set( SHARED_LIB ON ) + else() + set( LIBRARY_TYPE STATIC ) + set( SHARED_LIB OFF ) + endif(INSTALL_ERT) +endif(MSVC) + @@ -57,9 +63,11 @@ if (ERT_LINUX) set( NEED_LIBM TRUE ) set( LINK_STATIC FALSE ) add_definitions( -DHAVE_PROC ) + set( NEED_LIBDL ON ) else() set( NEED_LIBM FALSE ) set( LINK_STATIC TRUE ) + set( NEED_LIBDL OFF ) endif() @@ -92,13 +100,6 @@ add_subdirectory( libecl_well ) #----------------------------------------------------------------- if (BUILD_ERT) #----------------------------------------------------------------- - try_compile( DLOPEN ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_dlopen.c ) - if (DLOPEN) - set(NEED_LIBDL OFF) - else() - set(NEED_LIBDL ON) - endif() - option(USE_LSF "Include support for LSF" ON) include_directories( ${PROJECT_SOURCE_DIR}/libconfig/include ) diff --git a/ThirdParty/Ert/devel/cmake/Tests/test_dlopen.c b/ThirdParty/Ert/devel/cmake/Tests/test_dlopen.c deleted file mode 100644 index 83b3f7bc67..0000000000 --- a/ThirdParty/Ert/devel/cmake/Tests/test_dlopen.c +++ /dev/null @@ -1,5 +0,0 @@ -#include - -int main( int argc , char ** argv) { - dlopen( NULL , 0 ); -} diff --git a/ThirdParty/Ert/devel/cmake/cmake_pyc b/ThirdParty/Ert/devel/cmake/cmake_pyc new file mode 100644 index 0000000000..03fd6507e2 --- /dev/null +++ b/ThirdParty/Ert/devel/cmake/cmake_pyc @@ -0,0 +1,35 @@ +#!/usr/bin/env python +import py_compile +import os +import os.path +import sys + +# Small 'python compiler' used in the build system for ert. The +# commandline arguments should be: +# +# cmake_pyc.py src1.py src2.py src3.py /path/to/pyc/files +# +# The input source files can contain a path component like +# path/src1.py, but the path will not be recreated in the target +# domain. + + +def compile_file(src_file , target_file): + path = os.path.dirname( target_file ) + if not os.path.exists( path ): + os.makedirs( path ) + try: + py_compile.compile( src_file , cfile = target_file , doraise = True) + except Exception,error: + sys.exit(1) + + +target_path = sys.argv[-1] +for src_file in sys.argv[1:-1]: + compile_file( src_file , "%s/%sc" % (target_path , os.path.basename(src_file))) + +sys.exit(0) + + + + diff --git a/ThirdParty/Ert/devel/cmake/config/ert_build_config.h.in b/ThirdParty/Ert/devel/cmake/config/ert_build_config.h.in index 2fa0b98789..88df980d5e 100644 --- a/ThirdParty/Ert/devel/cmake/config/ert_build_config.h.in +++ b/ThirdParty/Ert/devel/cmake/config/ert_build_config.h.in @@ -1,18 +1,18 @@ -#cmakedefine HAVE_PTHREAD -#cmakedefine HAVE_EXECINFO -#cmakedefine HAVE_FORK -#cmakedefine HAVE_ZLIB -#cmakedefine HAVE_LSF -#cmakedefine HAVE_REALPATH -#cmakedefine HAVE_SYMLINK -#cmakedefine HAVE_READLINKAT -#cmakedefine HAVE_GETUID -#cmakedefine HAVE_LOCALTIME_R -#cmakedefine HAVE_LOCKF -#cmakedefine HAVE_SETENV -#cmakedefine HAVE_GLOB -#cmakedefine MKDIR_POSIX -#cmakedefine HAVE_FNMATCH -#cmakedefine NEED_BLAS -#cmakedefine HAVE_OPENMP -#cmakedefine HAVE_FTRUNCATE +#cmakedefine HAVE_PTHREAD 1 +#cmakedefine HAVE_EXECINFO 1 +#cmakedefine HAVE_FORK 1 +#cmakedefine HAVE_ZLIB 1 +#cmakedefine HAVE_LSF 1 +#cmakedefine HAVE_REALPATH 1 +#cmakedefine HAVE_SYMLINK 1 +#cmakedefine HAVE_READLINKAT 1 +#cmakedefine HAVE_GETUID 1 +#cmakedefine HAVE_LOCALTIME_R 1 +#cmakedefine HAVE_LOCKF 1 +#cmakedefine HAVE_SETENV 1 +#cmakedefine HAVE_GLOB 1 +#cmakedefine MKDIR_POSIX 1 +#cmakedefine HAVE_FNMATCH 1 +#cmakedefine NEED_BLAS 1 +#cmakedefine HAVE_OPENMP 1 +#cmakedefine HAVE_FTRUNCATE 1 diff --git a/ThirdParty/Ert/devel/cmake/ert_find.cmake b/ThirdParty/Ert/devel/cmake/ert_find.cmake index 4d7d1efb66..3057b8baf1 100644 --- a/ThirdParty/Ert/devel/cmake/ert_find.cmake +++ b/ThirdParty/Ert/devel/cmake/ert_find.cmake @@ -52,6 +52,8 @@ if (LATEX_PATH) else() set( WITH_LATEX OFF ) endif() +#-----------------------------------------------------------------f +find_program(PING_PATH NAMES ping) #----------------------------------------------------------------- find_path( EXECINFO_HEADER execinfo.h /usr/include ) if (EXECINFO_HEADER) @@ -63,6 +65,8 @@ if (GETOPT_HEADER) add_definitions( -DHAVE_GETOPT ) endif() #----------------------------------------------------------------- +find_path( UNISTD_HEADER unistd.h /usr/include ) + if (ERT_WINDOWS) find_library( SHLWAPI_LIBRARY NAMES Shlwapi ) endif() diff --git a/ThirdParty/Ert/devel/cmake/python.cmake b/ThirdParty/Ert/devel/cmake/python.cmake index cb53d7103f..a9b386e294 100644 --- a/ThirdParty/Ert/devel/cmake/python.cmake +++ b/ThirdParty/Ert/devel/cmake/python.cmake @@ -3,15 +3,17 @@ macro(add_python_target tgt PYTHON_INSTALL_PATH ARGN) foreach(file ${ARGN}) set(OUT ${CMAKE_CURRENT_BINARY_DIR}/${file}.pyc) list(APPEND OUT_FILES ${OUT}) +#------------------------------------------------------ ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${file}.pyc - COMMAND python -m py_compile - ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.py - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND mv - ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.pyc ${CMAKE_CURRENT_BINARY_DIR} + OUTPUT ${OUT} + COMMAND ${PROJECT_SOURCE_DIR}/cmake/cmake_pyc + ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.py ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PATH} ) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${file}.pyc DESTINATION ${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PATH}) +#------------------------------------------------------ + if (INSTALL_ERT) + install(FILES ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PATH}/${file}.pyc DESTINATION ${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PATH}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${file}.py DESTINATION ${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PATH}) + endif() endforeach(file) list(REMOVE_DUPLICATES OUT_FILES) ADD_CUSTOM_TARGET( diff --git a/ThirdParty/Ert/devel/debian/changelog b/ThirdParty/Ert/devel/debian/changelog index f86efe7fe7..963e48161a 100644 --- a/ThirdParty/Ert/devel/debian/changelog +++ b/ThirdParty/Ert/devel/debian/changelog @@ -1,3 +1,9 @@ +libert.ecl (1.0-2) precise; urgency=low + + * Mark -dev package as architecture independent + + -- Arne Morten Kvarving Tue, 19 Feb 2013 10:03:04 +0100 + libert.ecl (1.0-1) unstable; urgency=low * Initial release diff --git a/ThirdParty/Ert/devel/debian/control b/ThirdParty/Ert/devel/debian/control index 7ea4d426b8..1a46a19dce 100644 --- a/ThirdParty/Ert/devel/debian/control +++ b/ThirdParty/Ert/devel/debian/control @@ -10,7 +10,7 @@ Vcs-Browser: https://github.com/Ensembles/ert Package: libert.ecl-dev Section: libdevel -Architecture: any +Architecture: all Depends: libert.ecl1 (= ${binary:Version}) Description: The Ensemble based Reservoir Tool -- Development files ERT - Ensemble based Reservoir Tool is a tool for managing en ensemble diff --git a/ThirdParty/Ert/devel/debian/libert.ecl1.install b/ThirdParty/Ert/devel/debian/libert.ecl1.install index 3ddde58419..00c8fc1fd2 100644 --- a/ThirdParty/Ert/devel/debian/libert.ecl1.install +++ b/ThirdParty/Ert/devel/debian/libert.ecl1.install @@ -1 +1,2 @@ usr/lib/*/lib*.so.* +usr/bin/* diff --git a/ThirdParty/Ert/devel/debian/rules b/ThirdParty/Ert/devel/debian/rules index 7f4ddf48bd..265d328965 100644 --- a/ThirdParty/Ert/devel/debian/rules +++ b/ThirdParty/Ert/devel/debian/rules @@ -13,4 +13,4 @@ dh $@ override_dh_auto_configure: - dh_auto_configure -- -DSHARED_LIB=1 + dh_auto_configure -- -DSHARED_LIB=1 -DBUILD_ECL_SUMMARY=1 -DCMAKE_BUILD_TYPE=Release diff --git a/ThirdParty/Ert/devel/libanalysis/include/ert/analysis/rml_enkf_common.h b/ThirdParty/Ert/devel/libanalysis/include/ert/analysis/rml_enkf_common.h index eeca1c0404..fcb0d38e0b 100644 --- a/ThirdParty/Ert/devel/libanalysis/include/ert/analysis/rml_enkf_common.h +++ b/ThirdParty/Ert/devel/libanalysis/include/ert/analysis/rml_enkf_common.h @@ -2,23 +2,22 @@ #ifndef __RML_ENKF_COMMON_H__ #define __RML_ENKF_COMMON_H__ - - #include -#include -#include + +#include +#include void rml_enkf_common_initA__( matrix_type * A , - matrix_type * S , - matrix_type * Cd , - matrix_type * E , - matrix_type * D , - double truncation, - double lamda, - matrix_type * Ud, - double * Wd, - matrix_type * VdT); + matrix_type * S , + matrix_type * Cd , + matrix_type * E , + matrix_type * D , + double truncation, + double lamda, + matrix_type * Ud, + double * Wd, + matrix_type * VdT); #endif diff --git a/ThirdParty/Ert/devel/libanalysis/src/CMakeLists.txt b/ThirdParty/Ert/devel/libanalysis/src/CMakeLists.txt index ffaedd6bf9..2346c6e9f0 100644 --- a/ThirdParty/Ert/devel/libanalysis/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libanalysis/src/CMakeLists.txt @@ -16,12 +16,15 @@ endif() set( CMAKE_SHARED_MODULE_PREFIX "" ) add_library( std_enkf MODULE std_enkf.c ) add_library( sqrt_enkf MODULE sqrt_enkf.c ) +add_library( rml_enkf MODULE rml_enkf.c rml_enkf_common.c ) #----------------------------------------------------------------- -install(TARGETS analysis DESTINATION ${CMAKE_INSTALL_LIBDIR}) -foreach(header ${header_files}) - install(FILES ../include/ert/analysis/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/analysis) -endforeach() - +if (INSTALL_ERT) + install(TARGETS analysis DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(TARGETS rml_enkf DESTINATION ${CMAKE_INSTALL_LIBDIR}) + foreach(header ${header_files}) + install(FILES ../include/ert/analysis/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/analysis) + endforeach() +endif() diff --git a/ThirdParty/Ert/devel/libconfig/CMakeLists.txt b/ThirdParty/Ert/devel/libconfig/CMakeLists.txt index d4fb658258..da0dfb169f 100644 --- a/ThirdParty/Ert/devel/libconfig/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libconfig/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory( src ) +add_subdirectory( tests ) diff --git a/ThirdParty/Ert/devel/libconfig/include/ert/config/config.h b/ThirdParty/Ert/devel/libconfig/include/ert/config/config.h index 007bf7fa5d..08b110b46a 100644 --- a/ThirdParty/Ert/devel/libconfig/include/ert/config/config.h +++ b/ThirdParty/Ert/devel/libconfig/include/ert/config/config.h @@ -18,61 +18,52 @@ #ifndef __CONFIG_H__ #define __CONFIG_H__ + #ifdef __cplusplus extern "C" { #endif #include +#include #include #include #include +#include +#include +#include + #define ECL_COM_KW "--" #define ENKF_COM_KW "--" -/** - Types used for validation of config items. -*/ -typedef enum {CONFIG_STRING = 0, - CONFIG_INT = 1, - CONFIG_FLOAT = 2, - CONFIG_FILE = 9, /* These file does not need to exist - but includes are handled. */ - CONFIG_EXISTING_FILE = 3, - CONFIG_EXISTING_DIR = 4, - CONFIG_BOOLEAN = 5, - CONFIG_CONFIG = 6, - CONFIG_BYTESIZE = 7, - CONFIG_EXECUTABLE = 8 , - CONFIG_INVALID = 1000 } config_item_types; -typedef struct config_struct config_type; -typedef struct config_schema_item_struct config_schema_item_type; + + +typedef struct config_struct config_type; + char ** config_alloc_active_list(const config_type *, int *); void config_free(config_type *); config_type * config_alloc( ); char ** config_alloc_active_list(const config_type * , int * ); - void config_parse(config_type * , const char * , const char * , const char * , const char * , bool , bool ); + bool config_parse(config_type * , const char * , const char * , const char * , const char * , config_schema_unrecognized_enum unrecognized_behaviour , bool ); bool config_has_schema_item(const config_type * config , const char * kw); void config_clear(config_type * config); /*****************************************************************/ - void config_schema_item_set_envvar_expansion( config_schema_item_type * item , bool expand_envvar ); - bool config_item_set(const config_type * , const char * ); - void config_schema_item_free__ (void * ); - void config_schema_item_free( config_schema_item_type * ); - config_schema_item_type * config_schema_item_alloc(const char * , bool , bool); config_schema_item_type * config_get_schema_item(const config_type *, const char *); + bool config_item_set(const config_type * , const char * ); void config_add_alias(config_type * , const char * , const char * ); void config_install_message(config_type * , const char * , const char * ); const char * config_safe_get(const config_type * , const char *); char * config_alloc_joined_string(const config_type * , const char * , const char * ); void config_add_define( config_type * config , const char * key , const char * value ); - + + /* bool config_schema_item_is_set(const config_schema_item_type * ); void config_schema_item_set_argc_minmax(config_schema_item_type * , int , int , int type_map_size , const config_item_types * ); void config_schema_item_set_common_selection_set(config_schema_item_type * , int argc , const char ** argv); @@ -80,17 +71,12 @@ typedef struct config_schema_item_struct config_schema_item_type; void config_schema_item_set_required_children(config_schema_item_type * , stringlist_type * ); void config_schema_item_set_required_children_on_value(config_schema_item_type * , const char * , stringlist_type * ); void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key); + */ + + config_schema_item_type * config_add_schema_item(config_type * config, + const char * kw, + bool required); - config_schema_item_type * config_add_schema_item(config_type *, - const char * , - bool , - bool); - - - bool config_has_keys(const config_type *, - const char **, - int , - bool ); const char * config_safe_iget(const config_type * config , const char *kw, int occurence , int index); const char * config_iget(const config_type * , const char * , int occurence , int index); @@ -100,21 +86,29 @@ typedef struct config_schema_item_struct config_schema_item_type; stringlist_type * config_alloc_complete_stringlist(const config_type* , const char * ); stringlist_type * config_alloc_stringlist(const config_type * config , const char * ); hash_type * config_alloc_hash(const config_type * , const char * ); - const stringlist_type * config_get_stringlist_ref(const config_type * , const char * ); - stringlist_type * config_iget_stringlist_ref(const config_type * , const char * , int ); - bool config_has_set_item(const config_type * , const char * ); + const stringlist_type * config_iget_stringlist_ref(const config_type * , const char * , int ); int config_get_occurences(const config_type * , const char * ); int config_get_occurence_size( const config_type * config , const char * kw , int occurence); - + bool config_has_content_item( const config_type * config , const char * input_kw); + config_content_item_type * config_get_content_item( const config_type * config , const char * input_kw); config_schema_item_type * config_add_key_value( config_type * config , const char * key , bool required , config_item_types item_type); bool config_get_value_as_bool(const config_type * config , const char * kw); int config_get_value_as_int(const config_type * config , const char * kw); double config_get_value_as_double(const config_type * config , const char * kw); + const char * config_get_value_as_abspath( const config_type * config , const char * kw); + const char * config_get_value_as_relpath( const config_type * config , const char * kw); + const char * config_get_value_as_path( const config_type * config , const char * kw); const char * config_get_value(const config_type * config , const char * kw); - void config_fprintf_item_list(const config_type * config , FILE * stream); const char * config_get_config_file( const config_type * config , bool abs_path); + void config_fprintf_errors( const config_type * config , bool add_count , FILE * stream ); + + int config_get_schema_size( const config_type * config ); + int config_get_content_size( const config_type * config ); + const config_content_node_type * config_iget_content_node( const config_type * config , int index ); + config_content_node_type * config_get_value_node( const config_type * config , const char * kw); + config_error_type * config_get_errors( const config_type * config ); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libconfig/include/ert/config/config_content_item.h b/ThirdParty/Ert/devel/libconfig/include/ert/config/config_content_item.h new file mode 100644 index 0000000000..da4dd393bc --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/include/ert/config/config_content_item.h @@ -0,0 +1,66 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_content_item.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + + +#ifndef __CONFIG_CONTENT_ITEM_H__ +#define __CONFIG_CONTENT_ITEM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include +#include +#include + +typedef struct config_content_item_struct config_content_item_type; + + int config_content_item_get_size(const config_content_item_type * item); + config_content_node_type * config_content_item_get_last_node(const config_content_item_type * item); + config_content_node_type * config_content_item_iget_node(const config_content_item_type * item , int index); + const config_content_node_type * config_content_item_get_last_node_const(const config_content_item_type * item); + const config_content_node_type * config_content_item_iget_node_const(const config_content_item_type * item , int index); + char * config_content_item_ialloc_joined_string(const config_content_item_type * item , const char * sep , int occurence); + char * config_content_item_alloc_joined_string(const config_content_item_type * item , const char * sep); + const stringlist_type * config_content_item_iget_stringlist_ref(const config_content_item_type * item, int occurence); + const stringlist_type * config_content_item_get_stringlist_ref(const config_content_item_type * item); + stringlist_type * config_content_item_alloc_complete_stringlist(const config_content_item_type * item, bool copy); + stringlist_type * config_content_item_alloc_stringlist(const config_content_item_type * item, bool copy); + hash_type * config_content_item_alloc_hash(const config_content_item_type * item , bool copy); + const char * config_content_item_iget(const config_content_item_type * item , int occurence , int index); + bool config_content_item_iget_as_bool(const config_content_item_type * item, int occurence , int index); + int config_content_item_iget_as_int(const config_content_item_type * item, int occurence , int index); + double config_content_item_iget_as_double(const config_content_item_type * item, int occurence , int index); + void config_content_item_clear( config_content_item_type * item ); + void config_content_item_free( config_content_item_type * item ); + void config_content_item_free__( void * arg ); + config_content_item_type * config_content_item_alloc( const config_schema_item_type * schema , const config_path_elm_type * path_elm); + void config_content_item_validate(const config_content_item_type * item, config_error_type * error); + config_content_node_type * config_content_item_alloc_node( const config_content_item_type * item , const config_path_elm_type * path_elm); + const config_schema_item_type * config_content_item_get_schema( const config_content_item_type * item ); + const config_path_elm_type * config_content_item_get_path_elm( const config_content_item_type * item ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/devel/libconfig/include/ert/config/config_content_node.h b/ThirdParty/Ert/devel/libconfig/include/ert/config/config_content_node.h new file mode 100644 index 0000000000..b318bff85b --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/include/ert/config/config_content_node.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_content_node.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + + +#ifndef __CONFIG_CONTENT_NODE_H__ +#define __CONFIG_CONTENT_NODE_H__ + +#ifdef __cplusplus +define extern "C" { +#endif + +#include + +#include +#include + +typedef struct config_content_node_struct config_content_node_type; + + config_content_node_type * config_content_node_alloc( const config_schema_item_type * schema , const config_path_elm_type * cwd); + void config_content_node_add_value(config_content_node_type * node , const char * value); + void config_content_node_set(config_content_node_type * node , const stringlist_type * token_list); + char * config_content_node_alloc_joined_string(const config_content_node_type * node, const char * sep); + void config_content_node_free(config_content_node_type * node); + void config_content_node_free__(void * arg); + const char * config_content_node_get_full_string( config_content_node_type * node , const char * sep ); + const char * config_content_node_iget(const config_content_node_type * node , int index); + bool config_content_node_iget_as_bool(const config_content_node_type * node , int index); + int config_content_node_iget_as_int(const config_content_node_type * node , int index); + double config_content_node_iget_as_double(const config_content_node_type * node , int index); + const char * config_content_node_iget_as_path(config_content_node_type * node , int index); + const char * config_content_node_iget_as_abspath( config_content_node_type * node , int index); + const char * config_content_node_iget_as_relpath( config_content_node_type * node , int index); + const stringlist_type * config_content_node_get_stringlist( const config_content_node_type * node ); + const char * config_content_node_safe_iget(const config_content_node_type * node , int index); + int config_content_node_get_size( const config_content_node_type * node ); + const char * config_content_node_get_kw( const config_content_node_type * node ); + void config_content_node_assert_key_value( const config_content_node_type * node ); + const config_path_elm_type * config_content_node_get_path_elm( const config_content_node_type * node ); + void config_content_node_init_opt_hash( const config_content_node_type * node , hash_type * opt_hash , int elm_offset); + void config_content_node_fprintf( const config_content_node_type * node , FILE * stream ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/devel/libconfig/include/ert/config/config_error.h b/ThirdParty/Ert/devel/libconfig/include/ert/config/config_error.h new file mode 100644 index 0000000000..c6314a4b97 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/include/ert/config/config_error.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_error.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + +#ifndef __CONFIG_ERROR_H__ +#define __CONFIG_ERROR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef struct config_error_struct config_error_type; + + + config_error_type * config_error_alloc(); + config_error_type * config_error_alloc_copy( const config_error_type * src_error); + void config_error_free(config_error_type * error); + const char * config_error_iget(const config_error_type * error , int index); + void config_error_add( config_error_type * error , char * new_error ); + void config_error_clear( config_error_type * error ); + int config_error_count( const config_error_type * error ); + void config_error_fprintf( const config_error_type * error , bool add_count , FILE * stream ); + bool config_error_equal( const config_error_type * error1 , const config_error_type * error2); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/devel/libconfig/include/ert/config/config_path_elm.h b/ThirdParty/Ert/devel/libconfig/include/ert/config/config_path_elm.h new file mode 100644 index 0000000000..e4ab4210ee --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/include/ert/config/config_path_elm.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'config_path_elm.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + +#ifndef __CONFIG_PATH_ELM_H__ +#define __CONFIG_PATH_ELM_H__ + +#ifdef __cplusplus +extern "C" +#endif + +#include + +typedef struct config_path_elm_struct config_path_elm_type; + +void config_path_elm_free( config_path_elm_type * path_elm ); +void config_path_elm_free__( void * arg ); +config_path_elm_type * config_path_elm_alloc( const config_root_path_type * root_path , const char * path); +const char * config_path_elm_get_abspath( const config_path_elm_type * path_elm ); +const char * config_path_elm_get_relpath( const config_path_elm_type * path_elm ); +const config_root_path_type * config_path_elm_get_rootpath( const config_path_elm_type * path_elm ); +char * config_path_elm_alloc_abspath(const config_path_elm_type * path_elm , const char * input_path); +char * config_path_elm_alloc_relpath(const config_path_elm_type * path_elm , const char * input_path); +char * config_path_elm_alloc_path(const config_path_elm_type * path_elm , const char * input_path); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/devel/libconfig/include/ert/config/config_root_path.h b/ThirdParty/Ert/devel/libconfig/include/ert/config/config_root_path.h new file mode 100644 index 0000000000..09289ec398 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/include/ert/config/config_root_path.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'config_root_path.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + +#ifndef __CONFIG_ROOT_PATH_H__ +#define __CONFIG_ROOT_PATH_H__ + +#ifdef __cplusplus +extern "C" +#endif + + +typedef struct config_root_path_struct config_root_path_type; + +void config_root_path_free( config_root_path_type * root_path ); +config_root_path_type * config_root_path_alloc( const char * input_path ); + +const char * config_root_path_get_input_path( const config_root_path_type * root_path ); +const char * config_root_path_get_rel_path( const config_root_path_type * root_path ); +const char * config_root_path_get_abs_path( const config_root_path_type * root_path ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/devel/libconfig/include/ert/config/config_schema_item.h b/ThirdParty/Ert/devel/libconfig/include/ert/config/config_schema_item.h new file mode 100644 index 0000000000..50eb65e187 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/include/ert/config/config_schema_item.h @@ -0,0 +1,123 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_schema_item.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + + +#ifndef __CONFIG_SCHEMA_ITEM_H__ +#define __CONFIG_SCHEMA_ITEM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include + +/** + Types used for validation of config items. +*/ +typedef enum {CONFIG_STRING = 1, + CONFIG_INT = 2, + CONFIG_FLOAT = 4, + CONFIG_PATH = 8, + CONFIG_EXISTING_PATH = 16, + CONFIG_BOOL = 32, + CONFIG_CONFIG = 64, + CONFIG_BYTESIZE = 128, + CONFIG_EXECUTABLE = 256 , + CONFIG_INVALID = 512 } config_item_types; + +#define CONFIG_ITEM_TYPE_ENUM_DEFS \ +{.value = 1 , .name="CONFIG_STRING"}, \ +{.value = 2 , .name="CONFIG_INT"}, \ +{.value = 4 , .name="CONFIG_FLOAT"}, \ +{.value = 8 , .name="CONFIG_PATH"}, \ +{.value = 16 , .name="CONFIG_EXISTING_PATH"}, \ +{.value = 32 , .name="CONFIG_BOOL"}, \ +{.value = 64 , .name="CONFIG_CONFIG"}, \ +{.value = 128 , .name="CONFIG_BYTESIZE"}, \ +{.value = 256 , .name="CONFIG_EXECUTABLE"}, \ +{.value = 512 , .name="CONFIG_INVALID"} +#define CONFIG_ITEM_TYPE_ENUM_SIZE 10 + + + typedef enum { + CONFIG_UNRECOGNIZED_IGNORE = 0, + CONFIG_UNRECOGNIZED_WARN = 1, + CONFIG_UNRECOGNIZED_ERROR = 2 + } config_schema_unrecognized_enum; + + +#define CONFIG_SCHEMA_UNRECOGNIZED_ENUM_DEFS \ +{.value = 0 , .name="CONFIG_UNRECOGNIZED_IGNORE"}, \ +{.value = 1 , .name="CONFIG_UNRECOGNIZED_WARN"}, \ +{.value = 2 , .name="CONFIG_UNRECOGNIZED_ERROR"} +#define CONFIG_SCHEMA_UNRECOGNIZED_ENUM_SIZE 3 + + + + +#define CONFIG_DEFAULT_ARG_MIN -1 +#define CONFIG_DEFAULT_ARG_MAX -1 + + + + typedef struct config_schema_item_struct config_schema_item_type; + + + config_schema_item_type * config_schema_item_alloc(const char * kw , bool required); + bool config_schema_item_validate_set(const config_schema_item_type * item , + stringlist_type * token_list , + const char * config_file, + const config_path_elm_type * path_elm, + config_error_type * error_list); + + void config_schema_item_free( config_schema_item_type * item); + void config_schema_item_free__ (void * void_item); + + + void config_schema_item_set_common_selection_set(config_schema_item_type * item , int argc , const char ** argv); + void config_schema_item_set_indexed_selection_set(config_schema_item_type * item , int index , int argc , const char ** argv); + void config_schema_item_set_required_children(config_schema_item_type * item , stringlist_type * stringlist); + void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key); + void config_schema_item_set_envvar_expansion( config_schema_item_type * item , bool expand_envvar ); + void config_schema_item_set_argc_minmax(config_schema_item_type * item , + int argc_min , + int argc_max); + void config_schema_item_assure_type(const config_schema_item_type * item , int index , int type_mask); + + int config_schema_item_num_required_children(const config_schema_item_type * item); + const char * config_schema_item_iget_required_child( const config_schema_item_type * item , int index); + const char * config_schema_item_get_kw( const config_schema_item_type * item ); + bool config_schema_item_required( const config_schema_item_type * item ); + bool config_schema_item_expand_envvar( const config_schema_item_type * item ); + void config_schema_item_get_argc( const config_schema_item_type * item , int *argc_min , int *argc_max); + bool config_schema_item_has_required_children_value( const config_schema_item_type * item ); + stringlist_type * config_schema_item_get_required_children_value(const config_schema_item_type * item , const char * value); + + void config_schema_item_iset_type( config_schema_item_type * item , int index , config_item_types type); + config_item_types config_schema_item_iget_type(const config_schema_item_type * item , int index ); + void config_schema_item_set_default_type( config_schema_item_type * item , config_item_types type); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/devel/libconfig/src/CMakeLists.txt b/ThirdParty/Ert/devel/libconfig/src/CMakeLists.txt index e0c31cfab9..555a39c4cd 100644 --- a/ThirdParty/Ert/devel/libconfig/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libconfig/src/CMakeLists.txt @@ -1,12 +1,14 @@ -set( source_files config.c conf.c conf_util.c conf_data.c) -set( header_files config.h conf.h conf_data.h) +set( source_files config.c config_error.c config_schema_item.c config_content_item.c config_content_node.c config_root_path.c config_path_elm.c conf.c conf_util.c conf_data.c) +set( header_files config.h config_error.h config_schema_item.h config_content_item.h config_content_node.h config_root_path.h config_path_elm.h conf.h conf_data.h) add_library( config ${LIBRARY_TYPE} ${source_files} ) set_target_properties( config PROPERTIES VERSION 1.0 SOVERSION 1.0 ) target_link_libraries( config ert_util ) -install(TARGETS config DESTINATION ${CMAKE_INSTALL_LIBDIR}) -foreach(header ${header_files}) - install(FILES ../include/ert/config/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/config) -endforeach() +if (INSTALL_ERT) + install(TARGETS config DESTINATION ${CMAKE_INSTALL_LIBDIR}) + foreach(header ${header_files}) + install(FILES ../include/ert/config/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/config) + endforeach() +endif() diff --git a/ThirdParty/Ert/devel/libconfig/src/config.c b/ThirdParty/Ert/devel/libconfig/src/config.c index 1eb45b0336..e3df9254d7 100644 --- a/ThirdParty/Ert/devel/libconfig/src/config.c +++ b/ThirdParty/Ert/devel/libconfig/src/config.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -29,13 +30,17 @@ #include #include #include +#include #include +#include +#include +#include +#include +#include +#include -#define CLEAR_STRING "__RESET__" - - - +#define CLEAR_STRING "__RESET__" @@ -113,879 +118,57 @@ In this case the whole config object will contain three items, corresponding to the keywords OUTFILE, INPUT and OPTIONS. The two first will again only contain one node each, whereas the OPTIONS item will contain three nodes, corresponding to the three times the keyword -"OPTIONS" appear in the config file. Observe that *IF* the OPTIONS -item had been added with append_arg == false, only the last occurence, -corresponding to 'optimize cache=1' would be present. - +"OPTIONS" appear in the config file. */ -typedef struct validate_struct validate_type; - -/** - This is a 'support-struct' holding various pieces of information - needed during the validation process. Observe the following about - validation: - - 1. It is atomic, in the sense that if you try to an item like this: - - KW ARG1 ARG2 ARG3 - - where ARG1 and ARG2 are valid, whereas there is something wrong - with ARG3, NOTHING IS SET. - - 2. Validation is a two-step process, the first step is run when an - item is parsed. This includes checking: - - o The number of argument. - o That the arguments have the right type. - o That the values match the selection set. - - The second validation step is done when the pasing is complete, - in this pass we check dependencies - i.e. required_children and - required_children_on_value. - - - Observe that nothing has-to be set in this struct. There are some dependencies: - - 1. Only _one_ of common_selection_set and indexed_selection_set - can be set. - - 2. If setting indexed_selection_set or type_map, you MUST set - argc_max first. -*/ - -typedef struct config_item_node_struct config_item_node_type; -typedef struct config_content_item_struct config_content_item_type; - - -struct validate_struct { - int argc_min; /* The minimum number of arguments: -1 means no lower limit. */ - int argc_max; /* The maximum number of arguments: -1 means no upper limit. */ - set_type * common_selection_set; /* A selection set which will apply uniformly to all the arguments. */ - set_type ** indexed_selection_set; /* A selection set which will apply for specifi (indexed) arguments. */ - config_item_types * type_map; /* A list of types for the items - can be NULL. Set along with argc_minmax(); */ - int type_map_size; - stringlist_type * required_children; /* A list of item's which must also be set (if this item is set). (can be NULL) */ - hash_type * required_children_value; /* A list of item's which must also be set - depending on the value of this item. (can be NULL) (This one is complex). */ -}; -#define CONFIG_SCHEMA_ITEM_ID 6751 -struct config_schema_item_struct { - UTIL_TYPE_ID_DECLARATION; - char * kw; /* The kw which identifies this item· */ - - bool append_arg; /* Should the values be appended if a keyword appears several times in the config file. */ - bool required_set; - stringlist_type * required_children; /* A list of item's which must also be set (if this item is set). (can be NULL) */ - hash_type * required_children_value; /* A list of item's which must also be set - depending on the value of this item. (can be NULL) */ - validate_type * validate; /* Information need during validation. */ - bool expand_envvar; /* Should environment variables like $HOME be expanded?*/ -}; + -#define CONFIG_CONTENT_ITEM_ID 8876752 -struct config_content_item_struct { - UTIL_TYPE_ID_DECLARATION; - const config_schema_item_type * schema; - int alloc_size; /* The number of nodes which have been allocated. */ - int node_size; /* The number of active nodes.*/ - config_item_node_type ** nodes; /* A vector of config_item_node_type instances. */ - bool currently_set; /* Has a value been assigned to this keyword. */ - -}; - - - -struct config_item_node_struct { - stringlist_type * stringlist; /* The values which have been set. */ - char * config_cwd; /* The currently active cwd (relative or absolute) of the parser when this item is set. */ -}; struct config_struct { + vector_type * content_list; /* Vector of content_content_node instances. */ hash_type * content_items; hash_type * schema_items; - stringlist_type * parse_errors; /* A stringlist containg the errors found when parsing.*/ + config_error_type * parse_errors; set_type * parsed_files; /* A set of config files whcih have been parsed - to protect against circular includes. */ hash_type * messages; /* Can print a (warning) message when a keyword is encountered. */ subst_list_type * define_list; char * config_file; /* The last parsed file - NULL if no file is parsed-. */ char * abs_path; + config_root_path_type * invoke_path; + vector_type * path_elm_storage; + vector_type * path_elm_stack; }; -/*****************************************************************/ -static void config_add_and_free_error(config_type * config , char * error_message); -/*****************************************************************/ -static validate_type * validate_alloc() { - validate_type * validate = util_malloc(sizeof * validate ); - validate->argc_min = -1; - validate->argc_max = -1; - validate->common_selection_set = NULL; - validate->indexed_selection_set = NULL; - validate->type_map = NULL; - validate->type_map_size = 0; - validate->required_children = NULL; - validate->required_children_value = NULL; - - return validate; -} - - -static void validate_free(validate_type * validate) { - if (validate->common_selection_set != NULL) set_free(validate->common_selection_set); - if (validate->indexed_selection_set != NULL) { - for (int i = 0; i < validate->argc_max; i++) - if (validate->indexed_selection_set[i] != NULL) - set_free(validate->indexed_selection_set[i]); - free(validate->indexed_selection_set); - } - if (validate->type_map != NULL) free(validate->type_map); - if (validate->required_children != NULL) stringlist_free(validate->required_children); - if (validate->required_children_value != NULL) hash_free(validate->required_children_value); - free(validate); -} - -static void validate_set_argc_minmax(validate_type * validate , int argc_min , int argc_max, int type_map_size , const config_item_types * type_map) { - if (validate->argc_min != -1) - util_abort("%s: sorry - current implementation does not allow repeated calls to: %s \n",__func__ , __func__); - - if (argc_min == -1) - argc_min = 0; - - validate->argc_min = argc_min; - validate->argc_max = argc_max; - - { - int internal_type_size = 0; /* Should end up in the range [argc_min,argc_max] */ - - if (argc_max > 0) - internal_type_size = argc_max; - else - internal_type_size = argc_min; - - if (internal_type_size > 0) { - validate->indexed_selection_set = util_calloc( internal_type_size , sizeof * validate->indexed_selection_set ); - for (int iarg=0; iarg < internal_type_size; iarg++) - validate->indexed_selection_set[iarg] = NULL; - } - } - - if (type_map != NULL) { - validate->type_map_size = type_map_size; - validate->type_map = util_alloc_copy(type_map , type_map_size * sizeof * type_map ); - } - -} - - - -static void validate_set_common_selection_set(validate_type * validate , int argc , const char ** argv) { - if (validate->common_selection_set != NULL) - set_free(validate->common_selection_set); - validate->common_selection_set = set_alloc( argc , argv ); -} - - -static void validate_set_indexed_selection_set(validate_type * validate , int index , int argc , const char ** argv) { - - if (validate->indexed_selection_set == NULL) - util_abort("%s: must call xxx_set_argc_minmax() first - aborting \n",__func__); - - if (index >= validate->argc_min) - util_abort("%s: When not not setting argc_max selection set can only be applied to indices up to argc_min\n",__func__); - - if (validate->indexed_selection_set[index] != NULL) - set_free(validate->indexed_selection_set[index]); - - validate->indexed_selection_set[index] = set_alloc(argc , argv); -} - - - - -static char * __alloc_relocated__(const char * config_cwd , const char * value) { - char * file; - - if (util_is_abs_path(value)) - file = util_alloc_string_copy( value ); - else - file = util_alloc_filename(config_cwd , value , NULL); - - return file; -} - -/*****************************************************************/ - -static config_item_node_type * config_item_node_alloc() { - config_item_node_type * node = util_malloc(sizeof * node ); - node->stringlist = stringlist_alloc_new(); - node->config_cwd = NULL; - return node; -} - - -static void config_item_node_set(config_item_node_type * node , const stringlist_type * token_list) { - int argc = stringlist_get_size( token_list ) - 1; - for (int iarg=0; iarg < argc; iarg++) - stringlist_append_copy( node->stringlist , stringlist_iget( token_list , iarg + 1)); -} - - - -static char * config_item_node_alloc_joined_string(const config_item_node_type * node, const char * sep) { - return stringlist_alloc_joined_string(node->stringlist , sep); -} - - -static void config_item_node_free(config_item_node_type * node) { - stringlist_free(node->stringlist); - util_safe_free(node->config_cwd); - free(node); -} - - - - - - - -static void config_item_node_clear(config_item_node_type * node) { - stringlist_clear( node->stringlist ); - util_safe_free(node->config_cwd); - node->config_cwd = NULL; -} - - - - - - - - - -void config_schema_item_assure_type(const config_schema_item_type * item , int index , config_item_types item_type) { - if (index < item->validate->type_map_size) { - bool OK = false; - - if (item->validate->type_map != NULL) - if (item->validate->type_map[index] == item_type) - OK = true; - - if (!OK) - util_abort("%s: failed - wrong installed type \n" , __func__); - } -} - - - - - - - - - - - - - - - - - - -config_schema_item_type * config_schema_item_alloc(const char * kw , bool required , bool append_arg) { - config_schema_item_type * item = util_malloc(sizeof * item ); - UTIL_TYPE_ID_INIT( item , CONFIG_SCHEMA_ITEM_ID); - item->kw = util_alloc_string_copy(kw); - - item->append_arg = append_arg; - item->required_set = required; - item->required_children = NULL; - item->required_children_value = NULL; - item->expand_envvar = true; /* Default is to expand $VAR expressions; can be turned off with - config_schema_item_set_envvar_expansion( item , false ); */ - item->validate = validate_alloc(); - return item; -} - - - -/* - Observe that this function is a bit funny - because it will - actually free the incoming message. -*/ - -static void config_add_and_free_error(config_type * config , char * error_message) { - if (error_message != NULL) { - int error_nr = stringlist_get_size(config->parse_errors) + 1; - stringlist_append_owned_ref(config->parse_errors , util_alloc_sprintf(" %02d: %s" , error_nr , error_message)); - free(error_message); - } -} - - - -/** - This function validates the setting of an item. If the item is OK NULL is returned, - otherwise an error message is returned. -*/ - -static bool config_schema_item_validate_set(config_type * config , const config_schema_item_type * item , stringlist_type * token_list , const char * config_file, const char * config_cwd) { - bool OK = true; - int argc = stringlist_get_size( token_list ) - 1; - if (item->validate->argc_min >= 0) { - if (argc < item->validate->argc_min) { - OK = false; - if (config_file != NULL) - config_add_and_free_error(config , util_alloc_sprintf("Error when parsing config_file:\"%s\" Keyword:%s must have at least %d arguments.",config_file , item->kw , item->validate->argc_min)); - else - config_add_and_free_error(config , util_alloc_sprintf("Error:: Keyword:%s must have at least %d arguments.",item->kw , item->validate->argc_min)); - } - } - - if (item->validate->argc_max >= 0) { - if (argc > item->validate->argc_max) { - OK = false; - if (config_file != NULL) - config_add_and_free_error(config , util_alloc_sprintf("Error when parsing config_file:\"%s\" Keyword:%s must have maximum %d arguments.",config_file , item->kw , item->validate->argc_max)); - else - config_add_and_free_error(config , util_alloc_sprintf("Error:: Keyword:%s must have maximum %d arguments.",item->kw , item->validate->argc_max)); - } - } - - /* - OK - now we have verified that the number of arguments is correct. Then - we start actually looking at the values. - */ - - if (OK) { - /* Validating selection set - first common, then indexed */ - if (item->validate->common_selection_set) { - for (int iarg = 0; iarg < argc; iarg++) { - if (!set_has_key(item->validate->common_selection_set , stringlist_iget( token_list , iarg + 1))) { - config_add_and_free_error(config , util_alloc_sprintf("%s: is not a valid value for: %s.",stringlist_iget( token_list , iarg + 1) , item->kw)); - OK = false; - } - } - } else if (item->validate->indexed_selection_set != NULL) { - for (int iarg = 0; iarg < argc; iarg++) { - if ((item->validate->argc_max > 0) || (iarg < item->validate->argc_min)) { /* Without this test we might go out of range on the indexed selection set. */ - if (item->validate->indexed_selection_set[iarg] != NULL) { - if (!set_has_key(item->validate->indexed_selection_set[iarg] , stringlist_iget( token_list , iarg + 1))) { - config_add_and_free_error(config , util_alloc_sprintf("%s: is not a valid value for item %d of \'%s\'.",stringlist_iget( token_list , iarg + 1) , iarg + 1 , item->kw)); - OK = false; - } - } - } - } - } - - /* - Observe that the following code might rewrite the content of - argv for arguments referring to path locations. - */ - - - /* Validate the TYPE of the various argumnents */ - if (item->validate->type_map != NULL) { - for (int iarg = 0; iarg < argc; iarg++) { - if (iarg < item->validate->type_map_size) { - const char * value = stringlist_iget(token_list , iarg + 1); - switch (item->validate->type_map[iarg]) { - case(CONFIG_STRING): /* This never fails ... */ - break; - case(CONFIG_EXECUTABLE): - { - /* - 1. If the supplied value is an abolute path - do nothing. - 2. If the supplied is _not_ an absolute path: - - a. Try if the relocated exists - then use that. - b. Else - try if the util_alloc_PATH_executable() exists. - */ - if (!util_is_abs_path( value )) { - char * relocated = __alloc_relocated__(config_cwd , value); - char * path_exe = util_alloc_PATH_executable( value ); - - if (util_file_exists(relocated)) { - if (util_is_executable(relocated)) - stringlist_iset_copy( token_list , iarg , relocated); - } else if (path_exe != NULL) - stringlist_iset_copy( token_list , iarg , path_exe); - else - config_add_and_free_error(config , util_alloc_sprintf("Could not locate executable:%s ", value)); - - free(relocated); - util_safe_free(path_exe); - } else { - if (!util_is_executable( value )) - config_add_and_free_error(config , util_alloc_sprintf("Could not locate executable:%s ", value)); - } - } - break; - case(CONFIG_INT): - if (!util_sscanf_int( value , NULL )) - config_add_and_free_error(config , util_alloc_sprintf("Failed to parse:%s as an integer.",value)); - break; - case(CONFIG_FLOAT): - if (!util_sscanf_double( value , NULL )) - config_add_and_free_error(config , util_alloc_sprintf("Failed to parse:%s as a floating point number.", value)); - break; - case(CONFIG_EXISTING_FILE): - { - char * file = __alloc_relocated__(config_cwd , value); - if (!util_file_exists(file)) - config_add_and_free_error(config , util_alloc_sprintf("Can not find file %s in %s ",value , config_cwd)); - else - stringlist_iset_copy( token_list , iarg + 1 , file); - free( file ); - } - break; - case(CONFIG_FILE): - { - char * file = __alloc_relocated__(config_cwd , value); - stringlist_iset_copy( token_list , iarg + 1 , file); - free( file ); - } - break; - case(CONFIG_EXISTING_DIR): - { - char * dir = __alloc_relocated__(config_cwd , value); - if (!util_is_directory(value)) - config_add_and_free_error(config , util_alloc_sprintf("Can not find directory: %s. ",value)); - else - stringlist_iset_copy( token_list , iarg + 1 , dir); - free( dir ); - } - break; - case(CONFIG_BOOLEAN): - if (!util_sscanf_bool( value , NULL )) - config_add_and_free_error(config , util_alloc_sprintf("Failed to parse:%s as a boolean.", value)); - break; - case(CONFIG_BYTESIZE): - if (!util_sscanf_bytesize( value , NULL)) - config_add_and_free_error(config , util_alloc_sprintf("Failed to parse:\"%s\" as number of bytes." , value)); - break; - default: - util_abort("%s: config_item_type:%d not recognized \n",__func__ , item->validate->type_map[iarg]); - } - } - } - } - } - return OK; -} - - - - - - - - - - - - -void config_schema_item_free( config_schema_item_type * item) { - free(item->kw); - if (item->required_children != NULL) stringlist_free(item->required_children); - if (item->required_children_value != NULL) hash_free(item->required_children_value); - validate_free(item->validate); - free(item); -} - - - -static UTIL_SAFE_CAST_FUNCTION( config_schema_item , CONFIG_SCHEMA_ITEM_ID) - -void config_schema_item_free__ (void * void_item) { - config_schema_item_type * item = config_schema_item_safe_cast( void_item ); - config_schema_item_free( item ); -} - - -bool config_content_item_is_set(const config_content_item_type * item) { - return item->currently_set; -} - -void config_schema_item_set_common_selection_set(config_schema_item_type * item , int argc , const char ** argv) { - validate_set_common_selection_set(item->validate , argc , argv); -} - -void config_schema_item_set_indexed_selection_set(config_schema_item_type * item , int index , int argc , const char ** argv) { - validate_set_indexed_selection_set(item->validate , index , argc , argv); -} - - -void config_schema_item_set_required_children(config_schema_item_type * item , stringlist_type * stringlist) { - item->required_children = stringlist_alloc_deep_copy(stringlist); -} - -void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key) { - if (item->required_children == NULL) - item->required_children = stringlist_alloc_new(); - - stringlist_append_copy( item->required_children , child_key ); -} - - - -/** - This works in the following way: - - if item == value { - All children in child_list must also be set. - } - - -*/ - -void config_schema_item_set_required_children_on_value(config_schema_item_type * item , const char * value , stringlist_type * child_list) { - if (item->required_children_value == NULL) - item->required_children_value = hash_alloc(); - hash_insert_hash_owned_ref( item->required_children_value , value , stringlist_alloc_deep_copy(child_list) , stringlist_free__); -} - - - -/** - This function is used to set the minimum and maximum number of - arguments for an item. In addition you can pass in a pointer to an - array of config_schema_item_types values which will be used for validation - of the input. This vector must be argc_max elements long; it can be - NULL. -*/ - - -void config_schema_item_set_argc_minmax(config_schema_item_type * item , int argc_min , int argc_max, int type_map_size , const config_item_types * type_map) { - validate_set_argc_minmax(item->validate , argc_min , argc_max , type_map_size , type_map); -} - - - -void config_schema_item_set_envvar_expansion( config_schema_item_type * item , bool expand_envvar ) { - item->expand_envvar = expand_envvar; -} - - - -/*****************************************************************/ -/* section:content_item */ - -/** - This function counts the number of times a config item has been - set. Referring again to the example at the top: - - config_content_item_get_occurences( "KEY1" ) - - will return 2. However, if the item has been added with append_arg - set to false, this function can only return zero or one. -*/ - - -static int config_content_item_get_occurences(const config_content_item_type * item) { - return item->node_size; -} - - -static config_item_node_type * config_content_item_iget_node(const config_content_item_type * item , int index) { - if (index < 0 || index >= item->node_size) - util_abort("%s: error - asked for node nr:%d available: [0,%d> \n",__func__ , index , item->node_size); - return item->nodes[index]; -} - - -static char * config_content_item_ialloc_joined_string(const config_content_item_type * item , const char * sep , int occurence) { - config_item_node_type * node = config_content_item_iget_node(item , occurence); - return config_item_node_alloc_joined_string(node , sep); -} - - - -static char * config_content_item_alloc_joined_string(const config_content_item_type * item , const char * sep) { - const int occurences = config_content_item_get_occurences( item ); - char * joined_string = NULL; - - for (int i =0; i < occurences ; i++) { - joined_string = util_strcat_realloc( joined_string , config_content_item_ialloc_joined_string(item , sep , i)); - if (i < (occurences - 1)) - joined_string = util_strcat_realloc( joined_string , sep ); - } - - return joined_string; -} - -static stringlist_type * config_content_item_iget_stringlist_ref(const config_content_item_type * item, int occurence) { - config_item_node_type * node = config_content_item_iget_node(item , occurence); - return node->stringlist; -} - - -static const stringlist_type * config_content_item_get_stringlist_ref(const config_content_item_type * item) { - if (item->schema->append_arg) - util_abort("%s: this function can only be used on items added with append_arg == FALSE\n" , __func__); - return config_content_item_iget_stringlist_ref(item , 0); -} - - -/** - If copy == false - the stringlist will break down when/if the - config object is freed - your call. -*/ - -static stringlist_type * config_content_item_alloc_complete_stringlist(const config_content_item_type * item, bool copy) { - int inode; - stringlist_type * stringlist = stringlist_alloc_new(); - for (inode = 0; inode < item->node_size; inode++) { - - if (copy) - stringlist_append_stringlist_copy( stringlist , item->nodes[inode]->stringlist ); - else - stringlist_append_stringlist_ref( stringlist , item->nodes[inode]->stringlist ); - - } - - return stringlist; -} - - -/** - If copy == false - the stringlist will break down when/if the - config object is freed - your call. -*/ - -static stringlist_type * config_content_item_alloc_stringlist(const config_content_item_type * item, bool copy) { - if (item->schema->append_arg) { - util_abort("%s: item:%s must be initialized with append_arg == false for this call. \n",__func__); - return NULL; - } else { - stringlist_type * stringlist = stringlist_alloc_new(); - - if (copy) - stringlist_append_stringlist_copy( stringlist , item->nodes[0]->stringlist ); - else - stringlist_append_stringlist_ref( stringlist , item->nodes[0]->stringlist ); - - return stringlist; - } -} - - -/** - If copy == false - the hash will break down when/if the - config object is freed - your call. -*/ - -static hash_type * config_content_item_alloc_hash(const config_content_item_type * item , bool copy) { - hash_type * hash = hash_alloc(); - int inode; - for (inode = 0; inode < item->node_size; inode++) { - const config_item_node_type * node = item->nodes[inode]; - - if (copy) { - hash_insert_hash_owned_ref(hash , - stringlist_iget(node->stringlist , 0) , - util_alloc_string_copy(stringlist_iget(node->stringlist , 1)) , - free); - } else - hash_insert_ref(hash , stringlist_iget(node->stringlist , 0) , stringlist_iget(node->stringlist , 1)); - - } - return hash; -} - - - - -static void config_content_item_realloc_nodes(config_content_item_type * item , int new_size) { - const int old_size = item->alloc_size; - item->nodes = util_realloc(item->nodes , sizeof * item->nodes * new_size ); - item->alloc_size = new_size; - { - int i; - for (i=old_size; i < new_size; i++) - item->nodes[i] = NULL; - } -} - - - - - -/* - This function will fail item has not been allocated - append_arg == false. -*/ - -static const char * config_content_item_iget(const config_content_item_type * item , int occurence , int index) { - config_item_node_type * node = config_content_item_iget_node(item , occurence); - return stringlist_iget( node->stringlist , index ); -} - - - -static bool config_content_item_iget_as_bool(const config_content_item_type * item, int occurence , int index) { - bool value; - config_schema_item_assure_type(item->schema , index , CONFIG_BOOLEAN); - util_sscanf_bool( config_content_item_iget(item , occurence ,index) , &value ); - return value; -} - - -static int config_content_item_iget_as_int(const config_content_item_type * item, int occurence , int index) { - int value; - config_schema_item_assure_type(item->schema , index , CONFIG_INT); - util_sscanf_int( config_content_item_iget(item , occurence , index) , &value ); - return value; -} - - -static double config_content_item_iget_as_double(const config_content_item_type * item, int occurence , int index) { - double value; - config_schema_item_assure_type(item->schema , index , CONFIG_FLOAT); - util_sscanf_double( config_content_item_iget(item , occurence , index) , &value ); - return value; -} - - -static void config_content_item_validate(config_type * config , const config_content_item_type * item) { - const config_schema_item_type * schema_item = item->schema; - if (item->currently_set) { - if (schema_item->required_children != NULL) { - int i; - for (i = 0; i < stringlist_get_size(schema_item->required_children); i++) { - if (!config_has_set_item(config , stringlist_iget(schema_item->required_children , i))) { - char * error_message = util_alloc_sprintf("When:%s is set - you also must set:%s.",schema_item->kw , stringlist_iget(schema_item->required_children , i)); - config_add_and_free_error(config , error_message); - } - } - } - - if (schema_item->required_children_value != NULL) { - int inode; - for (inode = 0; inode < config_content_item_get_occurences(item); inode++) { - config_item_node_type * node = config_content_item_iget_node(item , inode); - stringlist_type * values = node->stringlist; - int is; - - for (is = 0; is < stringlist_get_size(values); is++) { - const char * value = stringlist_iget(values , is); - if (hash_has_key(schema_item->required_children_value , value)) { - stringlist_type * children = hash_get(schema_item->required_children_value , value); - int ic; - for (ic = 0; ic < stringlist_get_size( children ); ic++) { - const char * req_child = stringlist_iget( children , ic ); - if (!config_has_set_item(config , req_child )) { - char * error_message = util_alloc_sprintf("When:%s is set to:%s - you also must set:%s.",schema_item->kw , value , req_child ); - config_add_and_free_error(config , error_message); - } - } - } - } - } - } - } else if (schema_item->required_set) { /* The item is not set ... */ - char * error_message = util_alloc_sprintf("Item:%s must be set - parsing:%s",schema_item->kw , config->abs_path); - config_add_and_free_error(config , error_message); - } -} /** Adds a new node as side-effect ... */ -static config_item_node_type * config_content_item_get_new_node(config_content_item_type * item) { - if (item->node_size == item->alloc_size) - config_content_item_realloc_nodes(item , item->alloc_size * 2); - { - config_item_node_type * new_node = config_item_node_alloc(); - item->nodes[item->node_size] = new_node; - item->node_size++; - return new_node; - } +static config_content_node_type * config_get_new_content_node(config_type * config , config_content_item_type * item) { + config_content_node_type * new_node = config_content_item_alloc_node( item , config_content_item_get_path_elm( item )); + vector_append_ref( config->content_list , new_node ); + return new_node; } -static config_item_node_type * config_content_item_get_first_node(config_content_item_type * item) { - - if (item->node_size == 0) - config_content_item_get_new_node(item); - - return config_content_item_iget_node(item , 0); -} - -/** - Used to reset an item is the special string 'CLEAR_STRING' - is found as the only argument: - - OPTION V1 - OPTION V2 V3 V4 - OPTION __RESET__ - OPTION V6 - - In this case OPTION will get the value 'V6'. The example given - above is a bit contrived; this option is designed for situations - where several config files are parsed serially; and the user can - not/will not update the first. -*/ - -static void config_content_item_clear( config_content_item_type * item ) { - int i; - for (i = 0; i < item->node_size; i++) - config_item_node_free( item->nodes[i] ); - util_safe_free(item->nodes); - item->nodes = NULL; - item->node_size = 0; - item->currently_set = false; - config_content_item_realloc_nodes(item , 1); -} -static void config_content_item_free( config_content_item_type * item ) { - int i; - for (i = 0; i < item->node_size; i++) - config_item_node_free( item->nodes[i] ); - free(item->nodes); - free(item); -} - - -static UTIL_SAFE_CAST_FUNCTION( config_content_item , CONFIG_CONTENT_ITEM_ID); - - -static void config_content_item_free__( void * arg ) { - config_content_item_type * content_item = config_content_item_safe_cast( arg ); - config_content_item_free( content_item ); -} - - -static config_content_item_type * config_content_item_alloc( const config_schema_item_type * schema ) { - config_content_item_type * content_item = util_malloc( sizeof * content_item ); - UTIL_TYPE_ID_INIT( content_item , CONFIG_CONTENT_ITEM_ID ); - content_item->schema = schema; - - content_item->alloc_size = 0; - content_item->node_size = 0; - content_item->nodes = NULL; - content_item->currently_set = false; - config_content_item_realloc_nodes(content_item , 1); - return content_item; -} - /* @@ -998,23 +181,17 @@ static config_content_item_type * config_content_item_alloc( const config_schema calling scope will free it. */ -static void config_content_item_set_arg__(config_type * config , config_content_item_type * item , stringlist_type * token_list , const char * config_file , const char * config_cwd) { +static void config_content_item_set_arg__(config_type * config , config_content_item_type * item , stringlist_type * token_list , + const config_path_elm_type * path_elm , + const char * config_file ) { + int argc = stringlist_get_size( token_list ) - 1; if (argc == 1 && (strcmp(stringlist_iget(token_list , 1) , CLEAR_STRING) == 0)) { config_content_item_clear(item); } else { - config_item_node_type * node; - const config_schema_item_type * schema_item = item->schema; + const config_schema_item_type * schema_item = config_content_item_get_schema( item ); - if (schema_item->append_arg) - node = config_content_item_get_new_node(item); - else { - node = config_content_item_get_first_node(item); - config_item_node_clear(node); - } - - /* Filtering based on DEFINE statements */ if (subst_list_get_size( config->define_list ) > 0) { int iarg; @@ -1026,7 +203,7 @@ static void config_content_item_set_arg__(config_type * config , config_content_ /* Filtering based on environment variables */ - if (schema_item->expand_envvar) { + if (config_schema_item_expand_envvar( schema_item )) { int iarg; for (iarg = 0; iarg < argc; iarg++) { int env_offset = 0; @@ -1046,15 +223,12 @@ static void config_content_item_set_arg__(config_type * config , config_content_ } while (env_var != NULL); } } - - if (config_schema_item_validate_set(config , schema_item , token_list , config_file, config_cwd)) { - config_item_node_set(node , token_list); - item->currently_set = true; - if (config_cwd != NULL) - node->config_cwd = util_alloc_string_copy( config_cwd ); - else - node->config_cwd = util_alloc_cwd( ); /* For use from external scope. */ + { + if (config_schema_item_validate_set(schema_item , token_list , config_file, path_elm , config->parse_errors)) { + config_content_node_type * node = config_get_new_content_node(config , item); + config_content_node_set(node , token_list); + } } } } @@ -1068,38 +242,48 @@ static void config_content_item_set_arg__(config_type * config , config_content_ config_type * config_alloc() { - config_type *config = util_malloc(sizeof * config ); + config_type *config = util_malloc(sizeof * config ); + config->content_list = vector_alloc_new(); + config->path_elm_storage = vector_alloc_new(); + config->path_elm_stack = vector_alloc_new(); + config->schema_items = hash_alloc(); config->content_items = hash_alloc(); - config->parse_errors = stringlist_alloc_new(); + config->parse_errors = config_error_alloc(); config->parsed_files = set_alloc_empty(); config->messages = hash_alloc(); config->define_list = subst_list_alloc( NULL ); config->config_file = NULL; config->abs_path = NULL; + config->invoke_path = NULL; return config; } + + static void config_clear_content_items( config_type * config ) { - hash_iter_type * item_iter = hash_iter_alloc( config->content_items ); - while (!hash_iter_is_complete( item_iter )) { - config_content_item_type * item = hash_iter_get_next_value( item_iter ); - config_content_item_clear( item ); - } - hash_iter_free( item_iter ); + hash_free( config->content_items ); + config->content_items = hash_alloc(); + vector_clear( config->content_list ); } void config_clear(config_type * config) { - stringlist_clear(config->parse_errors); + config_error_clear(config->parse_errors); set_clear(config->parsed_files); subst_list_clear( config->define_list ); config_clear_content_items( config ); - + vector_clear( config->path_elm_storage ); + vector_clear( config->path_elm_stack ); + util_safe_free( config->config_file ); util_safe_free( config->abs_path ); + if (config->invoke_path != NULL) { + config_root_path_free( config->invoke_path ); + config->invoke_path = NULL; + } config->config_file = NULL; config->abs_path = NULL; } @@ -1107,10 +291,13 @@ void config_clear(config_type * config) { void config_free(config_type * config) { - stringlist_free( config->parse_errors ); + config_error_free( config->parse_errors ); set_free(config->parsed_files); subst_list_free( config->define_list ); + vector_free( config->path_elm_storage ); + vector_free( config->path_elm_stack ); + vector_free( config->content_list ); hash_free(config->schema_items); hash_free(config->content_items); hash_free(config->messages); @@ -1139,10 +326,9 @@ static void config_insert_schema_item(config_type * config , const char * kw , c config_schema_item_type * config_add_schema_item(config_type * config , const char * kw, - bool required , - bool append_arg) { + bool required) { - config_schema_item_type * item = config_schema_item_alloc( kw , required , append_arg); + config_schema_item_type * item = config_schema_item_alloc( kw , required ); config_insert_schema_item(config , kw , item , false); return item; } @@ -1153,15 +339,15 @@ config_schema_item_type * config_add_schema_item(config_type * config , This is a minor wrapper for adding an item with the properties. 1. It has argc_minmax = {1,1} - 2. It has append == false. The value can than be extracted with config_get_value() and config_get_value_as_xxxx functions. */ config_schema_item_type * config_add_key_value( config_type * config , const char * key , bool required , config_item_types item_type) { - config_schema_item_type * item = config_add_schema_item( config , key , required , false ); - config_schema_item_set_argc_minmax( item , 1 , 1 , 1 , (const config_item_types [1]) { item_type }); + config_schema_item_type * item = config_add_schema_item( config , key , required ); + config_schema_item_set_argc_minmax( item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , item_type ); return item; } @@ -1177,26 +363,56 @@ config_schema_item_type * config_get_schema_item(const config_type * config , co } /* - Will add if not exists. Due to the possibility of aliases we must go - through the canonical keyword which is internalized in the schema_item. + Due to the possibility of aliases we must go through the canonical + keyword which is internalized in the schema_item. */ -static config_content_item_type * config_get_content_item( const config_type * config , const char * input_kw) { + +static config_content_item_type * config_add_content_item( const config_type * config , const char * input_kw, const config_path_elm_type * path_elm) { config_schema_item_type * schema_item = config_get_schema_item( config , input_kw ); - const char * kw = schema_item->kw; + const char * kw = config_schema_item_get_kw( schema_item ); + config_content_item_type * content_item = config_content_item_alloc( schema_item , path_elm ); + hash_insert_hash_owned_ref( config->content_items , kw , content_item , config_content_item_free__ ); - if (!hash_has_key( config->content_items , kw)) { - config_content_item_type * content_item = config_content_item_alloc( schema_item ); - hash_insert_hash_owned_ref( config->content_items , kw , content_item , config_content_item_free__ ); - } - - return hash_get( config->content_items , kw ); + return content_item; } +bool config_has_content_item( const config_type * config , const char * input_kw) { + if (config_has_schema_item( config , input_kw )) { + config_schema_item_type * schema_item = config_get_schema_item( config , input_kw ); + const char * kw = config_schema_item_get_kw( schema_item ); + return hash_has_key( config->content_items , kw ); + } else + return false; +} + + +config_content_item_type * config_get_content_item( const config_type * config , const char * input_kw) { + if (config_has_schema_item( config , input_kw )) { + config_schema_item_type * schema_item = config_get_schema_item( config , input_kw ); + const char * kw = config_schema_item_get_kw( schema_item ); + + if (hash_has_key( config->content_items , kw )) + return hash_get( config->content_items , kw ); + else + return NULL; + + } else + return NULL; +} + + + bool config_item_set(const config_type * config , const char * kw) { - config_content_item_type * content_item = config_get_content_item( config , kw ); - return config_content_item_is_set( content_item ); + if (config_has_content_item(config , kw)) { + const config_content_item_type * item = config_get_content_item( config , kw ); + if (config_content_item_get_size( item )) + return true; + else + return false; // The item exists - but it has size zero. + } else + return false; } @@ -1218,7 +434,7 @@ char ** config_alloc_active_list(const config_type * config, int * _active_size) int i; for( i = 0; i < complete_size; i++) { - if (config_content_item_is_set(config_get_content_item(config , complete_key_list[i]) )) { + if (config_has_content_item( config , complete_key_list[i])) { active_key_list = util_stringlist_append_copy(active_key_list , active_size , complete_key_list[i]); active_size++; } @@ -1231,27 +447,102 @@ char ** config_alloc_active_list(const config_type * config, int * _active_size) +static void config_validate_content_item(const config_type * config , const config_content_item_type * item) { + const config_schema_item_type * schema_item = config_content_item_get_schema( item ); + const char * schema_kw = config_schema_item_get_kw( schema_item ); + + { + int i; + for (i = 0; i < config_schema_item_num_required_children(schema_item); i++) { + const char * required_child = config_schema_item_iget_required_child( schema_item , i ); + if (!config_item_set(config , required_child)) { + char * error_message = util_alloc_sprintf("When:%s is set - you also must set:%s.",schema_kw , required_child); + config_error_add( config->parse_errors , error_message ); + } + } + + if (config_schema_item_has_required_children_value( schema_item )) { + int inode; + for (inode = 0; inode < config_content_item_get_size(item); inode++) { + config_content_node_type * node = config_content_item_iget_node(item , inode); + const stringlist_type * values = config_content_node_get_stringlist( node ); + int is; + + for (is = 0; is < stringlist_get_size(values); is++) { + const char * value = stringlist_iget(values , is); + stringlist_type * required_children = config_schema_item_get_required_children_value( schema_item , value ); + + if (required_children != NULL) { + int ic; + for (ic = 0; ic < stringlist_get_size( required_children ); ic++) { + const char * req_child = stringlist_iget( required_children , ic ); + if (!config_item_set(config , req_child )) { + char * error_message = util_alloc_sprintf("When:%s is set to:%s - you also must set:%s.",schema_kw , value , req_child ); + config_error_add( config->parse_errors , error_message ); + } + } + } + } + } + } + } +} + + + static void config_validate(config_type * config, const char * filename) { int size = hash_get_size(config->schema_items); char ** key_list = hash_alloc_keylist(config->schema_items); int ikey; for (ikey = 0; ikey < size; ikey++) { - const config_content_item_type * item = config_get_content_item(config , key_list[ikey]); - config_content_item_validate(config , item); + if (config_has_content_item( config , key_list[ikey])) { + const config_content_item_type * item = config_get_content_item(config , key_list[ikey]); + config_validate_content_item(config , item ); + } else { + const config_schema_item_type * schema_item = config_get_schema_item( config , key_list[ikey]); + if (config_schema_item_required( schema_item)) { /* The item is not set ... */ + const char * schema_kw = config_schema_item_get_kw( schema_item ); + char * error_message = util_alloc_sprintf("Item:%s must be set - parsing:%s",schema_kw , config->abs_path); + config_error_add( config->parse_errors , error_message ); + } + } } util_free_stringlist(key_list , size); - - if (stringlist_get_size(config->parse_errors) > 0) { - fprintf(stderr,"Parsing errors in configuration file \'%s\':\n" , filename); - stringlist_fprintf(config->parse_errors , "\n", stderr); - util_exit(""); - } - } +static config_path_elm_type * config_add_path_elm( config_type * config , const char * path ) { + const config_path_elm_type * current_path_elm; + + if (vector_get_size( config->path_elm_stack ) == 0) + current_path_elm = NULL; + else + current_path_elm = vector_get_last_const(config->path_elm_stack); + + { + config_path_elm_type * new_path_elm; + + { + char * rel_path = NULL; + if (path != NULL) { + if (current_path_elm == NULL) + rel_path = util_alloc_rel_path( config_root_path_get_abs_path(config->invoke_path) , path); + else + rel_path = config_path_elm_alloc_relpath( current_path_elm , path ); + } + new_path_elm = config_path_elm_alloc( config->invoke_path , rel_path ); + util_safe_free( rel_path ); + } + vector_append_owned_ref( config->path_elm_storage , new_path_elm , config_path_elm_free__); + vector_append_ref( config->path_elm_stack , new_path_elm ); + return new_path_elm; + } +} + + + /** This function parses the config file 'filename', and updated the internal state of the config object as parsing proceeds. If @@ -1319,101 +610,106 @@ static void config_validate(config_type * config, const char * filename) { After parsing we will have an entry: "NAME" , "Bjarne" , "28" , "Dogs". - The key-value pairs internalized during the config parsing are NOT + The key-value pairs internalized during the config parsing are NOT returned to the calling scope in any way. */ static void config_parse__(config_type * config , - const char * config_cwd , - const char * _config_file, + path_stack_type * path_stack , + const char * config_input , const char * comment_string , const char * include_kw , const char * define_kw , - bool warn_unrecognized, + config_schema_unrecognized_enum unrecognized, bool validate) { - char * config_file = util_alloc_filename(config_cwd , _config_file , NULL); - char * abs_filename = util_alloc_realpath(config_file); - parser_type * parser = parser_alloc(" \t" , "\"", NULL , NULL , "--" , "\n"); - if (!set_add_key(config->parsed_files , abs_filename)) - util_exit("%s: file:%s already parsed - circular include ? \n",__func__ , config_file); - else { + /* Guard against circular includes. */ + { + char * abs_filename = util_alloc_realpath(config_input); + if (!set_add_key(config->parsed_files , abs_filename)) + util_exit("%s: file:%s already parsed - circular include ? \n",__func__ , abs_filename); + free( abs_filename ); + } + config_path_elm_type * current_path_elm; + + char * config_file; + { + /* Extract the path component of the current input file and chdir() */ + char * config_path; + { + char * config_base; + char * config_ext; + util_alloc_file_components( config_input , &config_path , &config_base , &config_ext); + config_file = util_alloc_filename( NULL , config_base , config_ext ); + free( config_base ); + util_safe_free( config_ext ); + } + current_path_elm = config_add_path_elm( config , config_path ); + path_stack_push_cwd( path_stack ); + if (config_path != NULL) { + chdir( config_path ); + free( config_path ); + } + } + + + { + parser_type * parser = parser_alloc(" \t" , "\"", NULL , NULL , "--" , "\n"); FILE * stream = util_fopen(config_file , "r"); bool at_eof = false; - + while (!at_eof) { int active_tokens; stringlist_type * token_list; char *line_buffer; - + line_buffer = util_fscanf_alloc_line(stream , &at_eof); if (line_buffer != NULL) { token_list = parser_tokenize_buffer(parser , line_buffer , true); active_tokens = stringlist_get_size( token_list ); - + /* - util_split_string(line_buffer , " \t" , &tokens , &token_list); - active_tokens = tokens; - for (i = 0; i < tokens; i++) { + util_split_string(line_buffer , " \t" , &tokens , &token_list); + active_tokens = tokens; + for (i = 0; i < tokens; i++) { char * comment_ptr = NULL; if(comment_string != NULL) - comment_ptr = strstr(token_list[i] , comment_string); + comment_ptr = strstr(token_list[i] , comment_string); if (comment_ptr != NULL) { - if (comment_ptr == token_list[i]) - active_tokens = i; - else - active_tokens = i + 1; - break; + if (comment_ptr == token_list[i]) + active_tokens = i; + else + active_tokens = i + 1; + break; } } */ - + if (active_tokens > 0) { const char * kw = stringlist_iget( token_list , 0 ); - + /*Treating the include keyword. */ if (include_kw != NULL && (strcmp(include_kw , kw) == 0)) { if (active_tokens != 2) util_abort("%s: keyword:%s must have exactly one argument. \n",__func__ ,include_kw); { - char *include_path = NULL; - char *extension = NULL; - char *include_file = NULL; - - { - char * tmp_path; - char * tmp_file; - util_alloc_file_components(stringlist_iget(token_list , 1) , &tmp_path , &tmp_file , &extension); - - /* Allocating a new path with current config_cwd and the (relative) path to the new config_file */ - if (tmp_path == NULL) - include_path = util_alloc_string_copy( config_cwd ); - else { - if (!util_is_abs_path(tmp_path)) - include_path = util_alloc_filename(config_cwd , tmp_path , NULL); - else - include_path = util_alloc_string_copy(tmp_path); - } - - include_file = util_alloc_filename(NULL , tmp_file , extension); - free(tmp_file); - free(tmp_path); - } - - config_parse__(config , include_path , include_file , comment_string , include_kw , define_kw , warn_unrecognized, false); /* Recursive call */ - util_safe_free(include_file); - util_safe_free(include_path); + const char *include_file = stringlist_iget( token_list , 1); + if (util_file_exists( include_file )) + config_parse__(config , path_stack , include_file , comment_string , include_kw , define_kw , unrecognized, false); /* Recursive call */ + else + config_error_add(config->parse_errors , util_alloc_sprintf("%s file:%s not found" , include_kw , include_file)); } } else if ((define_kw != NULL) && (strcmp(define_kw , kw) == 0)) { + /* Treating the define keyword. */ if (active_tokens < 3) util_abort("%s: keyword:%s must have exactly one (or more) arguments. \n",__func__ , define_kw); { char * key = util_alloc_string_copy( stringlist_iget(token_list ,1) ); char * value = stringlist_alloc_joined_substring( token_list , 2 , active_tokens , " "); - + { char * filtered_value = subst_list_alloc_filtered_string( config->define_list , value); config_add_define( config , key , filtered_value ); @@ -1425,15 +721,26 @@ static void config_parse__(config_type * config , } else { if (hash_has_key(config->messages , kw)) printf("%s \n", (const char *) hash_get(config->messages , kw)); - + if (!config_has_schema_item(config , kw)) { - if (warn_unrecognized) - fprintf(stderr,"** Warning keyword:%s not recognized when parsing:%s --- \n" , kw , config_file); + if (unrecognized == CONFIG_UNRECOGNIZED_WARN) + fprintf(stderr,"** Warning keyword:%s not recognized when parsing:%s --- \n" , kw , config_input); + else if (unrecognized == CONFIG_UNRECOGNIZED_ERROR) + config_error_add(config->parse_errors , util_alloc_sprintf("Keyword:%s is not recognized" , kw)); + } - + if (config_has_schema_item(config , kw)) { - config_content_item_type * content_item = config_get_content_item( config , kw ); - config_content_item_set_arg__(config , content_item , token_list , config_file , config_cwd); + char * config_cwd; + util_alloc_file_components( config_file , &config_cwd , NULL , NULL ); + + if (!config_has_content_item( config , kw )) + config_add_content_item( config , kw , current_path_elm ); + + { + config_content_item_type * content_item = config_get_content_item( config , kw ); + config_content_item_set_arg__(config , content_item , token_list , current_path_elm , config_file ); + } } } } @@ -1441,24 +748,32 @@ static void config_parse__(config_type * config , free(line_buffer); } } - if (validate) config_validate(config , config_file); + if (validate) + config_validate(config , config_file); fclose(stream); + parser_free( parser ); } - parser_free( parser ); - free(abs_filename); free(config_file); + path_stack_pop( path_stack ); + vector_pop( config->path_elm_stack ); } static void config_set_config_file( config_type * config , const char * config_file ) { config->config_file = util_realloc_string_copy( config->config_file , config_file ); - util_safe_free(config->abs_path); config->abs_path = util_alloc_abs_path( config_file ); } +static void config_set_invoke_path( config_type * config ) { + if (config->invoke_path != NULL) + config_root_path_free( config->invoke_path ); + config->invoke_path = config_root_path_alloc( NULL ); +} + + const char * config_get_config_file( const config_type * config , bool abs_path) { if (abs_path) return config->abs_path; @@ -1467,56 +782,35 @@ const char * config_get_config_file( const config_type * config , bool abs_path) } -void config_parse(config_type * config , - const char * filename, - const char * comment_string , - const char * include_kw , - const char * define_kw , - bool warn_unrecognized, - bool validate) { - char * config_path; - char * config_file; - char * tmp_file; - char * extension; - util_alloc_file_components(filename , &config_path , &tmp_file , &extension); - config_set_config_file( config , filename ); - config_file = util_alloc_filename(NULL , tmp_file , extension); - config_parse__(config , config_path , config_file , comment_string , include_kw , define_kw , warn_unrecognized , validate); - - util_safe_free(tmp_file); - util_safe_free(extension); - util_safe_free(config_path); - util_safe_free(config_file); +void config_fprintf_errors( const config_type * config , bool add_count , FILE * stream ) { + config_error_fprintf( config->parse_errors , add_count , stderr ); } -bool config_has_keys(const config_type * config, const char **ext_keys, int ext_num_keys, bool exactly) -{ - int i; - - int config_num_keys; - char ** config_keys; - - config_keys = config_alloc_active_list(config, &config_num_keys); - - if(exactly && (config_num_keys != ext_num_keys)) - { - util_free_stringlist(config_keys,config_num_keys); - return false; - } - - for(i=0; iparse_errors , util_alloc_sprintf("Could not open file:%s for parsing" , filename)); + + if (config_error_count( config->parse_errors ) == 0) + return true; // No errors + else + return false; // There were parse errors. } @@ -1535,7 +829,6 @@ bool config_has_keys(const config_type * config, const char **ext_keys, int ext_ parameter. But to ensure that the get is unambigous we set the following requirements to the item corresponding to 'kw': - * It has been added with append_arg == false. * argc_minmax has been set to 1,1 If this is not the case - we die. @@ -1586,6 +879,7 @@ const char * config_iget(const config_type * config , const char * kw, int occur } + /** This function will return NULL is the item has not been set, however it must be installed with config_add_schema_item(). @@ -1593,73 +887,18 @@ const char * config_iget(const config_type * config , const char * kw, int occur const char * config_safe_iget(const config_type * config , const char *kw, int occurence , int index) { const char * value = NULL; - config_content_item_type * item = config_get_content_item(config , kw); - if (config_content_item_is_set(item)) { - if (occurence < config_content_item_get_occurences( item )) { - config_item_node_type * node = config_content_item_iget_node( item , occurence ); - value = stringlist_safe_iget( node->stringlist , index); + if (config_has_content_item( config , kw )) { + config_content_item_type * item = config_get_content_item(config , kw); + if (occurence < config_content_item_get_size( item )) { + config_content_node_type * node = config_content_item_iget_node( item , occurence ); + value = config_content_node_safe_iget( node , index ); } } return value; } -static void assert_key_value(const config_schema_item_type * item) { - if (!((item->validate->argc_min == 1) && (item->validate->argc_min == 1))) - util_abort("%s: item:%s before calling config_get_value() functions *without* index you must set argc_min == argc_max = 1 \n",__func__ , item->kw); - - if (item->append_arg) - util_abort("%s: must have append_arg == false for _get_value functions \n",__func__); -} - -/** - The config_get_value_??() functions are simpler wrappers for: - - 1. Check that item has been added with append==false and - arg_minmax = {1,1}, i.e. it has typically been added with - config_add_key_value(). - - 2. Call config_iget_?? with both the occurence and index values - set to 0. -*/ - -bool config_get_value_as_bool(const config_type * config , const char * kw) { - config_content_item_type * item = config_get_content_item(config , kw); - assert_key_value( item->schema ); - return config_content_item_iget_as_bool(item , 0 , 0); -} - -int config_get_value_as_int(const config_type * config , const char * kw) { - config_content_item_type * item = config_get_content_item(config , kw); - assert_key_value( item->schema ); - return config_content_item_iget_as_int(item , 0 , 0); -} - -double config_get_value_as_double(const config_type * config , const char * kw) { - config_content_item_type * item = config_get_content_item(config , kw); - assert_key_value( item->schema ); - return config_content_item_iget_as_double(item , 0 , 0); -} - -const char * config_get_value(const config_type * config , const char * kw) { - config_content_item_type * item = config_get_content_item(config , kw); - assert_key_value( item->schema ); - return config_content_item_iget(item , 0 , 0); -} - - - - - -const stringlist_type * config_get_stringlist_ref(const config_type * config , const char * kw) { - config_content_item_type * item = config_get_content_item(config , kw); - - return config_content_item_get_stringlist_ref(item); -} - - - -stringlist_type * config_iget_stringlist_ref(const config_type * config , const char * kw, int occurence) { +const stringlist_type * config_iget_stringlist_ref(const config_type * config , const char * kw, int occurence) { config_content_item_type * item = config_get_content_item(config , kw); return config_content_item_iget_stringlist_ref(item , occurence); @@ -1688,7 +927,8 @@ stringlist_type * config_alloc_complete_stringlist(const config_type* config , c /** - It is enforced that kw-item has been added with append_arg == false. + In the case the keyword has been mentioned several times the last + occurence will be returned. */ stringlist_type * config_alloc_stringlist(const config_type * config , const char * kw) { config_content_item_type * item = config_get_content_item(config , kw); @@ -1710,18 +950,25 @@ char * config_alloc_joined_string(const config_type * config , const char * kw, /** - Return the number of times a keyword has been set - dies on unknown 'kw'; + Return the number of times a keyword has been set - dies on unknown + 'kw'. If the append_arg attribute has been set to false the + function will return 0 or 1 irrespective of how many times the item + has been set in the config file. */ + int config_get_occurences(const config_type * config, const char * kw) { - return config_content_item_get_occurences(config_get_content_item(config , kw)); + if (config_has_content_item( config , kw )) + return config_content_item_get_size(config_get_content_item(config , kw)); + else + return 0; } int config_get_occurence_size( const config_type * config , const char * kw , int occurence) { config_content_item_type * item = config_get_content_item(config , kw); - config_item_node_type * node = config_content_item_iget_node( item , occurence ); - return stringlist_get_size( node->stringlist ); + config_content_node_type * node = config_content_item_iget_node( item , occurence ); + return config_content_node_get_size( node ); } @@ -1734,7 +981,7 @@ ENV LD_LIBARRY_PATH /some/other/path ENV MALLOC STRICT .... -the returned hash table will be: {"PATH": "/som/path", "LD_LIBARRY_PATH": "/some/other_path" , "MALLOC": "STRICT"} +the returned hash table will be: {"PATH": "/some/path", "LD_LIBARRY_PATH": "/some/other_path" , "MALLOC": "STRICT"} It is enforced that: @@ -1754,13 +1001,6 @@ hash_type * config_alloc_hash(const config_type * config , const char * kw) { -bool config_has_set_item(const config_type * config , const char * kw) { - if (config_has_schema_item(config , kw)) { - config_content_item_type * item = config_get_content_item(config , kw); - return config_content_item_is_set(item); - } else - return false; -} /** @@ -1784,21 +1024,8 @@ void config_install_message(config_type * config , const char * kw, const char * } -void config_fprintf_item_list(const config_type * config , FILE * stream) { - stringlist_type * items = hash_alloc_stringlist( config->schema_items ); - stringlist_sort( items , NULL ); - { - int i; - for (i=0; i < stringlist_get_size( items ); i++) - fprintf(stream , "%s \n",stringlist_iget( items , i)); - } - - stringlist_free( items ); -} - - -/*****************************************************************/ +#include "config_get.c" diff --git a/ThirdParty/Ert/devel/libconfig/src/config_content_item.c b/ThirdParty/Ert/devel/libconfig/src/config_content_item.c new file mode 100644 index 0000000000..4b07fcbe7b --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/src/config_content_item.c @@ -0,0 +1,291 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_content_item.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#define CONFIG_CONTENT_ITEM_ID 8876752 +struct config_content_item_struct { + UTIL_TYPE_ID_DECLARATION; + const config_schema_item_type * schema; + vector_type * nodes; + const config_path_elm_type * path_elm; +}; + + + + + + + + +/*****************************************************************/ + +/** + This function counts the number of times a config item has been + set. Referring again to the example at the top: + + config_content_item_get_occurences( "KEY1" ) + + will return 2. +*/ + + + +int config_content_item_get_size(const config_content_item_type * item) { + return vector_get_size( item->nodes ); +} + + +config_content_node_type * config_content_item_get_last_node(const config_content_item_type * item) { + return vector_get_last( item->nodes ); +} + +config_content_node_type * config_content_item_iget_node(const config_content_item_type * item , int index) { + return vector_iget( item->nodes , index ); +} + +const config_content_node_type * config_content_item_get_last_node_const(const config_content_item_type * item) { + return vector_get_last( item->nodes ); +} + +const config_content_node_type * config_content_item_iget_node_const(const config_content_item_type * item , int index) { + return vector_iget( item->nodes , index ); +} + + +char * config_content_item_ialloc_joined_string(const config_content_item_type * item , const char * sep , int occurence) { + const config_content_node_type * node = config_content_item_iget_node(item , occurence); + return config_content_node_alloc_joined_string(node , sep); +} + + + +char * config_content_item_alloc_joined_string(const config_content_item_type * item , const char * sep) { + const int occurences = config_content_item_get_size( item ); + char * joined_string = NULL; + + for (int i =0; i < occurences ; i++) { + joined_string = util_strcat_realloc( joined_string , config_content_item_ialloc_joined_string(item , sep , i)); + if (i < (occurences - 1)) + joined_string = util_strcat_realloc( joined_string , sep ); + } + + return joined_string; +} + +const stringlist_type * config_content_item_iget_stringlist_ref(const config_content_item_type * item, int occurence) { + const config_content_node_type * node = config_content_item_iget_node(item , occurence); + return config_content_node_get_stringlist( node ); +} + + +const stringlist_type * config_content_item_get_stringlist_ref(const config_content_item_type * item) { + const config_content_node_type * node = config_content_item_get_last_node( item ); + return config_content_node_get_stringlist( node ); +} + + +/** + If copy == false - the stringlist will break down when/if the + config object is freed - your call. +*/ + +stringlist_type * config_content_item_alloc_complete_stringlist(const config_content_item_type * item, bool copy) { + int inode; + stringlist_type * stringlist = stringlist_alloc_new(); + for (inode = 0; inode < vector_get_size( item->nodes ); inode++) { + const config_content_node_type * node = config_content_item_iget_node(item , inode); + const stringlist_type * src_list = config_content_node_get_stringlist( node ); + + if (copy) + stringlist_append_stringlist_copy( stringlist , src_list ); + else + stringlist_append_stringlist_ref( stringlist , src_list ); + + } + + return stringlist; +} + + +/** + If copy == false - the stringlist will break down when/if the + config object is freed - your call. +*/ + +stringlist_type * config_content_item_alloc_stringlist(const config_content_item_type * item, bool copy) { + const config_content_node_type * node = config_content_item_get_last_node( item ); + stringlist_type * stringlist = stringlist_alloc_new(); + const stringlist_type * src_list = config_content_node_get_stringlist( node ); + + if (copy) + stringlist_append_stringlist_copy( stringlist , src_list ); + else + stringlist_append_stringlist_ref( stringlist , src_list ); + + return stringlist; +} + + +/** + If copy == false - the hash will break down when/if the + config object is freed - your call. +*/ + +hash_type * config_content_item_alloc_hash(const config_content_item_type * item , bool copy) { + hash_type * hash = hash_alloc(); + if (item != NULL) { + int inode; + for (inode = 0; inode < vector_get_size( item->nodes ); inode++) { + const config_content_node_type * node = config_content_item_iget_node(item , inode); + const stringlist_type * src_list = config_content_node_get_stringlist( node ); + const char * key = stringlist_iget(src_list , 0); + const char * value = stringlist_iget(src_list , 1); + + if (copy) { + hash_insert_hash_owned_ref(hash , + key , + util_alloc_string_copy(value) , + free); + } else + hash_insert_ref(hash , key , value ); + + } + } + return hash; +} + + +/******************************************************************/ + + + + +const char * config_content_item_iget(const config_content_item_type * item , int occurence , int index) { + const config_content_node_type * node = config_content_item_iget_node(item , occurence); + const stringlist_type * src_list = config_content_node_get_stringlist( node ); + return stringlist_iget( src_list , index ); +} + +bool config_content_item_iget_as_bool(const config_content_item_type * item, int occurence , int index) { + bool value; + config_schema_item_assure_type(item->schema , index , CONFIG_BOOL); + util_sscanf_bool( config_content_item_iget(item , occurence ,index) , &value ); + return value; +} + + + + +int config_content_item_iget_as_int(const config_content_item_type * item, int occurence , int index) { + int value; + config_schema_item_assure_type(item->schema , index , CONFIG_INT); + util_sscanf_int( config_content_item_iget(item , occurence , index) , &value ); + return value; +} + + +double config_content_item_iget_as_double(const config_content_item_type * item, int occurence , int index) { + double value; + config_schema_item_assure_type(item->schema , index , CONFIG_FLOAT); + util_sscanf_double( config_content_item_iget(item , occurence , index) , &value ); + return value; +} + + +/** + Used to reset an item is the special string 'CLEAR_STRING' + is found as the only argument: + + OPTION V1 + OPTION V2 V3 V4 + OPTION __RESET__ + OPTION V6 + + In this case OPTION will get the value 'V6'. The example given + above is a bit contrived; this option is designed for situations + where several config files are parsed serially; and the user can + not/will not update the first. +*/ + +void config_content_item_clear( config_content_item_type * item ) { + vector_clear( item->nodes ); +} + + + +void config_content_item_free( config_content_item_type * item ) { + vector_free( item->nodes ); + free(item); +} + + + +UTIL_SAFE_CAST_FUNCTION( config_content_item , CONFIG_CONTENT_ITEM_ID); + + + +void config_content_item_free__( void * arg ) { + config_content_item_type * content_item = config_content_item_safe_cast( arg ); + config_content_item_free( content_item ); +} + + +config_content_item_type * config_content_item_alloc( const config_schema_item_type * schema , const config_path_elm_type * path_elm) { + config_content_item_type * content_item = util_malloc( sizeof * content_item ); + UTIL_TYPE_ID_INIT( content_item , CONFIG_CONTENT_ITEM_ID ); + content_item->schema = schema; + content_item->nodes = vector_alloc_new(); + content_item->path_elm = path_elm; + return content_item; +} + + + + + +config_content_node_type * config_content_item_alloc_node( const config_content_item_type * item , const config_path_elm_type * path_elm) { + config_content_node_type * node = config_content_node_alloc( item->schema , path_elm ); + vector_append_owned_ref( item->nodes , node , config_content_node_free__); + return node; +} + + + +const config_schema_item_type * config_content_item_get_schema( const config_content_item_type * item ) { + return item->schema; +} + + + + +const config_path_elm_type * config_content_item_get_path_elm( const config_content_item_type * item ) { + return item->path_elm; +} diff --git a/ThirdParty/Ert/devel/libconfig/src/config_content_node.c b/ThirdParty/Ert/devel/libconfig/src/config_content_node.c new file mode 100644 index 0000000000..d7015802bc --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/src/config_content_node.c @@ -0,0 +1,229 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_content_node.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 + +#include +#include +#include + +#include +#include +#include + + +#define CONFIG_CONTENT_NODE_ID 6752887 +struct config_content_node_struct { + UTIL_TYPE_ID_DECLARATION; + const config_schema_item_type * schema; + stringlist_type * stringlist; /* The values which have been set. */ + const config_path_elm_type * cwd; + stringlist_type * string_storage; +}; + + +static UTIL_SAFE_CAST_FUNCTION( config_content_node , CONFIG_CONTENT_NODE_ID ) + + + +config_content_node_type * config_content_node_alloc( const config_schema_item_type * schema , const config_path_elm_type * cwd) { + config_content_node_type * node = util_malloc(sizeof * node ); + UTIL_TYPE_ID_INIT( node , CONFIG_CONTENT_NODE_ID ); + node->stringlist = stringlist_alloc_new(); + node->cwd = cwd; + node->schema = schema; + node->string_storage = NULL; + return node; +} + + +void config_content_node_add_value(config_content_node_type * node , const char * value) { + stringlist_append_copy( node->stringlist , value); +} + + +void config_content_node_set(config_content_node_type * node , const stringlist_type * token_list) { + int argc = stringlist_get_size( token_list ) - 1; + for (int iarg=0; iarg < argc; iarg++) + config_content_node_add_value( node , stringlist_iget( token_list , iarg + 1)); +} + + + +char * config_content_node_alloc_joined_string(const config_content_node_type * node, const char * sep) { + return stringlist_alloc_joined_string(node->stringlist , sep); +} + + + +void config_content_node_free(config_content_node_type * node) { + stringlist_free(node->stringlist); + if (node->string_storage != NULL) + stringlist_free( node->string_storage ); + free(node); +} + + + +void config_content_node_free__(void * arg) { + config_content_node_type * node = config_content_node_safe_cast( arg ); + config_content_node_free( node ); +} + +static void config_content_node_push_string( config_content_node_type * node , char * string) { + if (node->string_storage == NULL) + node->string_storage = stringlist_alloc_new( ); + + stringlist_append_owned_ref( node->string_storage , string ); +} + +const char * config_content_node_get_full_string( config_content_node_type * node , const char * sep ) { + char * full_string = stringlist_alloc_joined_string(node->stringlist , sep); + config_content_node_push_string( node , full_string ); + return full_string; +} + +const char * config_content_node_iget(const config_content_node_type * node , int index) { + return stringlist_iget( node->stringlist , index ); +} + + +const char * config_content_node_safe_iget(const config_content_node_type * node , int index) { + if (index >= stringlist_get_size( node->stringlist )) + return NULL; + else + return stringlist_iget( node->stringlist , index ); +} + + +bool config_content_node_iget_as_bool(const config_content_node_type * node , int index) { + bool value; + config_schema_item_assure_type(node->schema , index , CONFIG_BOOL); + util_sscanf_bool( config_content_node_iget(node , index) , &value ); + return value; +} + + +int config_content_node_iget_as_int(const config_content_node_type * node , int index) { + int value; + config_schema_item_assure_type(node->schema , index , CONFIG_INT); + util_sscanf_int( config_content_node_iget(node , index) , &value ); + return value; +} + + + +double config_content_node_iget_as_double(const config_content_node_type * node , int index) { + double value; + config_schema_item_assure_type(node->schema , index , CONFIG_FLOAT + CONFIG_INT); + util_sscanf_double( config_content_node_iget(node , index) , &value ); + return value; +} + + + + +const char * config_content_node_iget_as_path(config_content_node_type * node , int index) { + config_schema_item_assure_type(node->schema , index , CONFIG_PATH + CONFIG_EXISTING_PATH); + { + const char * config_value = config_content_node_iget(node , index); + char * path_value = config_path_elm_alloc_path( node->cwd , config_value ); + config_content_node_push_string( node , path_value ); + + return path_value; + } +} + + +const char * config_content_node_iget_as_abspath( config_content_node_type * node , int index) { + config_schema_item_assure_type(node->schema , index , CONFIG_PATH + CONFIG_EXISTING_PATH); + { + const char * config_value = config_content_node_iget(node , index); + char * path_value = config_path_elm_alloc_abspath( node->cwd , config_value ); + config_content_node_push_string( node , path_value ); + + return path_value; + } +} + + +const char * config_content_node_iget_as_relpath( config_content_node_type * node , int index) { + config_schema_item_assure_type(node->schema , index , CONFIG_PATH + CONFIG_EXISTING_PATH); + { + const char * config_value = config_content_node_iget(node , index); + char * path_value = config_path_elm_alloc_relpath( node->cwd , config_value ); + config_content_node_push_string( node , path_value ); + + return path_value; + } +} + + +const stringlist_type * config_content_node_get_stringlist( const config_content_node_type * node ) { + return node->stringlist; +} + + +const char * config_content_node_get_kw( const config_content_node_type * node ) { + return config_schema_item_get_kw( node->schema ); +} + + + + +int config_content_node_get_size( const config_content_node_type * node ) { + return stringlist_get_size( node->stringlist ); +} + + +void config_content_node_assert_key_value( const config_content_node_type * node ) { + int argc_min , argc_max; + config_schema_item_get_argc( node->schema , &argc_min , &argc_max); + + if (!((argc_min == 1) && (argc_min == 1))) + util_abort("%s: item:%s before calling config_get_value() functions *without* index you must set argc_min == argc_max = 1 \n",__func__ , config_schema_item_get_kw( node->schema )); +} + + +const config_path_elm_type * config_content_node_get_path_elm( const config_content_node_type * node ) { + return node->cwd; +} + +/** + The node should contain elements of the type: + + KEY1:VALUE1 KEY2:Value2 XX Key3:Val3 Ignored + + Which will be inserted in the opt_hash dictionary as : {"KEY1" : + "VALUE1" , ... } Elements which do not conform to this syntax are + ignored. +*/ + + +void config_content_node_init_opt_hash( const config_content_node_type * node , hash_type * opt_hash , int elm_offset) { + int i; + for (i = elm_offset; i < config_content_node_get_size( node ); i++) + hash_add_option( opt_hash , config_content_node_iget( node , i )); +} + + +void config_content_node_fprintf( const config_content_node_type * node , FILE * stream ) { + fprintf(stream , "%s: {" , config_schema_item_get_kw( node->schema )); + stringlist_fprintf( node->stringlist , ", " , stream ); + fprintf(stream , "}\n"); +} diff --git a/ThirdParty/Ert/devel/libconfig/src/config_error.c b/ThirdParty/Ert/devel/libconfig/src/config_error.c new file mode 100644 index 0000000000..2bd344ff96 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/src/config_error.c @@ -0,0 +1,86 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_error.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 + +#include +#include + +#include + +struct config_error_struct { + stringlist_type * error_list; +}; + + + +config_error_type * config_error_alloc() { + config_error_type * error = util_malloc( sizeof * error ); + error->error_list = stringlist_alloc_new(); + return error; +} + + +config_error_type * config_error_alloc_copy( const config_error_type * src_error) { + config_error_type * config_error = config_error_alloc(); + stringlist_deep_copy( config_error->error_list , src_error->error_list ); + return config_error; +} + + +bool config_error_equal( const config_error_type * error1 , const config_error_type * error2) { + return stringlist_equal( error1->error_list , error2->error_list ); +} + +void config_error_free( config_error_type * error ) { + stringlist_free( error->error_list ); + free( error ); +} + + + +void config_error_add( config_error_type * error , char * new_error) { + stringlist_append_owned_ref( error->error_list , new_error ); +} + + + +void config_error_clear( config_error_type * error ) { + stringlist_clear( error->error_list ); +} + + +int config_error_count( const config_error_type * error ) { + return stringlist_get_size( error->error_list ); +} + + +const char * config_error_iget( const config_error_type * error , int index) { + return stringlist_iget( error->error_list , index ); +} + + +void config_error_fprintf( const config_error_type * error , bool add_count , FILE * stream ) { + int error_nr; + + for (error_nr = 0; error_nr < stringlist_get_size( error->error_list ); error_nr++) { + if (add_count) + fprintf(stream , " %02d: " , error_nr); + + fprintf( stream , "%s\n" , stringlist_iget( error->error_list , error_nr)); + } +} diff --git a/ThirdParty/Ert/devel/libconfig/src/config_get.c b/ThirdParty/Ert/devel/libconfig/src/config_get.c new file mode 100644 index 0000000000..6c18e882e1 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/src/config_get.c @@ -0,0 +1,114 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_get.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + + +/*****************************************************************/ +/* All the functions in this block will operate on the last item + which has been set with a particular key value. So assuming the + config file looks like: + + KEY VALUE1 + KEY VALUE2 OPTIONAL + KEY 100 VALUE3 OPTIONAL ERROR + + these functions will all operate on the last line in the config file: + + KEY 100 VALUE3 OPTIONAL ERROR +*/ + + +config_content_node_type * config_get_value_node( const config_type * config , const char * kw) { + config_content_item_type * item = config_get_content_item(config , kw); + if (item != NULL) { + config_content_node_type * node = config_content_item_get_last_node( item ); + config_content_node_assert_key_value( node ); + return node; + } else + return NULL; // Will return NULL on unset keywords - must check NULL return value?! +} + +static config_content_node_type * config_get_value_node__( const config_type * config , const char * kw) { + config_content_node_type * node = config_get_value_node( config , kw ); + if (node == NULL) + util_abort("Tried to get value node from unset kw:%s \n",__func__ , kw ); + + return node; +} + +bool config_get_value_as_bool(const config_type * config , const char * kw) { + config_content_node_type * node = config_get_value_node__( config , kw ); + return config_content_node_iget_as_bool(node , 0); +} + +int config_get_value_as_int(const config_type * config , const char * kw) { + config_content_node_type * node = config_get_value_node__( config , kw ); + return config_content_node_iget_as_int(node , 0); +} + +double config_get_value_as_double(const config_type * config , const char * kw) { + config_content_node_type * node = config_get_value_node__( config , kw ); + return config_content_node_iget_as_double(node , 0); +} + +const char * config_get_value_as_path( const config_type * config , const char * kw) { + config_content_node_type * node = config_get_value_node__( config , kw ); + return config_content_node_iget_as_path(node , 0); +} + +const char * config_get_value_as_abspath( const config_type * config , const char * kw) { + config_content_node_type * node = config_get_value_node__( config , kw ); + return config_content_node_iget_as_abspath(node , 0); +} + +const char * config_get_value_as_relpath( const config_type * config , const char * kw) { + config_content_node_type * node = config_get_value_node__( config , kw ); + return config_content_node_iget_as_relpath(node , 0); +} + + +const char * config_get_value(const config_type * config , const char * kw) { + config_content_node_type * node = config_get_value_node__( config , kw ); + return config_content_node_iget(node , 0); +} + + +/*****************************************************************/ + +int config_get_content_size( const config_type * config ) { + return vector_get_size(config->content_list); +} + + +const config_content_node_type * config_iget_content_node( const config_type * config , int index) { + return vector_iget_const( config->content_list , index ); +} + + + + + +int config_get_schema_size( const config_type * config ) { + return hash_get_size( config->schema_items ); +} + + + + +config_error_type * config_get_errors( const config_type * config ) { + return config->parse_errors; +} diff --git a/ThirdParty/Ert/devel/libconfig/src/config_path_elm.c b/ThirdParty/Ert/devel/libconfig/src/config_path_elm.c new file mode 100644 index 0000000000..ec95f5a913 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/src/config_path_elm.c @@ -0,0 +1,135 @@ +/* + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'config_path_elm.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include + +#include +#include + +#define CONFIG_PATH_ELM_TYPE_ID 7100063 + +struct config_path_elm_struct { + UTIL_TYPE_ID_DECLARATION; + char * abs_path; // This will always be absolute + char * rel_path; // This will always be relative to the root path. + const config_root_path_type * root_path; +}; + +static UTIL_SAFE_CAST_FUNCTION( config_path_elm , CONFIG_PATH_ELM_TYPE_ID ) + + +config_path_elm_type * config_path_elm_alloc( const config_root_path_type * root_path , const char * path) { + if (root_path != NULL) { + config_path_elm_type * path_elm = util_malloc( sizeof * path_elm ); + UTIL_TYPE_ID_INIT(path_elm , CONFIG_PATH_ELM_TYPE_ID); + path_elm->root_path = root_path; + if (path == NULL) { + path_elm->rel_path = NULL; + path_elm->abs_path = util_alloc_string_copy( config_root_path_get_abs_path(root_path) ); + } else { + if (util_is_abs_path( path )) { + path_elm->abs_path = util_alloc_string_copy( path ); + path_elm->rel_path = util_alloc_rel_path( config_root_path_get_abs_path(root_path) , path ); + } else { + path_elm->abs_path = util_alloc_filename( config_root_path_get_abs_path(root_path) , path , NULL ); + path_elm->rel_path = util_alloc_string_copy( path ); + } + } + return path_elm; + } else { + util_abort("%s: root_path input argument == NULL - invalid \n",__func__); + return NULL; + } +} + + + + +void config_path_elm_free( config_path_elm_type * path_elm ) { + util_safe_free( path_elm->rel_path ); + util_safe_free( path_elm->abs_path ); + free( path_elm ); +} + + + +void config_path_elm_free__( void * arg ) { + config_path_elm_type * path_elm = config_path_elm_safe_cast( arg ); + config_path_elm_free( path_elm ); +} + +const config_root_path_type * config_path_elm_get_rootpath( const config_path_elm_type * path_elm ) { + return path_elm->root_path; +} + +const char * config_path_elm_get_relpath( const config_path_elm_type * path_elm ) { + return path_elm->rel_path; +} + +const char * config_path_elm_get_abspath( const config_path_elm_type * path_elm ) { + return path_elm->abs_path; +} + + +/*****************************************************************/ + + +char * config_path_elm_alloc_path(const config_path_elm_type * path_elm , const char * path) { + if (util_is_abs_path( path )) + return util_alloc_string_copy( path ); + else { + /* This will be relative or absolute depending on the relative/absolute + status of the root_path. */ + const char * input_root = config_root_path_get_input_path( path_elm->root_path ); + if (input_root == NULL) + return util_alloc_filename( path_elm->rel_path , path , NULL); + else + return util_alloc_joined_string( (const char *[3]) { input_root , path_elm->rel_path , path } , 3 , UTIL_PATH_SEP_STRING ); + } +} + + +char * config_path_elm_alloc_relpath(const config_path_elm_type * path_elm , const char * input_path) { + if (util_is_abs_path( input_path )) + return util_alloc_rel_path( config_root_path_get_rel_path( path_elm->root_path ) , input_path); + else { + char * abs_path = config_path_elm_alloc_abspath( path_elm , input_path ); + char * rel_path = util_alloc_rel_path( config_root_path_get_abs_path( path_elm->root_path ) , abs_path ); + free( abs_path ); + return rel_path; + } +} + + +char * config_path_elm_alloc_abspath(const config_path_elm_type * path_elm , const char * input_path) { + if (util_is_abs_path( input_path )) + return util_alloc_string_copy( input_path ); + else { + char * abs_path1 = util_alloc_filename( path_elm->abs_path , input_path , NULL ); + char * abs_path = util_alloc_realpath__( abs_path1 ); // The util_alloc_realpath__() will work also for nonexsting paths + free( abs_path1 ); + return abs_path; + } +} diff --git a/ThirdParty/Ert/devel/libconfig/src/config_root_path.c b/ThirdParty/Ert/devel/libconfig/src/config_root_path.c new file mode 100644 index 0000000000..9a82d3adce --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/src/config_root_path.c @@ -0,0 +1,97 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'config_root_path.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include + +#include + +struct config_root_path_struct { + char * input_path; + char * abs_path; + char * rel_path; +}; + + +/** + Input must be an existing directory, which will be used as the + root; or NULL in which case cwd will be used as root. The input + directory can be both realtive or absolute. +*/ + +config_root_path_type * config_root_path_alloc( const char * input_path ) { + if (input_path == NULL || util_is_directory( input_path )) { + config_root_path_type * root_path = util_malloc( sizeof * root_path ); + { + char * cwd = util_alloc_cwd(); + + root_path->input_path = util_alloc_string_copy( input_path ); + if (input_path == NULL) { + root_path->rel_path = NULL; + root_path->abs_path = util_alloc_string_copy( cwd ); + } else { + if (util_is_abs_path( input_path )) { + root_path->abs_path = util_alloc_string_copy( input_path ); + root_path->rel_path = util_alloc_rel_path( cwd , root_path->abs_path); + } else { + root_path->rel_path = util_alloc_string_copy( input_path ); + { + char * abs_path = util_alloc_filename( cwd , input_path , NULL ); + root_path->abs_path = util_alloc_realpath( abs_path ); + free( abs_path ); + } + } + } + free( cwd ); + } + return root_path; + } else + return NULL; +} + + +void config_root_path_free( config_root_path_type * root_path ) { + util_safe_free( root_path->rel_path ); + util_safe_free( root_path->abs_path ); + util_safe_free( root_path->input_path ); + free( root_path ); +} + +const char * config_root_path_get_input_path( const config_root_path_type * root_path ) { + return root_path->input_path; +} + + +const char * config_root_path_get_rel_path( const config_root_path_type * root_path ) { + return root_path->rel_path; +} + + +const char * config_root_path_get_abs_path( const config_root_path_type * root_path ) { + return root_path->abs_path; +} + + + + + diff --git a/ThirdParty/Ert/devel/libconfig/src/config_schema_item.c b/ThirdParty/Ert/devel/libconfig/src/config_schema_item.c new file mode 100644 index 0000000000..4945a362ad --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/src/config_schema_item.c @@ -0,0 +1,536 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_schema_item.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef struct validate_struct validate_type; + +/** + This is a 'support-struct' holding various pieces of information + needed during the validation process. Observe the following about + validation: + + 1. It is atomic, in the sense that if you try to an item like this: + + KW ARG1 ARG2 ARG3 + + where ARG1 and ARG2 are valid, whereas there is something wrong + with ARG3, NOTHING IS SET. + + 2. Validation is a two-step process, the first step is run when an + item is parsed. This includes checking: + + o The number of argument. + o That the arguments have the right type. + o That the values match the selection set. + + The second validation step is done when the pasing is complete, + in this pass we check dependencies - i.e. required_children and + required_children_on_value. + + + Observe that nothing has-to be set in this struct. There are some dependencies: + + 1. Only _one_ of common_selection_set and indexed_selection_set + can be set. + + 2. If setting indexed_selection_set or type_map, you MUST set + argc_max first. +*/ + + +struct validate_struct { + int argc_min; /* The minimum number of arguments: -1 means no lower limit. */ + int argc_max; /* The maximum number of arguments: -1 means no upper limit. */ + set_type * common_selection_set; /* A selection set which will apply uniformly to all the arguments. */ + set_type ** indexed_selection_set; /* A selection set which will apply for specifi (indexed) arguments. */ + int_vector_type * type_map; /* A list of types for the items. Set along with argc_minmax(); */ + stringlist_type * required_children; /* A list of item's which must also be set (if this item is set). (can be NULL) */ + hash_type * required_children_value; /* A list of item's which must also be set - depending on the value of this item. (can be NULL) (This one is complex). */ +}; + + + + + +#define CONFIG_SCHEMA_ITEM_ID 6751 +struct config_schema_item_struct { + UTIL_TYPE_ID_DECLARATION; + char * kw; /* The kw which identifies this item· */ + + + bool required_set; + stringlist_type * required_children; /* A list of item's which must also be set (if this item is set). (can be NULL) */ + hash_type * required_children_value; /* A list of item's which must also be set - depending on the value of this item. (can be NULL) */ + validate_type * validate; /* Information need during validation. */ + bool expand_envvar; /* Should environment variables like $HOME be expanded?*/ +}; + + +/*****************************************************************/ + + +/*****************************************************************/ +static void validate_set_default_type( validate_type * validate , config_item_types item_type) { + int_vector_set_default(validate->type_map , item_type); +} + +static validate_type * validate_alloc() { + validate_type * validate = util_malloc(sizeof * validate ); + validate->argc_min = CONFIG_DEFAULT_ARG_MIN; + validate->argc_max = CONFIG_DEFAULT_ARG_MAX; + validate->common_selection_set = NULL; + validate->indexed_selection_set = NULL; + validate->required_children = NULL; + validate->required_children_value = NULL; + validate->type_map = int_vector_alloc(0 , 0); + validate_set_default_type( validate , CONFIG_STRING ); + return validate; +} + + +static void validate_free(validate_type * validate) { + if (validate->common_selection_set != NULL) set_free(validate->common_selection_set); + if (validate->indexed_selection_set != NULL) { + for (int i = 0; i < validate->argc_max; i++) + if (validate->indexed_selection_set[i] != NULL) + set_free(validate->indexed_selection_set[i]); + free(validate->indexed_selection_set); + } + + int_vector_free( validate->type_map ); + if (validate->required_children != NULL) stringlist_free(validate->required_children); + if (validate->required_children_value != NULL) hash_free(validate->required_children_value); + free(validate); +} + + +static void validate_iset_type( validate_type * validate , int index , config_item_types type) { + int_vector_iset( validate->type_map , index , type); +} + + +static config_item_types validate_iget_type( const validate_type * validate , int index) { + return int_vector_safe_iget( validate->type_map , index ); +} + + +static void validate_set_argc_minmax(validate_type * validate , int argc_min , int argc_max) { + if (validate->argc_min != CONFIG_DEFAULT_ARG_MIN) + util_abort("%s: sorry - current implementation does not allow repeated calls to: %s \n",__func__ , __func__); + + if (argc_min == CONFIG_DEFAULT_ARG_MIN) + argc_min = 0; + + validate->argc_min = argc_min; + validate->argc_max = argc_max; + + if ((argc_max != CONFIG_DEFAULT_ARG_MAX) && (argc_max < argc_min)) + util_abort("%s invalid arg min/max values. argc_min:%d argc_max:%d \n",__func__ , argc_min , argc_max); + + { + int internal_type_size = 0; /* Should end up in the range [argc_min,argc_max] */ + + if (argc_max > 0) + internal_type_size = argc_max; + else + internal_type_size = argc_min; + + if (internal_type_size > 0) { + validate->indexed_selection_set = util_calloc( internal_type_size , sizeof * validate->indexed_selection_set ); + for (int iarg=0; iarg < internal_type_size; iarg++) + validate->indexed_selection_set[iarg] = NULL; + } + } +} + + + +static void validate_set_common_selection_set(validate_type * validate , int argc , const char ** argv) { + if (validate->common_selection_set != NULL) + set_free(validate->common_selection_set); + validate->common_selection_set = set_alloc( argc , argv ); +} + + +static void validate_set_indexed_selection_set(validate_type * validate , int index , int argc , const char ** argv) { + + if (validate->indexed_selection_set == NULL) + util_abort("%s: must call xxx_set_argc_minmax() first - aborting \n",__func__); + + if (index >= validate->argc_min) + util_abort("%s: When not not setting argc_max selection set can only be applied to indices up to argc_min\n",__func__); + + if (validate->indexed_selection_set[index] != NULL) + set_free(validate->indexed_selection_set[index]); + + validate->indexed_selection_set[index] = set_alloc(argc , argv); +} + + +/*****************************************************************/ + + +static UTIL_SAFE_CAST_FUNCTION( config_schema_item , CONFIG_SCHEMA_ITEM_ID) + +void config_schema_item_assure_type(const config_schema_item_type * item , int index , int type_mask) { + bool OK = false; + + if (int_vector_safe_iget( item->validate->type_map , index) & type_mask) + OK = true; + + if (!OK) + util_abort("%s: failed - wrong installed type \n" , __func__); +} + + +config_schema_item_type * config_schema_item_alloc(const char * kw , bool required) { + config_schema_item_type * item = util_malloc(sizeof * item ); + UTIL_TYPE_ID_INIT( item , CONFIG_SCHEMA_ITEM_ID); + item->kw = util_alloc_string_copy(kw); + + item->required_set = required; + item->required_children = NULL; + item->required_children_value = NULL; + item->expand_envvar = true; /* Default is to expand $VAR expressions; can be turned off with + config_schema_item_set_envvar_expansion( item , false ); */ + item->validate = validate_alloc(); + return item; +} + + + +static char * __alloc_relocated__(const config_path_elm_type * path_elm , const char * value) { + char * file; + + if (util_is_abs_path(value)) + file = util_alloc_string_copy( value ); + else + file = util_alloc_filename(config_path_elm_get_relpath( path_elm ) , value , NULL); + + return file; +} + + +bool config_schema_item_validate_set(const config_schema_item_type * item , stringlist_type * token_list , const char * config_file, const config_path_elm_type * path_elm , config_error_type * error_list) { + bool OK = true; + int argc = stringlist_get_size( token_list ) - 1; + if (item->validate->argc_min >= 0) { + if (argc < item->validate->argc_min) { + OK = false; + { + char * error_message; + if (config_file != NULL) + error_message = util_alloc_sprintf("Error when parsing config_file:\"%s\" Keyword:%s must have at least %d arguments.",config_file , item->kw , item->validate->argc_min); + else + error_message = util_alloc_sprintf("Error:: Keyword:%s must have at least %d arguments.",item->kw , item->validate->argc_min); + + config_error_add( error_list , error_message ); + } + } + } + + if (item->validate->argc_max >= 0) { + if (argc > item->validate->argc_max) { + OK = false; + { + char * error_message; + + if (config_file != NULL) + error_message = util_alloc_sprintf("Error when parsing config_file:\"%s\" Keyword:%s must have maximum %d arguments.",config_file , item->kw , item->validate->argc_max); + else + error_message = util_alloc_sprintf("Error:: Keyword:%s must have maximum %d arguments.",item->kw , item->validate->argc_max); + config_error_add( error_list , error_message ); + } + } + } + + /* + OK - now we have verified that the number of arguments is correct. Then + we start actually looking at the values. + */ + if (OK) { + /* Validating selection set - first common, then indexed */ + if (item->validate->common_selection_set) { + for (int iarg = 0; iarg < argc; iarg++) { + if (!set_has_key(item->validate->common_selection_set , stringlist_iget( token_list , iarg + 1))) { + config_error_add( error_list , util_alloc_sprintf("%s: is not a valid value for: %s.",stringlist_iget( token_list , iarg + 1) , item->kw)); + OK = false; + } + } + } else if (item->validate->indexed_selection_set != NULL) { + for (int iarg = 0; iarg < argc; iarg++) { + if ((item->validate->argc_max > 0) || (iarg < item->validate->argc_min)) { /* Without this test we might go out of range on the indexed selection set. */ + if (item->validate->indexed_selection_set[iarg] != NULL) { + if (!set_has_key(item->validate->indexed_selection_set[iarg] , stringlist_iget( token_list , iarg + 1))) { + config_error_add( error_list , util_alloc_sprintf("%s: is not a valid value for item %d of \'%s\'.",stringlist_iget( token_list , iarg + 1) , iarg + 1 , item->kw)); + OK = false; + } + } + } + } + } + + /* + Observe that the following code might rewrite the content of + argv for arguments referring to path locations. + */ + + + /* Validate the TYPE of the various argumnents */ + { + for (int iarg = 0; iarg < argc; iarg++) { + const char * value = stringlist_iget(token_list , iarg + 1); + switch (validate_iget_type( item->validate , iarg)) { + case(CONFIG_STRING): /* This never fails ... */ + break; + case(CONFIG_INT): + if (!util_sscanf_int( value , NULL )) + config_error_add( error_list , util_alloc_sprintf("Failed to parse:%s as an integer.",value)); + break; + case(CONFIG_FLOAT): + if (!util_sscanf_double( value , NULL )) { + config_error_add( error_list , util_alloc_sprintf("Failed to parse:%s as a floating point number.", value)); + OK = false; + } + break; + case(CONFIG_PATH): + // As long as we do not reuqire the path to exist it is just a string. + break; + case(CONFIG_EXISTING_PATH): + { + char * path = config_path_elm_alloc_abspath( path_elm , value ); + if (!util_entry_exists(path)) { + config_error_add( error_list , util_alloc_sprintf("Can not find entry %s in %s ",value , config_path_elm_get_relpath( path_elm) )); + OK = false; + } + free( path ); + } + break; + case(CONFIG_EXECUTABLE): + { + /* + 1. If the supplied value is an abolute path - do nothing. + 2. If the supplied is _not_ an absolute path: + + a. Try if the relocated exists - then use that. + b. Else - try if the util_alloc_PATH_executable() exists. + */ + if (!util_is_abs_path( value )) { + char * relocated = __alloc_relocated__(path_elm , value); + char * path_exe = util_alloc_PATH_executable( value ); + + if (util_file_exists(relocated)) { + if (util_is_executable(relocated)) + stringlist_iset_copy( token_list , iarg , relocated); + } else if (path_exe != NULL) + stringlist_iset_copy( token_list , iarg , path_exe); + else + config_error_add( error_list , util_alloc_sprintf("Could not locate executable:%s ", value)); + + free(relocated); + util_safe_free(path_exe); + } else { + if (!util_is_executable( value )) + config_error_add( error_list , util_alloc_sprintf("Could not locate executable:%s ", value)); + } + } + break; + case(CONFIG_BOOL): + if (!util_sscanf_bool( value , NULL )) { + config_error_add( error_list , util_alloc_sprintf("Failed to parse:%s as a boolean.", value)); + OK = false; + } + break; + case(CONFIG_BYTESIZE): + if (!util_sscanf_bytesize( value , NULL)) { + config_error_add( error_list , util_alloc_sprintf("Failed to parse:\"%s\" as number of bytes." , value)); + OK = false; + } + break; + default: + util_abort("%s: config_item_type:%d not recognized \n",__func__ , validate_iget_type(item->validate , iarg)); + } + } + } + } + return OK; +} + + +void config_schema_item_free( config_schema_item_type * item) { + free(item->kw); + if (item->required_children != NULL) stringlist_free(item->required_children); + if (item->required_children_value != NULL) hash_free(item->required_children_value); + validate_free(item->validate); + free(item); +} + + +void config_schema_item_free__ (void * void_item) { + config_schema_item_type * item = config_schema_item_safe_cast( void_item ); + config_schema_item_free( item ); +} + + + +void config_schema_item_set_required_children_on_value(config_schema_item_type * item , const char * value , stringlist_type * child_list) { + if (item->required_children_value == NULL) + item->required_children_value = hash_alloc(); + hash_insert_hash_owned_ref( item->required_children_value , value , stringlist_alloc_deep_copy(child_list) , stringlist_free__); +} + + + +/** + This function is used to set the minimum and maximum number of + arguments for an item. In addition you can pass in a pointer to an + array of config_schema_item_types values which will be used for validation + of the input. This vector must be argc_max elements long; it can be + NULL. +*/ + + +void config_schema_item_set_argc_minmax(config_schema_item_type * item , + int argc_min , + int argc_max) { + + validate_set_argc_minmax(item->validate , argc_min , argc_max); + +} + +void config_schema_item_iset_type( config_schema_item_type * item , int index , config_item_types type) { + validate_iset_type( item->validate , index , type ); +} + +void config_schema_item_set_default_type( config_schema_item_type * item , config_item_types type) { + validate_set_default_type( item->validate , type ); +} + + +config_item_types config_schema_item_iget_type(const config_schema_item_type * item , int index ) { + return validate_iget_type( item->validate , index ); +} + + + + +void config_schema_item_set_envvar_expansion( config_schema_item_type * item , bool expand_envvar ) { + item->expand_envvar = expand_envvar; +} + + + +void config_schema_item_set_common_selection_set(config_schema_item_type * item , int argc , const char ** argv) { + validate_set_common_selection_set(item->validate , argc , argv); +} + +void config_schema_item_set_indexed_selection_set(config_schema_item_type * item , int index , int argc , const char ** argv) { + validate_set_indexed_selection_set(item->validate , index , argc , argv); +} + + +void config_schema_item_set_required_children(config_schema_item_type * item , stringlist_type * stringlist) { + item->required_children = stringlist_alloc_deep_copy(stringlist); +} + +void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key) { + if (item->required_children == NULL) + item->required_children = stringlist_alloc_new(); + + stringlist_append_copy( item->required_children , child_key ); +} + + +int config_schema_item_num_required_children(const config_schema_item_type * item) { + if (item->required_children == NULL) + return 0; + else + return stringlist_get_size( item->required_children ); +} + + +const char * config_schema_item_iget_required_child( const config_schema_item_type * item , int index) { + return stringlist_iget( item->required_children , index ); +} + + +const char * config_schema_item_get_kw( const config_schema_item_type * item ) { + return item->kw; +} + + +bool config_schema_item_required( const config_schema_item_type * item ) { + return item->required_set; +} + + +bool config_schema_item_expand_envvar( const config_schema_item_type * item ) { + return item->expand_envvar; +} + + +void config_schema_item_get_argc( const config_schema_item_type * item , int *argc_min , int *argc_max) { + *argc_min = item->validate->argc_min; + *argc_max = item->validate->argc_max; +} + + + +bool config_schema_item_has_required_children_value( const config_schema_item_type * item ) { + if (item->required_children_value == NULL) + return false; + else + return true; +} + + + +stringlist_type * config_schema_item_get_required_children_value(const config_schema_item_type * item , const char * value) { + return hash_safe_get( item->required_children_value , value ); +} + + +/*****************************************************************/ +/* Small functions to support enum introspection. */ + + +const char * config_schema_item_type_enum_iget( int index, int * value) { + return util_enum_iget( index , CONFIG_ITEM_TYPE_ENUM_SIZE , (const util_enum_element_type []) { CONFIG_ITEM_TYPE_ENUM_DEFS }, value); +} + + +const char * config_schema_item_unrecognized_enum_iget( int index, int * value) { + return util_enum_iget( index , CONFIG_SCHEMA_UNRECOGNIZED_ENUM_SIZE , (const util_enum_element_type []) { CONFIG_SCHEMA_UNRECOGNIZED_ENUM_DEFS }, value); +} diff --git a/ThirdParty/Ert/devel/libconfig/tests/CMakeLists.txt b/ThirdParty/Ert/devel/libconfig/tests/CMakeLists.txt new file mode 100644 index 0000000000..dde9e5e977 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/CMakeLists.txt @@ -0,0 +1,49 @@ +add_executable( config_append_test config_append_test.c ) +target_link_libraries( config_append_test config ) + +add_executable( config_node_test config_node_test.c ) +target_link_libraries( config_node_test config ) + +add_executable( config_typeOK config_typeOK.c ) +target_link_libraries( config_typeOK config ) + +add_executable( config_typeFail config_typeFail.c ) +target_link_libraries( config_typeFail config ) + +add_executable( config_path_elm config_path_elm.c ) +target_link_libraries( config_path_elm config ) + +add_executable( config_root_path config_root_path.c ) +target_link_libraries( config_root_path config ) + +add_executable( config_include_test config_include_test.c) +target_link_libraries( config_include_test config) + +add_executable( config_content_node config_content_node.c) +target_link_libraries( config_content_node config) + +add_executable( config_content_item config_content_item.c) +target_link_libraries( config_content_item config) + +add_executable( config_error config_error.c) +target_link_libraries( config_error config) +add_test( config_error ${EXECUTABLE_OUTPUT_PATH}/config_error ) + + +add_executable( config_config config_config.c) +target_link_libraries( config_config config) +add_test( config_config ${EXECUTABLE_OUTPUT_PATH}/config_config ) + +add_executable( config_schema_item config_schema_item.c) +target_link_libraries( config_schema_item config) +add_test( config_schema_item ${EXECUTABLE_OUTPUT_PATH}/config_schema_item ) + +add_test( config_typeOK ${EXECUTABLE_OUTPUT_PATH}/config_typeOK ${CMAKE_CURRENT_SOURCE_DIR}/data/type_testOK ) +add_test( config_typeFail ${EXECUTABLE_OUTPUT_PATH}/config_typeFail ${CMAKE_CURRENT_SOURCE_DIR}/data/type_testFail ) +add_test( config_append_test ${EXECUTABLE_OUTPUT_PATH}/config_append_test ${CMAKE_CURRENT_SOURCE_DIR}/data/append_test ) +add_test( config_node_test ${EXECUTABLE_OUTPUT_PATH}/config_node_test ${CMAKE_CURRENT_SOURCE_DIR}/data/append_test ) +add_test( config_path_elm ${EXECUTABLE_OUTPUT_PATH}/config_path_elm ) +add_test( config_content_node ${EXECUTABLE_OUTPUT_PATH}/config_content_node ) +add_test( config_content_item ${EXECUTABLE_OUTPUT_PATH}/config_content_item ${CMAKE_CURRENT_SOURCE_DIR}/data/content_item_test) +add_test( config_include_test ${EXECUTABLE_OUTPUT_PATH}/config_include_test ${CMAKE_CURRENT_SOURCE_DIR}/data include_test ) +add_test( config_root_path ${EXECUTABLE_OUTPUT_PATH}/config_root_path ${CMAKE_CURRENT_SOURCE_DIR}/data ) diff --git a/ThirdParty/Ert/devel/libconfig/tests/config_append_test.c b/ThirdParty/Ert/devel/libconfig/tests/config_append_test.c new file mode 100644 index 0000000000..1433f3c5f9 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/config_append_test.c @@ -0,0 +1,47 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_append_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include + +#include + + + + +int main(int argc , char ** argv) { + const char * config_file = argv[1]; + config_type * config = config_alloc(); + bool OK; + config_schema_item_type * item = config_add_schema_item(config , "APPEND" , false ); + config_schema_item_set_argc_minmax( item , 1 , 1); + + test_assert_true(config_parse(config , config_file , "--" , NULL , NULL , false , true )); + + { + test_assert_int_equal( config_get_occurences( config , "APPEND" ) , 3); + { + const char * value = config_get_value( config , "APPEND"); + test_assert_string_equal( value , "VALUE3"); + } + } + + test_assert_false( config_parse( config , "DoesNotExist" , "--" , NULL , NULL , false , true)); + exit(0); +} diff --git a/ThirdParty/Ert/devel/libconfig/tests/config_config.c b/ThirdParty/Ert/devel/libconfig/tests/config_config.c new file mode 100644 index 0000000000..f9d627c479 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/config_config.c @@ -0,0 +1,36 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'config_config.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include + +#include +#include + + +int main(int argc , char ** argv) { + config_type * config = config_alloc(); + config_schema_item_type * schema_item = config_add_schema_item( config , "KEYWORD" , false ); + config_free( config ); + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libconfig/tests/config_content_item.c b/ThirdParty/Ert/devel/libconfig/tests/config_content_item.c new file mode 100644 index 0000000000..ee0be46be8 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/config_content_item.c @@ -0,0 +1,58 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'config_content_item.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + + +int main(int argc , char ** argv) { + const char * config_file = argv[1]; + config_type * config = config_alloc(); + + config_add_schema_item( config , "SET" , true ); + config_add_schema_item( config , "NOTSET" , false ); + + test_assert_true( config_parse( config , config_file , "--" , "INCLUDE" , NULL , CONFIG_UNRECOGNIZED_IGNORE , true )); + + test_assert_not_NULL( config_get_content_item( config , "SET" )); + test_assert_NULL( config_get_content_item( config , "NOTSET" ) ); + test_assert_NULL( config_get_content_item( config , "UNKNOWN" ) ); + + test_assert_true( config_has_schema_item( config , "SET" )); + test_assert_true( config_has_schema_item( config , "NOTSET" )); + test_assert_false( config_has_schema_item( config , "UNKNOWN" )); + + test_assert_true( config_has_content_item( config , "SET" )); + test_assert_false( config_has_content_item( config , "NOTSET" )); + test_assert_false( config_has_content_item( config , "UNKNOWN" )); + + + + + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libconfig/tests/config_content_node.c b/ThirdParty/Ert/devel/libconfig/tests/config_content_node.c new file mode 100644 index 0000000000..f7289f60de --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/config_content_node.c @@ -0,0 +1,76 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'config_content_node.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include +#include + +#include +#include +#include + + +int main(int argc , char ** argv) { + config_schema_item_type * schema = config_schema_item_alloc("TEST" , true); + config_root_path_type * root_path = config_root_path_alloc( NULL ); + config_path_elm_type * cwd = config_path_elm_alloc( root_path , NULL ); + { + config_content_node_type * node = config_content_node_alloc( schema , cwd ); + config_content_node_add_value( node , "KEY1:VALUE1" ); + config_content_node_add_value( node , "KEY2:VALUE2" ); + config_content_node_add_value( node , "KEY3:VALUE3" ); + config_content_node_add_value( node , "KEYVALUE" ); + + test_assert_int_equal( config_content_node_get_size( node ) , 4 ); + test_assert_string_equal( config_content_node_iget( node , 0 ) , "KEY1:VALUE1" ); + test_assert_string_equal( config_content_node_iget( node , 2 ) , "KEY3:VALUE3" ); + + test_assert_string_equal( config_content_node_get_full_string( node , ",") , "KEY1:VALUE1,KEY2:VALUE2,KEY3:VALUE3,KEYVALUE"); + + { + hash_type * opt_hash = hash_alloc( ); + { + config_content_node_init_opt_hash( node , opt_hash , 0 ); + test_assert_int_equal( hash_get_size( opt_hash ) , 3 ); + test_assert_string_equal( hash_get( opt_hash , "KEY1" ) , "VALUE1" ); + test_assert_string_equal( hash_get( opt_hash , "KEY3" ) , "VALUE3" ); + } + + hash_clear( opt_hash ); + test_assert_int_equal( hash_get_size( opt_hash ) , 0 ); + config_content_node_init_opt_hash( node , opt_hash , 1 ); + test_assert_int_equal( hash_get_size( opt_hash ) , 2 ); + test_assert_string_equal( hash_get( opt_hash , "KEY2" ) , "VALUE2" ); + test_assert_string_equal( hash_get( opt_hash , "KEY3" ) , "VALUE3" ); + test_assert_false( hash_has_key( opt_hash , "KEY1" ) ); + test_assert_false( hash_has_key( opt_hash , "KEYVALUE" ) ); + hash_free( opt_hash ); + } + + + config_content_node_free( node ); + } + config_path_elm_free( cwd ); + config_root_path_free( root_path ); + config_schema_item_free( schema ); + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libconfig/tests/config_error.c b/ThirdParty/Ert/devel/libconfig/tests/config_error.c new file mode 100644 index 0000000000..5312d937d9 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/config_error.c @@ -0,0 +1,43 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_error.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include + +#include + +int main(int argc , char ** argv) { + config_error_type * config_error = config_error_alloc(); + + { + config_error_type * error_copy = config_error_alloc_copy( config_error ); + + test_assert_true( config_error_equal( config_error , error_copy )); + test_assert_ptr_not_equal( config_error , error_copy ); + + config_error_free( error_copy ); + } + + config_error_free( config_error ); + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libconfig/tests/config_include_test.c b/ThirdParty/Ert/devel/libconfig/tests/config_include_test.c new file mode 100644 index 0000000000..d1afa66261 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/config_include_test.c @@ -0,0 +1,133 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_include_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include + +#include +#include + +void parse_test(config_type * config , + const char * root_path , // The new working directory - the test will start by chdir() here. + const char * config_file ) { // The config_file, either as an absolute path - or relative from root_path + +#ifdef ERT_LINUX + const char * path0 = "PATH0"; + const char * path1 = "path/PATH1"; + const char * path2 = "path/PATH2"; + const char * path3 = "path/subpath/PATH3"; + const char * path4 = "path/subpath/subsubpath/PATH4"; +#endif + + + char * config_path, *config_rel_path,*config_abs_path; + path_stack_type * path_stack = path_stack_alloc(); + + util_alloc_file_components( config_file , &config_path , NULL , NULL); + path_stack_push( path_stack , NULL ); + if (root_path != NULL) + chdir( root_path ); + + config_abs_path = util_alloc_abs_path( config_path ); + config_rel_path = util_alloc_rel_path( NULL , config_abs_path); + + { + config_clear( config ); + if (config_parse( config , config_file , "--" , "INCLUDE" , NULL , CONFIG_UNRECOGNIZED_IGNORE , true )) { + + char * relpath0 = util_alloc_filename( config_rel_path , path0, NULL); + char * relpath1 = util_alloc_filename( config_rel_path , path1, NULL); + char * relpath2 = util_alloc_filename( config_rel_path , path2, NULL); + char * relpath3 = util_alloc_filename( config_rel_path , path3, NULL); + char * relpath4 = util_alloc_filename( config_rel_path , path4, NULL); + + char * abspath0 = util_alloc_filename( config_abs_path , path0, NULL); + char * abspath1 = util_alloc_filename( config_abs_path , path1, NULL); + char * abspath2 = util_alloc_filename( config_abs_path , path2, NULL); + char * abspath3 = util_alloc_filename( config_abs_path , path3, NULL); + char * abspath4 = util_alloc_filename( config_abs_path , path4, NULL); + + test_assert_string_equal(config_get_value_as_relpath(config , "PATH0") , relpath0 ); + test_assert_string_equal(config_get_value_as_relpath(config , "PATH1") , relpath1 ); + test_assert_string_equal(config_get_value_as_relpath(config , "PATH2") , relpath2 ); + test_assert_string_equal(config_get_value_as_relpath(config , "PATH3") , relpath3 ); + test_assert_string_equal(config_get_value_as_relpath(config , "PATH4") , relpath4 ); + + test_assert_string_equal(config_get_value_as_abspath(config , "PATH0") , abspath0 ); + test_assert_string_equal(config_get_value_as_abspath(config , "PATH1") , abspath1 ); + test_assert_string_equal(config_get_value_as_abspath(config , "PATH2") , abspath2 ); + test_assert_string_equal(config_get_value_as_abspath(config , "PATH3") , abspath3 ); + test_assert_string_equal(config_get_value_as_abspath(config , "PATH4") , abspath4 ); + + } else { + config_error_type * error = config_get_errors( config ); + config_error_fprintf( error , true , stdout ); + test_error_exit("Hmm - parsing %s failed \n", config_file ); + } + } + path_stack_pop( path_stack ); +} + + +int main(int argc , char ** argv) { + const char * abs_path = argv[1]; + const char * config_file = argv[2]; + char * abs_config_file = util_alloc_filename( abs_path , config_file , NULL); + config_type * config = config_alloc(); + + { + config_schema_item_type * schema_item; + + schema_item = config_add_schema_item( config , "PATH0" , true ); + config_schema_item_set_argc_minmax( schema_item , 1 , 1 ); + config_schema_item_iset_type( schema_item , 0 , CONFIG_PATH ); + + schema_item = config_add_schema_item( config , "PATH1" , true ); + config_schema_item_set_argc_minmax( schema_item , 1 , 1 ); + config_schema_item_iset_type( schema_item , 0 , CONFIG_PATH ); + + schema_item = config_add_schema_item( config , "PATH2" , true ); + config_schema_item_set_argc_minmax( schema_item , 1 , 1 ); + config_schema_item_iset_type( schema_item , 0 , CONFIG_PATH ); + + schema_item = config_add_schema_item( config , "PATH3" , true ); + config_schema_item_set_argc_minmax( schema_item , 1 , 1 ); + config_schema_item_iset_type( schema_item , 0 , CONFIG_PATH ); + + schema_item = config_add_schema_item( config , "PATH4" , true ); + config_schema_item_set_argc_minmax( schema_item , 1 , 1 ); + config_schema_item_iset_type( schema_item , 0 , CONFIG_PATH ); + } + + parse_test( config , abs_path , config_file ); + parse_test( config , abs_path , abs_config_file ); + parse_test( config , NULL , abs_config_file ); + parse_test( config , "../../" , abs_config_file ); + + config_free( config ); + exit(0); +} + + + + diff --git a/ThirdParty/Ert/devel/libconfig/tests/config_node_test.c b/ThirdParty/Ert/devel/libconfig/tests/config_node_test.c new file mode 100644 index 0000000000..75c3c2dccd --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/config_node_test.c @@ -0,0 +1,55 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_node_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include + + + +int main(int argc , char ** argv) { + const char * config_file = argv[1]; + config_type * config = config_alloc(); + bool OK; + { + config_schema_item_type * item = config_add_schema_item(config , "APPEND" , false ); + config_schema_item_set_argc_minmax( item , 1 , 1); + } + config_add_schema_item(config , "NEXT" , false ); + + OK = config_parse(config , config_file , "--" , NULL , NULL , false , true ); + + if (OK) { + if (config_get_content_size( config ) == 4) { + const config_content_node_type * node0 = config_iget_content_node( config , 0 ); + if (strcmp( config_content_node_get_kw( node0 ) , "APPEND") == 0) { + if (config_content_node_get_size(node0) == 1) { + const config_content_node_type * node3 = config_iget_content_node( config , 3 ); + if (strcmp( config_content_node_get_kw( node3 ) , "NEXT") == 0) { + if (config_content_node_get_size(node3) == 2) { + exit(0); + } else printf("Size error node3\n"); + } else printf("kw error node3 \n"); + } else printf("Size error node0\n"); + } else printf("kw error node0 kw:%s \n", config_content_node_get_kw( node0 )); + } else printf("Size error \n"); + } else printf("Parse error"); + + exit(1); +} + diff --git a/ThirdParty/Ert/devel/libconfig/tests/config_path_elm.c b/ThirdParty/Ert/devel/libconfig/tests/config_path_elm.c new file mode 100644 index 0000000000..0cd949bdcd --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/config_path_elm.c @@ -0,0 +1,92 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_path_elm.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include + +#include +#include +#include + +int main(int argc , char ** argv) { +#ifdef ERT_LINUX + const char * root = "/tmp/root"; + const char * rel_path = "rel/path"; + const char * abs_path = "/tmp/root/rel/path"; + const char * rel_true = "rel/path/XXX"; + const char * abs_true = "/tmp/root/rel/path/XXX"; + const char * path_true1 = "rel/path/XXX"; + const char * path_true2 = "/tmp/root/rel/path/XXX"; + +#endif + + util_make_path( root ); + config_root_path_type * root_path = config_root_path_alloc( root ); + { + config_path_elm_type * path_elm = config_path_elm_alloc( root_path , rel_path ); + + test_assert_string_equal( config_path_elm_get_relpath( path_elm ) , rel_path ); + test_assert_string_equal( config_path_elm_get_abspath( path_elm ) , abs_path ); + + test_assert_string_equal( config_path_elm_alloc_relpath( path_elm , "XXX" ) , rel_true); + test_assert_string_equal( config_path_elm_alloc_abspath( path_elm , "XXX" ) , abs_true); + test_assert_string_equal( config_path_elm_alloc_path( path_elm , "XXX" ) , path_true2 ); + + + config_path_elm_free( path_elm ); + } + printf("test1 OK \n"); + { + config_path_elm_type * path_elm = config_path_elm_alloc( root_path , abs_path ); + + test_assert_string_equal( config_path_elm_get_relpath( path_elm ) , rel_path ); + test_assert_string_equal( config_path_elm_get_abspath( path_elm ) , abs_path ); + + test_assert_string_equal( config_path_elm_alloc_relpath( path_elm , "XXX" ) , rel_true); + test_assert_string_equal( config_path_elm_alloc_abspath( path_elm , "XXX" ) , abs_true); + test_assert_string_equal( config_path_elm_alloc_path( path_elm , "XXX" ) , path_true2 ); + + config_path_elm_free( path_elm ); + } + printf("test2 OK \n"); + config_root_path_free( root_path ); + + chdir( root ); + root_path = config_root_path_alloc( NULL ); + { + config_path_elm_type * path_elm = config_path_elm_alloc( root_path , rel_path ); + + test_assert_string_equal( config_path_elm_get_relpath( path_elm ) , rel_path ); + test_assert_string_equal( config_path_elm_get_abspath( path_elm ) , abs_path ); + + test_assert_string_equal( config_path_elm_alloc_relpath( path_elm , "XXX" ) , rel_true); + test_assert_string_equal( config_path_elm_alloc_abspath( path_elm , "XXX" ) , abs_true); + test_assert_string_equal( config_path_elm_alloc_path( path_elm , "XXX" ) , path_true1 ); + + + config_path_elm_free( path_elm ); + } + printf("test3 OK \n"); + + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libconfig/tests/config_root_path.c b/ThirdParty/Ert/devel/libconfig/tests/config_root_path.c new file mode 100644 index 0000000000..e0f43a3982 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/config_root_path.c @@ -0,0 +1,88 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'config_root_path.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include + +#include +#include + + +int main(int argc , char ** argv) { +#ifdef ERT_LINUX + const char * root = "/tmp/root"; + const char * rel_path = "rel/path"; + const char * abs_path = "/tmp/root/abs/path"; + const char * rel_true = "rel/path/XXX"; + const char * abs_true = "/tmp/root/rel/path/XXX"; + const char * path_true1 = "rel/path/XXX"; + const char * path_true2 = "/tmp/root/rel/path/XXX"; +#endif + + char * cwd = util_alloc_cwd(); + + { + config_root_path_type * root_path = config_root_path_alloc( NULL ); + + if (!test_string_equal( config_root_path_get_abs_path( root_path ) , cwd )) + test_error_exit("abs:path:%s expeceted:%s \n",config_root_path_get_abs_path( root_path ) , cwd ); + + if (!test_string_equal( config_root_path_get_input_path( root_path ) , NULL )) + test_error_exit("input:path:%s expeceted:%s \n",config_root_path_get_input_path( root_path ) , NULL ); + + if (!test_string_equal( config_root_path_get_rel_path( root_path ) , NULL )) + test_error_exit("rel:path:%s expeceted:%s \n",config_root_path_get_rel_path( root_path ) , NULL ); + + + config_root_path_free( root_path ); + } + + + { + config_root_path_type * root_path = config_root_path_alloc( "/does/not/exist" ); + if (root_path != NULL) + test_error_exit("Created root_path instance for not-existing input \n"); + } + + + + { + const char * input_path = argv[1]; + char * cwd = util_alloc_cwd(); + char * rel_path = util_alloc_rel_path( cwd , input_path ); + + config_root_path_type * root_path1 = config_root_path_alloc( input_path ); + config_root_path_type * root_path2 = config_root_path_alloc( rel_path ); + + if (!test_string_equal( config_root_path_get_rel_path( root_path1 ) , config_root_path_get_rel_path( root_path2 ))) + test_error_exit("Rel: %s != %s \n",config_root_path_get_rel_path( root_path1 ) , config_root_path_get_rel_path( root_path2)); + + if (!test_string_equal( config_root_path_get_abs_path( root_path1 ) , config_root_path_get_abs_path( root_path2 ))) + test_error_exit("Abs: %s != %s \n",config_root_path_get_abs_path( root_path1 ) , config_root_path_get_abs_path( root_path2 )); + + config_root_path_free( root_path1 ); + config_root_path_free( root_path2 ); + } + + + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libconfig/tests/config_schema_item.c b/ThirdParty/Ert/devel/libconfig/tests/config_schema_item.c new file mode 100644 index 0000000000..69dc55238c --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/config_schema_item.c @@ -0,0 +1,48 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'config_schema_item.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include + +#include + + + +int main(int argc , char ** argv) { + config_schema_item_type * schema_item = config_schema_item_alloc( "KW" , false ); + + test_assert_int_equal( config_schema_item_iget_type( schema_item , 1 ) , CONFIG_STRING ); + test_assert_int_equal( config_schema_item_iget_type( schema_item , 2 ) , CONFIG_STRING ); + + config_schema_item_iset_type( schema_item , 0 , CONFIG_INT ); + config_schema_item_iset_type( schema_item , 5 , CONFIG_BOOL ); + + + test_assert_int_equal( config_schema_item_iget_type( schema_item , 0 ) , CONFIG_INT ); + test_assert_int_equal( config_schema_item_iget_type( schema_item , 1 ) , CONFIG_STRING ); + test_assert_int_equal( config_schema_item_iget_type( schema_item , 2 ) , CONFIG_STRING ); + test_assert_int_equal( config_schema_item_iget_type( schema_item , 5 ) , CONFIG_BOOL ); + + config_schema_item_set_default_type( schema_item , CONFIG_FLOAT ); + test_assert_int_equal( config_schema_item_iget_type( schema_item , 7 ) , CONFIG_FLOAT ); + + config_schema_item_free( schema_item ); + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libconfig/tests/config_typeFail.c b/ThirdParty/Ert/devel/libconfig/tests/config_typeFail.c new file mode 100644 index 0000000000..5514dd94a0 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/config_typeFail.c @@ -0,0 +1,67 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_typeFail.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include + + +void error(char * msg) { + fprintf(stderr , msg); + exit(1); +} + + +int main(int argc , char ** argv) { + const char * config_file = argv[1]; + config_type * config = config_alloc(); + bool OK; + { + config_schema_item_type * item = config_add_schema_item(config , "TYPES_KEY" , false ); + config_schema_item_set_argc_minmax( item , 4 , 4 ); + config_schema_item_iset_type( item , 0 , CONFIG_INT ); + config_schema_item_iset_type( item , 1 , CONFIG_FLOAT ); + config_schema_item_iset_type( item , 2 , CONFIG_BOOL ); + + item = config_add_schema_item( config , "SHORT_KEY" , false ); + config_schema_item_set_argc_minmax( item , 1 , 1 ); + + item = config_add_schema_item( config , "LONG_KEY" , false ); + config_schema_item_set_argc_minmax( item , 3 , CONFIG_DEFAULT_ARG_MAX); + } + OK = config_parse(config , config_file , "--" , NULL , NULL , false , true ); + + if (OK) { + error("Parse error\n"); + } else { + config_error_type * cerror = config_get_errors( config ); + if (config_error_count( cerror ) > 0) { + int i; + for (i=0; i < config_error_count( cerror ); i++) { + printf("Error %d: %s \n",i , config_error_iget( cerror , i )); + } + } + printf("Error count:%d \n",config_error_count( cerror )); + if (config_error_count( cerror ) != 5) + error("Wrong error count\n"); + } + printf("OK \n"); + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libconfig/tests/config_typeOK.c b/ThirdParty/Ert/devel/libconfig/tests/config_typeOK.c new file mode 100644 index 0000000000..83aded9a60 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/config_typeOK.c @@ -0,0 +1,55 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_typeOK.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include + + +void error(char * msg) { + fprintf(stderr , msg); + exit(1); +} + + +int main(int argc , char ** argv) { + const char * config_file = argv[1]; + config_type * config = config_alloc(); + bool OK; + { + config_schema_item_type * item = config_add_schema_item(config , "TYPE_KEY" , false ); + config_schema_item_set_argc_minmax( item , 4 , 4 ); + config_schema_item_iset_type( item , 0 , CONFIG_INT ); + config_schema_item_iset_type( item , 1 , CONFIG_FLOAT ); + config_schema_item_iset_type( item , 2 , CONFIG_BOOL ); + + item = config_add_schema_item( config , "SHORT_KEY" , false ); + config_schema_item_set_argc_minmax( item , 1 , 1 ); + + item = config_add_schema_item( config , "LONG_KEY" , false ); + config_schema_item_set_argc_minmax( item , 3 , CONFIG_DEFAULT_ARG_MAX ); + } + OK = config_parse(config , config_file , "--" , NULL , NULL , false , true ); + + if (OK) { + + } else error("Parse error\n"); + + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libconfig/tests/data/append_test b/ThirdParty/Ert/devel/libconfig/tests/data/append_test new file mode 100644 index 0000000000..8af962aaa2 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/data/append_test @@ -0,0 +1,4 @@ +APPEND VALUE1 +APPEND VALUE2 +APPEND VALUE3 +NEXT VALUE4 VALUE5 \ No newline at end of file diff --git a/ThirdParty/Ert/devel/libconfig/tests/data/content_item_test b/ThirdParty/Ert/devel/libconfig/tests/data/content_item_test new file mode 100644 index 0000000000..403ef6ae3e --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/data/content_item_test @@ -0,0 +1 @@ +SET SetValue diff --git a/ThirdParty/Ert/devel/libconfig/tests/data/include_test b/ThirdParty/Ert/devel/libconfig/tests/data/include_test new file mode 100644 index 0000000000..9717f9dcaf --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/data/include_test @@ -0,0 +1,3 @@ +PATH0 PATH0 +INCLUDE path/include1 +INCLUDE path/subpath/include2 \ No newline at end of file diff --git a/ThirdParty/Ert/devel/libconfig/tests/data/path/include1 b/ThirdParty/Ert/devel/libconfig/tests/data/path/include1 new file mode 100644 index 0000000000..24c1ce46d0 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/data/path/include1 @@ -0,0 +1,5 @@ +PATH1 PATH1 +PATH2 PATH2 + +INCLUDE subpath/include3 +INCLUDE subpath/subsubpath/include4 \ No newline at end of file diff --git a/ThirdParty/Ert/devel/libconfig/tests/data/path/subpath/include2 b/ThirdParty/Ert/devel/libconfig/tests/data/path/subpath/include2 new file mode 100644 index 0000000000..df203e9835 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/data/path/subpath/include2 @@ -0,0 +1 @@ +PATH2 PATH2 \ No newline at end of file diff --git a/ThirdParty/Ert/devel/libconfig/tests/data/path/subpath/include3 b/ThirdParty/Ert/devel/libconfig/tests/data/path/subpath/include3 new file mode 100644 index 0000000000..85a8dae08a --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/data/path/subpath/include3 @@ -0,0 +1 @@ +PATH3 PATH3 \ No newline at end of file diff --git a/ThirdParty/Ert/devel/libconfig/tests/data/path/subpath/subsubpath/include4 b/ThirdParty/Ert/devel/libconfig/tests/data/path/subpath/subsubpath/include4 new file mode 100644 index 0000000000..9bb116f3a4 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/data/path/subpath/subsubpath/include4 @@ -0,0 +1 @@ +PATH4 PATH4 \ No newline at end of file diff --git a/ThirdParty/Ert/devel/libconfig/tests/data/type_testFail b/ThirdParty/Ert/devel/libconfig/tests/data/type_testFail new file mode 100644 index 0000000000..f54ebe9a10 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/data/type_testFail @@ -0,0 +1,6 @@ +TYPES_KEY 100 0.75 rue String +TYPES_KEY 100 0.75 True String +TYPES_KEY 100 0.75X True String +TYPES_KEY 100X 0.75 True String +SHORT_KEY 100 100 +LONG_KEY 100 100 diff --git a/ThirdParty/Ert/devel/libconfig/tests/data/type_testOK b/ThirdParty/Ert/devel/libconfig/tests/data/type_testOK new file mode 100644 index 0000000000..7801b99a58 --- /dev/null +++ b/ThirdParty/Ert/devel/libconfig/tests/data/type_testOK @@ -0,0 +1,4 @@ +TYPES_KEY 100 0.75 True String +SHORT_KEY 100 +LONG_KEY 100 100 100 +LONG_KEY asc asc asc asc asc asc as asc sac asc sac sca sca sa sac \ No newline at end of file diff --git a/ThirdParty/Ert/devel/libecl/CMakeLists.txt b/ThirdParty/Ert/devel/libecl/CMakeLists.txt index acb1c9d2f4..90b94538d4 100644 --- a/ThirdParty/Ert/devel/libecl/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libecl/CMakeLists.txt @@ -1,8 +1,9 @@ add_subdirectory( src ) -if (BUILD_APPLICATONS OR BUILD_ECL_SUMMARY) - add_subdirectory( applications ) -endif() +#if (BUILD_APPLICATIONS OR BUILD_ECL_SUMMARY) +# add_subdirectory( applications ) +#endif() +add_subdirectory( applications ) if (BUILD_TESTS) add_subdirectory( tests ) endif() diff --git a/ThirdParty/Ert/devel/libecl/applications/CMakeLists.txt b/ThirdParty/Ert/devel/libecl/applications/CMakeLists.txt index 80644e6dea..afc4dba904 100644 --- a/ThirdParty/Ert/devel/libecl/applications/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libecl/applications/CMakeLists.txt @@ -4,6 +4,7 @@ if (BUILD_APPLICATIONS) add_executable( grdecl_grid grdecl_grid.c ) add_executable( summary2csv summary2csv.c ) if (ERT_LINUX) + add_executable( esummary.x esummary.c ) add_executable( convert.x convert.c ) add_executable( grdecl_test.x grdecl_test.c ) add_executable( kw_list.x kw_list.c ) @@ -14,7 +15,7 @@ if (BUILD_APPLICATIONS) add_executable( summary.x view_summary.c ) add_executable( select_test.x select_test.c ) add_executable( load_test.x load_test.c ) - set(program_list summary2csv kw_extract.x grdecl_grid make_grid sum_write load_test.x grdecl_test.x grid_dump_ascii.x select_test.x grid_dump.x convert.x kw_list.x grid_info.x summary.x) + set(program_list summary2csv esummary.x kw_extract.x grdecl_grid make_grid sum_write load_test.x grdecl_test.x grid_dump_ascii.x select_test.x grid_dump.x convert.x kw_list.x grid_info.x summary.x) else() # The stupid .x extension creates problems on windows add_executable( convert convert.c ) @@ -36,10 +37,12 @@ if (BUILD_APPLICATIONS) #----------------------------------------------------------------- set (destination ${CMAKE_INSTALL_PREFIX}/bin) - install(TARGETS ${prog} DESTINATION ${destination}) - if (INSTALL_GROUP) - install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/${prog})") - install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/${prog})") + if (INSTALL_ERT) + install(TARGETS ${prog} DESTINATION ${destination}) + if (INSTALL_GROUP) + install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/${prog})") + install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/${prog})") + endif() endif() endforeach() endif() @@ -47,13 +50,15 @@ endif() if (BUILD_ENS_PLOT) include_directories( ${PLPLOT_HEADER} ) add_executable( ens_plot.x ens_plot.c ) - target_link_libraries( ens_plot.x plot ecl ert_util) + target_link_libraries( ens_plot.x plot ecl) set (destination ${CMAKE_INSTALL_PREFIX}/bin) - install(TARGETS ens_plot.x DESTINATION ${destination}) - if (INSTALL_GROUP) - install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/ens_plot.x)") - install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/ens_plot.x)") + if (INSTALL_ERT) + install(TARGETS ens_plot.x DESTINATION ${destination}) + if (INSTALL_GROUP) + install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/ens_plot.x)") + install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/ens_plot.x)") + endif() endif() endif() @@ -61,13 +66,15 @@ endif() if (BUILD_ECL_SUMMARY) add_executable( ecl_summary view_summary.c ) - target_link_libraries( ecl_summary ecl ert_util) + target_link_libraries( ecl_summary ecl) set (destination ${CMAKE_INSTALL_PREFIX}/bin) - install(TARGETS ecl_summary DESTINATION ${destination}) - if (INSTALL_GROUP) - install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/ecl_summary)") - install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/ecl_summary)") + if (INSTALL_ERT) + install(TARGETS ecl_summary DESTINATION ${destination}) + if (INSTALL_GROUP) + install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/ecl_summary)") + install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/ecl_summary)") + endif() endif() endif() diff --git a/ThirdParty/Ert/devel/libecl/applications/ecl_quantile.c b/ThirdParty/Ert/devel/libecl/applications/ecl_quantile.c index d4748b4f00..a1207eb4a8 100644 --- a/ThirdParty/Ert/devel/libecl/applications/ecl_quantile.c +++ b/ThirdParty/Ert/devel/libecl/applications/ecl_quantile.c @@ -33,6 +33,8 @@ #include #include +#include +#include #include @@ -222,16 +224,23 @@ void ensemble_init( ensemble_type * ensemble , config_type * config) { thread_pool_type * tp = thread_pool_alloc( LOAD_THREADS , true ); { int i,j; - for (i=0; i < config_get_occurences( config , "CASE_LIST"); i++) { - const stringlist_type * case_list = config_iget_stringlist_ref( config , "CASE_LIST" , i ); - for (j=0; j < stringlist_get_size( case_list ); j++) - ensemble_load_from_glob( ensemble , stringlist_iget( case_list , j ) , tp); + const config_content_item_type * case_item = config_get_content_item( config , "CASE_LIST" ); + + if (case_item != NULL) { + for (j=0; j < config_content_node_get_size( case_item ); j++) { + const config_content_node_type * case_node = config_content_item_iget_node( case_item ); + for (i=0; i < config_content_node_get_size( case_node ) i++) { + const char * case_glob = config_content_node_iget( case_node , i ); + ensemble_load_from_glob( ensemble , case_glob , tp); + } + } } + } thread_pool_join( tp ); thread_pool_free( tp ); } - + { const sum_case_type * tmp = vector_iget_const( ensemble->data , 0 ); ensemble->refcase = tmp->ecl_sum; @@ -347,17 +356,21 @@ static void output_add_key( const ecl_sum_type * refcase , output_type * output void output_table_init( const ecl_sum_type * refcase, hash_type * output_table , const config_type * config ) { int i,j; - for (i=0; i < config_get_occurences( config , "OUTPUT" ); i++) { - const stringlist_type * tokens = config_iget_stringlist_ref( config , "OUTPUT" , i); - const char * file = stringlist_iget( tokens , 0 ); - const char * format_string = stringlist_iget( tokens , 1 ); - output_type * output = output_alloc( file , format_string ); + const config_content_item_type * output_item = config_get_content_item( config , "OUTPUT"); + if (output_item != NULL) { + for (i = 0; i < config_content_item_get_size( output_item ); i++) { + const config_content_node_type * output_node = config_content_item_iget_node( output_item , i ); + + const char * file = config_content_node_iget( output_node , 0 ); + const char * format_string = config_content_node_iget( output_node , 1 ); + output_type * output = output_alloc( file , format_string ); - /* All the keys are just added - without any check. */ - for (j = 2; j < stringlist_get_size( tokens ); j++) - output_add_key( refcase , output , stringlist_iget( tokens , j)); - - hash_insert_hash_owned_ref( output_table , file , output , output_free__ ); + /* All the keys are just added - without any check. */ + for (j = 2; j < config_content_node_get_size( output_node ); j++) + output_add_key( refcase , output , config_content_node_iget( output_node , j)); + + hash_insert_hash_owned_ref( output_table , file , output , output_free__ ); + } } } @@ -713,7 +726,7 @@ void config_init( config_type * config ) { { config_schema_item_type * item; item = config_add_schema_item( config , "OUTPUT" , true , true ); - config_schema_item_set_argc_minmax( item , 2 , -1 , 0 , NULL ); + config_schema_item_set_argc_minmax( item , 2 , CONFIG_DEFAULT_ARG_MAX , 0 , NULL ); config_schema_item_set_indexed_selection_set( item , 1 , 3 , (const char *[3]) { S3GRAPH_STRING , HEADER_STRING , PLAIN_STRING }); } @@ -815,16 +828,18 @@ int main( int argc , char ** argv ) { const char * config_arg = argv[1]; config_init( config ); - config_parse( config , config_arg , "--" , NULL , NULL , true , true ); - - { + if (config_parse( config , config_arg , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_WARN, true )) { char * config_path; util_alloc_file_components( config_arg , &config_path , NULL , NULL); if (config_path != NULL) { chdir( config_path ); free( config_path ); } + } else { + config_fprintf_errors( config , stderr ); + exit(1); } + ensemble_init( ensemble , config ); diff --git a/ThirdParty/Ert/devel/libecl/applications/esummary.c b/ThirdParty/Ert/devel/libecl/applications/esummary.c index bd1241d65c..4ecb00b189 100644 --- a/ThirdParty/Ert/devel/libecl/applications/esummary.c +++ b/ThirdParty/Ert/devel/libecl/applications/esummary.c @@ -16,13 +16,16 @@ for more details. */ -#include #include -#include -#include #include #include -#include + +#include +#include +#include + +#include +#include void install_SIGNALS(void) { @@ -39,6 +42,8 @@ void usage() { } +#define MISSING_STRING " 0.000" + int main(int argc , char ** argv) { @@ -49,6 +54,12 @@ int main(int argc , char ** argv) { { ecl_sum_type * first_ecl_sum; /* This governs the timing */ vector_type * ecl_sum_list = vector_alloc_new(); + time_interval_type * time_union = NULL; + time_interval_type * time_intersect = NULL; + time_interval_type * time = NULL; + bool use_time_union = true; + + int load_count = 0; int nvars; char ** var_list; bool * has_var; @@ -61,51 +72,46 @@ int main(int argc , char ** argv) { char * path , * basename; ecl_sum_type * ecl_sum; util_alloc_file_components( argv[iarg] , &path , &basename , NULL); - ecl_sum = ecl_sum_fread_alloc_case( argv[iarg] , ":"); - if (iarg == 1) - first_ecl_sum = ecl_sum; /* Keep track of this - might sort the vector */ - fprintf(stderr,"Loading case: %s/%s" , path , basename); fflush(stderr); - vector_append_owned_ref( ecl_sum_list , ecl_sum , ecl_sum_free__ ); + ecl_sum = ecl_sum_fread_alloc_case( argv[iarg] , ":"); + + if (iarg == 1) { + first_ecl_sum = ecl_sum; /* Keep track of this - might sort the vector */ + time_union = time_interval_alloc_copy( ecl_sum_get_sim_time( ecl_sum )); + time_intersect = time_interval_alloc_copy( ecl_sum_get_sim_time( ecl_sum )); + + if (use_time_union) + time = time_union; + else + time = time_intersect; + vector_append_owned_ref( ecl_sum_list , ecl_sum , ecl_sum_free__ ); + } else { + const time_interval_type * ti = ecl_sum_get_sim_time( ecl_sum ); + if (time_interval_has_overlap(time , ti)) { + time_interval_intersect( time_intersect , ti ); + time_interval_extend( time_union , ti ); + + vector_append_owned_ref( ecl_sum_list , ecl_sum , ecl_sum_free__ ); + load_count++; + } else { + fprintf(stderr,"** Warning case:%s has no time overlap - discarded \n",ecl_sum_get_case( ecl_sum )); + ecl_sum_free( ecl_sum ); + } + } + iarg++; fprintf(stderr,"\n"); util_safe_free( path ); free( basename ); } } - nvars = argc - vector_get_size( ecl_sum_list ) - 1; + if (load_count == 0) + usage(); + + nvars = argc - load_count - 1; if (nvars == 0) util_exit(" --- No variables \n"); - var_list = &argv[vector_get_size( ecl_sum_list ) + 1]; + var_list = &argv[load_count + 1]; has_var = util_calloc( nvars , sizeof * has_var ); - - - /** Checking time consistency - and discarding those with unmatching time vector. */ - { - int i; - time_t_vector_type * first_time = ecl_sum_alloc_time_vector( vector_iget_const( ecl_sum_list , 0) , true ); - - for (i=1; i < vector_get_size( ecl_sum_list); i++) { - time_t_vector_type * time_vector; - const ecl_sum_type * ecl_sum = vector_iget_const( ecl_sum_list , i ); - if (ecl_sum_get_first_report_step( ecl_sum ) >= 0 ) { - time_vector = ecl_sum_alloc_time_vector( ecl_sum , true ); - int i; - for (i=0; i < util_int_min( time_t_vector_size( first_time ) , time_t_vector_size( time_vector )); i++) { - if (time_t_vector_iget( first_time , i) != time_t_vector_iget(time_vector , i)) { - vector_iset_ref( ecl_sum_list , i , NULL); - printf("Discarding case:%s due to time inconsistencies \n" , ecl_sum_get_case( ecl_sum )); - break; - } - } - time_t_vector_free( time_vector ); - } else { - vector_iset_ref( ecl_sum_list , i , NULL); - printf("Discarding case:%s - no data \n" , ecl_sum_get_case( ecl_sum )); - } - } - time_t_vector_free( first_time ); - } - /* Checking that the summary files have the various variables - @@ -131,39 +137,55 @@ int main(int argc , char ** argv) { } } } - - + + if (!time_interval_equal(time_union , time_intersect )) { + fprintf(stderr,"** Warning: not all simulations have the same length. "); + if (use_time_union) + fprintf(stderr,"Using %s for missing values.\n" , MISSING_STRING); + else + fprintf(stderr,"Only showing common time period.\n"); + } + /** The actual summary lookup. */ { - int first_report = ecl_sum_get_first_report_step( first_ecl_sum ); - int last_report = ecl_sum_get_last_report_step( first_ecl_sum ); + time_t_vector_type * date_list = time_t_vector_alloc(0,0); + time_t start_time = time_interval_get_start( time ); FILE * stream = stdout; - int iens,ivar,report; + int iens,ivar,itime; - for (report = first_report; report <= last_report; report++) { + ecl_util_init_month_range( date_list , time_interval_get_start( time ) , time_interval_get_end( time )); + for (itime = 0; itime < time_t_vector_size( date_list ); itime++) { + time_t current_time = time_t_vector_iget( date_list , itime ); for (ivar = 0; ivar < nvars; ivar++) { /* Iterating over the variables */ if (has_var[ivar]) { for (iens = 0; iens < vector_get_size( ecl_sum_list ); iens++) { /* Iterating over the ensemble members */ const ecl_sum_type * ecl_sum = vector_iget_const( ecl_sum_list , iens ); - double value = 0; - int end_index; - if (ecl_sum_has_report_step(ecl_sum , report)) { - end_index = ecl_sum_iget_report_end( ecl_sum , report ); - if (end_index >= 0) { - if (ivar == 0 && iens == 0) { /* Display time info in the first columns */ - int day,month,year; - util_set_date_values(ecl_sum_iget_sim_time(ecl_sum , end_index) , &day , &month, &year); - fprintf(stream , "%7.2f %02d/%02d/%04d " , ecl_sum_iget_sim_days(ecl_sum , end_index) , day , month , year); - } - value = ecl_sum_get_general_var(ecl_sum , end_index , var_list[ivar]); - } + + if (ivar == 0 && iens == 0) { /* Display time info in the first columns */ + int day,month,year; + util_set_date_values( current_time , &day , &month, &year); + fprintf(stream , "%7.2f %02d/%02d/%04d " , util_difftime_days( start_time , current_time ) , day , month , year); + } + + { + const time_interval_type * sim_time = ecl_sum_get_sim_time( ecl_sum ); + + if (time_interval_arg_before( sim_time , current_time)) + fprintf(stream , " %s " , MISSING_STRING); // We are before this case has data. + else if (time_interval_arg_after( sim_time , current_time)) + fprintf(stream , " %s " , MISSING_STRING); // We are after this case has data. + else { + double value = ecl_sum_get_general_var_from_sim_time(ecl_sum , current_time , var_list[ivar]); + fprintf(stream , " %12.3f " , value); + } + } - fprintf(stream , " %12.3f " , value); } } } fprintf(stream , "\n"); } + time_t_vector_free( date_list ); } vector_free( ecl_sum_list ); free( has_var ); diff --git a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_grid.h b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_grid.h index 00decbc2e2..cbd8a73f1a 100644 --- a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_grid.h +++ b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_grid.h @@ -79,6 +79,7 @@ extern "C" { ecl_grid_type * ecl_grid_alloc_GRDECL_data(int , int , int , const float * , const float * , const int * , const float * mapaxes); ecl_grid_type * ecl_grid_alloc_GRID_data(int num_coords , int nx, int ny , int nz , int coords_size , int ** coords , float ** corners , const float * mapaxes); ecl_grid_type * ecl_grid_alloc(const char * ); + bool ecl_grid_file_dims( const char * grid_filename , const char * init_restart_filename , int * dims); ecl_grid_type * ecl_grid_load_case( const char * case_input ); ecl_grid_type * ecl_grid_alloc_rectangular( int nx , int ny , int nz , double dx , double dy , double dz , const int * actnum); ecl_grid_type * ecl_grid_alloc_regular( int nx, int ny , int nz , const double * ivec, const double * jvec , const double * kvec , const int * actnum); @@ -149,7 +150,7 @@ extern "C" { double ecl_grid_get_double_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k); int ecl_grid_get_int_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k); - void ecl_grid_grdecl_fprintf_kw( const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , FILE * stream , double double_default); + void ecl_grid_grdecl_fprintf_kw( const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream , double double_default); bool ecl_grid_test_lgr_consistency( const ecl_grid_type * ecl_grid ); void ecl_grid_fwrite_EGRID( ecl_grid_type * grid , const char * filename); diff --git a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_kw.h b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_kw.h index b53f614328..fe04cf3433 100644 --- a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_kw.h +++ b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_kw.h @@ -98,6 +98,7 @@ extern "C" { bool ecl_kw_numeric_equal(const ecl_kw_type *ecl_kw1, const ecl_kw_type *ecl_kw2 , double rel_diff); bool ecl_kw_block_equal( const ecl_kw_type * ecl_kw1 , const ecl_kw_type * ecl_kw2 , int cmp_elements); bool ecl_kw_data_equal( const ecl_kw_type * ecl_kw , const void * data); + bool ecl_kw_content_equal( const ecl_kw_type * ecl_kw1 , const ecl_kw_type * ecl_kw2); void ecl_kw_fskip_data__( ecl_type_enum ecl_type , int size , fortio_type * fortio); void ecl_kw_fskip_data(ecl_kw_type *ecl_kw, fortio_type *fortio); void ecl_kw_fread_data(ecl_kw_type *ecl_kw, fortio_type *fortio); diff --git a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_kw_grdecl.h b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_kw_grdecl.h index bd824dc599..9ed3845e0e 100644 --- a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_kw_grdecl.h +++ b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_kw_grdecl.h @@ -48,6 +48,7 @@ extern "C" { char * ecl_kw_grdecl_alloc_next_header( FILE * stream ); void ecl_kw_fprintf_grdecl(const ecl_kw_type * ecl_kw , FILE * stream); + void ecl_kw_fprintf_grdecl__(const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_intehead.h b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_rsthead.h similarity index 70% rename from ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_intehead.h rename to ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_rsthead.h index 5819fccecd..a128e2adf1 100644 --- a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_intehead.h +++ b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_rsthead.h @@ -1,7 +1,7 @@ /* Copyright (C) 2011 Statoil ASA, Norway. - The file 'ecl_INTEHEAD.h' is part of ERT - Ensemble based Reservoir Tool. + The file 'ecl_RSTHEAD.h' is part of ERT - Ensemble based Reservoir Tool. ERT 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 +16,8 @@ for more details. */ -#ifndef __ECL_INTEHEAD_H__ -#define __ECL_INTEHEAD_H__ +#ifndef __ECL_RSTHEAD_H__ +#define __ECL_RSTHEAD_H__ #ifdef __cplusplus extern "C" { @@ -25,9 +25,9 @@ extern "C" { #include +#include #include -#define INTEHEAD_KW "INTEHEAD" /* Long array with lots of data. */ typedef struct { int day; @@ -63,14 +63,24 @@ extern "C" { int nswlmx; // The maximum number of segmented wells int nlbrmx; // The maximum number of lateral branches pr well int nilbrz; // The number of entries pr segment in ILBR array - } ecl_intehead_type; + + // Properteies from the LOGIHEAD keyword: + bool dualp; + + + // Properties from the DOUBHEAD keyword: + double sim_days; + } ecl_rsthead_type; - void ecl_intehead_free( ecl_intehead_type * intehead ); - ecl_intehead_type * ecl_intehead_alloc( const ecl_kw_type * intehead_kw ); - time_t ecl_intehead_date( const ecl_kw_type * intehead_kw ); - void ecl_intehead_fprintf( const ecl_intehead_type * header , FILE * stream); + void ecl_rsthead_free( ecl_rsthead_type * rsthead ); + ecl_rsthead_type * ecl_rsthead_ialloc( const ecl_file_type * rst_file , int occurence); + ecl_rsthead_type * ecl_rsthead_alloc( const ecl_file_type * rst_file ); + time_t ecl_rsthead_date( const ecl_kw_type * intehead_kw ); + void ecl_rsthead_fprintf( const ecl_rsthead_type * header , FILE * stream); + void ecl_rsthead_fprintf_struct( const ecl_rsthead_type * header , FILE * stream); + bool ecl_rsthead_equal( const ecl_rsthead_type * header1 , const ecl_rsthead_type * header2); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_sum.h b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_sum.h index 22f54b2b2e..c62fc61f42 100644 --- a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_sum.h +++ b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_sum.h @@ -30,6 +30,7 @@ extern "C" { #include #include #include +#include #include #include @@ -59,6 +60,7 @@ typedef struct ecl_sum_struct ecl_sum_type; double ecl_sum_get_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const smspec_node_type * node); double ecl_sum_get_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const smspec_node_type * node); + double ecl_sum_time2days( const ecl_sum_type * ecl_sum , time_t sim_time); void ecl_sum_set_unified( ecl_sum_type * ecl_sum , bool unified ); void ecl_sum_set_fmt_case( ecl_sum_type * ecl_sum , bool fmt_case ); @@ -158,6 +160,7 @@ typedef struct ecl_sum_struct ecl_sum_type; time_t ecl_sum_get_data_start( const ecl_sum_type * ecl_sum ); time_t ecl_sum_get_end_time( const ecl_sum_type * ecl_sum); time_t ecl_sum_get_start_time(const ecl_sum_type * ); + const time_interval_type * ecl_sum_get_sim_time( const ecl_sum_type * ecl_sum); const char * ecl_sum_get_base(const ecl_sum_type * ecl_sum ); const char * ecl_sum_get_path(const ecl_sum_type * ecl_sum ); diff --git a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_sum_data.h b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_sum_data.h index e8d9593c21..496eecb00b 100644 --- a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_sum_data.h +++ b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_sum_data.h @@ -29,6 +29,7 @@ extern "C" { #include #include #include +#include #include #include @@ -40,6 +41,7 @@ typedef struct ecl_sum_data_struct ecl_sum_data_type ; void ecl_sum_data_fread_restart( ecl_sum_data_type * data , const stringlist_type * filelist); ecl_sum_data_type * ecl_sum_data_alloc_writer( ecl_smspec_type * smspec ); ecl_sum_data_type * ecl_sum_data_alloc( ecl_smspec_type * smspec); + double ecl_sum_data_time2days( const ecl_sum_data_type * data , time_t sim_time); int ecl_sum_data_get_report_step_from_time(const ecl_sum_data_type * data , time_t sim_time); int ecl_sum_data_get_report_step_from_days(const ecl_sum_data_type * data , double days); bool ecl_sum_data_check_sim_time( const ecl_sum_data_type * data , time_t sim_time); @@ -52,6 +54,7 @@ typedef struct ecl_sum_data_struct ecl_sum_data_type ; time_t ecl_sum_data_get_data_start( const ecl_sum_data_type * data ); time_t ecl_sum_data_get_report_time( const ecl_sum_data_type * data , int report_step); double ecl_sum_data_get_first_day( const ecl_sum_data_type * data); + const time_interval_type * ecl_sum_data_get_sim_time( const ecl_sum_data_type * data); time_t ecl_sum_data_get_sim_start ( const ecl_sum_data_type * data ); time_t ecl_sum_data_get_sim_end ( const ecl_sum_data_type * data ); double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data ); diff --git a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_util.h b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_util.h index 518f58be4c..371bd62870 100644 --- a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_util.h +++ b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_util.h @@ -25,6 +25,7 @@ extern "C" { #include #include +#include typedef enum { ECL_OTHER_FILE = 0 , ECL_RESTART_FILE = 1 , @@ -178,6 +179,8 @@ const char * ecl_util_get_phase_name( ecl_phase_enum phase ); const char * ecl_util_file_enum_iget( int index, int * value); int ecl_util_select_filelist( const char * path , const char * base , ecl_file_enum file_type , bool fmt_file , stringlist_type * filelist); +void ecl_util_append_month_range( time_t_vector_type * date_list , time_t start_date , time_t end_date , bool force_append_end); +void ecl_util_init_month_range( time_t_vector_type * date_list , time_t start_date , time_t end_date); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libecl/include/ert/ecl/smspec_node.h b/ThirdParty/Ert/devel/libecl/include/ert/ecl/smspec_node.h index 11f3b1fde4..725376e9ca 100644 --- a/ThirdParty/Ert/devel/libecl/include/ert/ecl/smspec_node.h +++ b/ThirdParty/Ert/devel/libecl/include/ert/ecl/smspec_node.h @@ -113,6 +113,7 @@ typedef enum {ECL_SMSPEC_INVALID_VAR = 0 , void smspec_node_set_unit( smspec_node_type * smspec_node , const char * unit ); bool smspec_node_is_rate( const smspec_node_type * smspec_node ); bool smspec_node_is_total( const smspec_node_type * smspec_node ); + bool smspec_node_is_historical( const smspec_node_type * smspec_node ); bool smspec_node_need_nums( const smspec_node_type * smspec_node ); void smspec_node_fprintf( const smspec_node_type * smspec_node , FILE * stream); diff --git a/ThirdParty/Ert/devel/libecl/src/CMakeLists.txt b/ThirdParty/Ert/devel/libecl/src/CMakeLists.txt index a6e51931f1..309ccd43da 100644 --- a/ThirdParty/Ert/devel/libecl/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libecl/src/CMakeLists.txt @@ -2,9 +2,9 @@ include_directories( ext ) file(GLOB ext_source "ext/*.c" ) file(GLOB ext_header "ext/*.h" ) -set( source_files ecl_sum_tstep.c ecl_rst_file.c ecl_init_file.c ecl_grid_cache.c smspec_node.c ecl_kw_grdecl.c ecl_file_kw.c ecl_grav.c ecl_grav_calc.c ecl_smspec.c ecl_sum_data.c ecl_util.c ecl_kw.c ecl_sum.c fortio.c ecl_rft_file.c ecl_rft_node.c ecl_grid.c ecl_coarse_cell.c ecl_box.c ecl_io_config.c ecl_file.c ecl_region.c point.c tetrahedron.c ecl_intehead.c ecl_subsidence.c ecl_grav_common.c ${ext_source}) +set( source_files ecl_rsthead.c ecl_sum_tstep.c ecl_rst_file.c ecl_init_file.c ecl_grid_cache.c smspec_node.c ecl_kw_grdecl.c ecl_file_kw.c ecl_grav.c ecl_grav_calc.c ecl_smspec.c ecl_sum_data.c ecl_util.c ecl_kw.c ecl_sum.c fortio.c ecl_rft_file.c ecl_rft_node.c ecl_grid.c ecl_coarse_cell.c ecl_box.c ecl_io_config.c ecl_file.c ecl_region.c point.c tetrahedron.c ecl_subsidence.c ecl_grav_common.c ${ext_source}) -set( header_files ecl_sum_tstep.h ecl_rst_file.h ecl_init_file.h smspec_node.h ecl_grid_cache.h ecl_kw_grdecl.h ecl_file_kw.h ecl_grav.h ecl_grav_calc.h ecl_endian_flip.h ecl_smspec.h ecl_sum_data.h ecl_util.h ecl_kw.h ecl_sum.h fortio.h ecl_rft_file.h ecl_rft_node.h ecl_box.h ecl_coarse_cell.h ecl_grid.h ecl_io_config.h ecl_file.h ecl_region.h ecl_intehead.h ecl_kw_magic.h ecl_subsidence.h ${ext_header} ecl_grav_common.h) +set( header_files ecl_rsthead.h ecl_sum_tstep.h ecl_rst_file.h ecl_init_file.h smspec_node.h ecl_grid_cache.h ecl_kw_grdecl.h ecl_file_kw.h ecl_grav.h ecl_grav_calc.h ecl_endian_flip.h ecl_smspec.h ecl_sum_data.h ecl_util.h ecl_kw.h ecl_sum.h fortio.h ecl_rft_file.h ecl_rft_node.h ecl_box.h ecl_coarse_cell.h ecl_grid.h ecl_io_config.h ecl_file.h ecl_region.h ecl_kw_magic.h ecl_subsidence.h ${ext_header} ecl_grav_common.h) @@ -28,11 +28,12 @@ endif() target_link_libraries( ecl ert_geometry ert_util ) #----------------------------------------------------------------- -install(TARGETS ecl DESTINATION ${CMAKE_INSTALL_LIBDIR}) -foreach(header ${header_files}) - install(FILES ../include/ert/ecl/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/ecl) -endforeach() - +if (INSTALL_ERT) + install(TARGETS ecl DESTINATION ${CMAKE_INSTALL_LIBDIR}) + foreach(header ${header_files}) + install(FILES ../include/ert/ecl/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/ecl) + endforeach() +endif() diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_file.c b/ThirdParty/Ert/devel/libecl/src/ecl_file.c index a160c809ed..6777de334f 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_file.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_file.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_grid.c b/ThirdParty/Ert/devel/libecl/src/ecl_grid.c index a94afe09a8..56ca5a85c7 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_grid.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_grid.c @@ -2395,8 +2395,109 @@ ecl_grid_type * ecl_grid_alloc(const char * grid_file ) { return ecl_grid; } +static void ecl_grid_file_nactive_dims( fortio_type * data_fortio , int * dims) { + if (data_fortio) { + if (ecl_kw_fseek_kw( INTEHEAD_KW , false , false , data_fortio )) { + ecl_kw_type * intehead_kw = ecl_kw_fread_alloc( data_fortio ); + dims[3] = ecl_kw_iget_int( intehead_kw , INTEHEAD_NACTIVE_INDEX ); + ecl_kw_free( intehead_kw ); + } + } +} +static bool ecl_grid_file_EGRID_dims( fortio_type * grid_fortio , fortio_type * data_fortio , int * dims ) { + + if (ecl_kw_fseek_kw( GRIDHEAD_KW , false , false , grid_fortio)) { + { + ecl_kw_type * gridhead_kw = ecl_kw_fread_alloc( grid_fortio ); + dims[0] = ecl_kw_iget_int( gridhead_kw , GRIDHEAD_NX_INDEX ); + dims[1] = ecl_kw_iget_int( gridhead_kw , GRIDHEAD_NY_INDEX ); + dims[2] = ecl_kw_iget_int( gridhead_kw , GRIDHEAD_NZ_INDEX ); + + ecl_kw_free( gridhead_kw ); + } + ecl_grid_file_nactive_dims( data_fortio , dims ); + return true; + } else + return false; + +} + +static bool ecl_grid_file_GRID_dims( fortio_type * grid_fortio , fortio_type * data_fortio , int * dims ) { + + if (ecl_kw_fseek_kw( DIMENS_KW , false , false , grid_fortio)) { + { + ecl_kw_type * dimens_kw = ecl_kw_fread_alloc( grid_fortio ); + dims[0] = ecl_kw_iget_int( dimens_kw , DIMENS_NX_INDEX ); + dims[1] = ecl_kw_iget_int( dimens_kw , DIMENS_NY_INDEX ); + dims[2] = ecl_kw_iget_int( dimens_kw , DIMENS_NZ_INDEX ); + + ecl_kw_free( dimens_kw ); + } + + ecl_grid_file_nactive_dims( data_fortio , dims ); + return true; + } else + return false; + +} + +/** + Will check the grid dimensions from the input grid file + @grid_filename; the input file must be a GRID/EGRID file. On exit + the dims array will be filled as: + + dims[0] = nx; + dims[1] = ny; + dims[2] = nz; + + Optionally you can in addition supply the name of a restart or INIT + file in the second file argument - if-and-only-if, that filename + points to an existing file the fourth element in the dims array + will be set as: + + dims[3] = nactive; + + The function as a whole will return true if the grid dimensions + (nx,ny,nz) are sucessfully set. If the dimensions are not set the + dims vector is not touched. +*/ + + + +bool ecl_grid_file_dims( const char * grid_filename , const char * init_restart_filename , int * dims) { + bool input_file_OK = false; + bool grid_fmt_file; + ecl_file_enum grid_file_type = ecl_util_get_file_type( grid_filename , &grid_fmt_file , NULL ); + + if ((grid_file_type == ECL_GRID_FILE) || (grid_file_type == ECL_EGRID_FILE)) { + fortio_type * grid_fortio = fortio_open_reader( grid_filename , grid_fmt_file , ECL_ENDIAN_FLIP ); + if (grid_fortio) { + fortio_type * data_fortio = NULL; + bool data_fmt_file; + + if (init_restart_filename) { + ecl_file_enum data_file_type = ecl_util_get_file_type( init_restart_filename , &data_fmt_file , NULL ); + data_fortio = fortio_open_reader( init_restart_filename , data_fmt_file , ECL_ENDIAN_FLIP ); + } + + + if (grid_file_type == ECL_GRID_FILE) + input_file_OK = ecl_grid_file_GRID_dims( grid_fortio , data_fortio , dims ); + else + input_file_OK = ecl_grid_file_EGRID_dims( grid_fortio , data_fortio , dims ); + + if (data_fortio) + fortio_fclose( data_fortio ); + + fortio_fclose( grid_fortio ); + } + } + + return input_file_OK; +} + /** @@ -3005,8 +3106,10 @@ int ecl_grid_get_active_fracture_index3(const ecl_grid_type * ecl_grid , int i , */ int ecl_grid_get_active_fracture_index1(const ecl_grid_type * ecl_grid , int global_index) { - if (!ecl_grid->fracture_index_map) return -1; - return ecl_grid->fracture_index_map[global_index]; + if (ecl_grid->fracture_index_map == NULL) + return -1; + else + return ecl_grid->fracture_index_map[global_index]; } @@ -3720,10 +3823,10 @@ int ecl_grid_get_region_cells(const ecl_grid_type * ecl_grid , const ecl_kw_type -void ecl_grid_grdecl_fprintf_kw( const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , FILE * stream , double double_default) { +void ecl_grid_grdecl_fprintf_kw( const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream , double double_default) { int src_size = ecl_kw_get_size( ecl_kw ); if (src_size == ecl_grid->size) - ecl_kw_fprintf_grdecl( ecl_kw , stream ); + ecl_kw_fprintf_grdecl__( ecl_kw , special_header , stream ); else if (src_size == ecl_grid->total_active) { void * default_ptr = NULL; float float_default; @@ -3755,7 +3858,7 @@ void ecl_grid_grdecl_fprintf_kw( const ecl_grid_type * ecl_grid , const ecl_kw_t { ecl_kw_type * tmp_kw = ecl_kw_alloc_scatter_copy( ecl_kw , ecl_grid->size , ecl_grid->inv_index_map , default_ptr ); - ecl_kw_fprintf_grdecl( tmp_kw , stream ); + ecl_kw_fprintf_grdecl__( tmp_kw , special_header , stream ); ecl_kw_free( tmp_kw ); } } else diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_intehead.c b/ThirdParty/Ert/devel/libecl/src/ecl_intehead.c deleted file mode 100644 index cbc4777a9a..0000000000 --- a/ThirdParty/Ert/devel/libecl/src/ecl_intehead.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_intehead.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT 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. - - ERT 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 - -#include - -#include -#include -#include - -static time_t intehead_date( int day , int month , int year) { - return util_make_date( day , month, year ); -} - - -time_t ecl_intehead_date( const ecl_kw_type * intehead_kw ) { - return intehead_date( ecl_kw_iget_int( intehead_kw , INTEHEAD_DAY_INDEX) , - ecl_kw_iget_int( intehead_kw , INTEHEAD_MONTH_INDEX) , - ecl_kw_iget_int( intehead_kw , INTEHEAD_YEAR_INDEX) ); -} - - - -ecl_intehead_type * ecl_intehead_alloc( const ecl_kw_type * intehead_kw ) { - ecl_intehead_type * intehead = util_malloc( sizeof * intehead ); - const int * data = (const int *) ecl_kw_get_void_ptr( intehead_kw ); - - intehead->day = data[INTEHEAD_DAY_INDEX]; - intehead->month = data[INTEHEAD_MONTH_INDEX]; - intehead->year = data[INTEHEAD_YEAR_INDEX]; - intehead->version = data[INTEHEAD_IPROG_INDEX]; - intehead->phase_sum = data[INTEHEAD_PHASE_INDEX]; - - intehead->nx = data[INTEHEAD_NX_INDEX]; - intehead->ny = data[INTEHEAD_NY_INDEX]; - intehead->nz = data[INTEHEAD_NZ_INDEX]; - intehead->nactive = data[INTEHEAD_NACTIVE_INDEX]; - - intehead->nwells = data[INTEHEAD_NWELLS_INDEX]; - intehead->niwelz = data[INTEHEAD_NIWELZ_INDEX]; - intehead->nzwelz = data[INTEHEAD_NZWELZ_INDEX]; - - intehead->niconz = data[INTEHEAD_NICONZ_INDEX]; - intehead->ncwmax = data[INTEHEAD_NCWMAX_INDEX]; - - intehead->nisegz = data[INTEHEAD_NISEGZ_INDEX]; - intehead->nsegmx = data[INTEHEAD_NSEGMX_INDEX]; - intehead->nswlmx = data[INTEHEAD_NSWLMX_INDEX]; - - // The only derived quantity - intehead->sim_time = intehead_date( intehead->day , intehead->month , intehead->year ); - return intehead; -} - - -void ecl_intehead_fprintf( const ecl_intehead_type * header , FILE * stream) { - fprintf(stream , "nx %d \n",header->nx); - fprintf(stream , "nwells %d \n",header->nwells); - fprintf(stream , "niwelz %d \n\n",header->niwelz); -} - -void ecl_intehead_free( ecl_intehead_type * intehead ) { - free( intehead ); -} diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_kw.c b/ThirdParty/Ert/devel/libecl/src/ecl_kw.c index 49b5cdc1c6..85432ec2c3 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_kw.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_kw.c @@ -336,15 +336,25 @@ bool ecl_kw_ichar_eq(const ecl_kw_type *ecl_kw , int i , const char *value) { } +static bool ecl_kw_size_and_type_equal( const ecl_kw_type *ecl_kw1 , const ecl_kw_type * ecl_kw2 ) { + bool equal = true; + + if (ecl_kw1->size != ecl_kw2->size) + equal = false; + else if (ecl_kw1->ecl_type != ecl_kw2->ecl_type) + equal = false; + + return equal; +} + + bool ecl_kw_header_eq(const ecl_kw_type *ecl_kw1 , const ecl_kw_type * ecl_kw2) { bool equal = true; if (strcmp(ecl_kw1->header8 , ecl_kw2->header8) != 0) equal = false; - else if (ecl_kw1->size != ecl_kw2->size) - equal = false; - else if (ecl_kw1->ecl_type != ecl_kw2->ecl_type) - equal = false; + else + equal = ecl_kw_size_and_type_equal( ecl_kw1 , ecl_kw2 ); return equal; } @@ -368,6 +378,16 @@ bool ecl_kw_data_equal( const ecl_kw_type * ecl_kw , const void * data) { } +bool ecl_kw_content_equal( const ecl_kw_type * ecl_kw1 , const ecl_kw_type * ecl_kw2) { + if (ecl_kw_size_and_type_equal( ecl_kw1 , ecl_kw2)) + return ecl_kw_data_equal__( ecl_kw1 , ecl_kw2->data , ecl_kw1->size); + else + return false; +} + + + + /** This function compares two ecl_kw instances, and returns true if they are equal. diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_kw_grdecl.c b/ThirdParty/Ert/devel/libecl/src/ecl_kw_grdecl.c index 9d76f8ffc7..1fb0f3bb5a 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_kw_grdecl.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_kw_grdecl.c @@ -633,8 +633,19 @@ ecl_kw_type * ecl_kw_fscanf_alloc_current_grdecl( FILE * stream , ecl_type_enum /*****************************************************************/ -void ecl_kw_fprintf_grdecl(const ecl_kw_type * ecl_kw , FILE * stream) { - fprintf(stream,"%s\n" , ecl_kw_get_header(ecl_kw)); + +/* + This method allows to write with a different header, + i.e. PORO_XXXX. This header is even allowed to break the 8 character + length limit; i.e. loading it back naively will fail. +*/ + +void ecl_kw_fprintf_grdecl__(const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream) { + if (special_header) + fprintf(stream,"%s\n" , special_header); + else + fprintf(stream,"%s\n" , ecl_kw_get_header(ecl_kw)); + { fortio_type * fortio = fortio_alloc_FILE_wrapper(NULL , false , true , stream); /* Endian flip should *NOT* be used */ ecl_kw_fwrite_data(ecl_kw , fortio); @@ -644,3 +655,7 @@ void ecl_kw_fprintf_grdecl(const ecl_kw_type * ecl_kw , FILE * stream) { } +void ecl_kw_fprintf_grdecl(const ecl_kw_type * ecl_kw , FILE * stream) { + ecl_kw_fprintf_grdecl__(ecl_kw , NULL , stream ); +} + diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_rst_file.c b/ThirdParty/Ert/devel/libecl/src/ecl_rst_file.c index 85bff601ef..6549e85922 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_rst_file.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_rst_file.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_rstfile.c b/ThirdParty/Ert/devel/libecl/src/ecl_rstfile.c index d64d6c3efc..a87989410d 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_rstfile.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_rstfile.c @@ -158,7 +158,7 @@ static time_t file_map_iget_restart_sim_date(const file_map_type * file_map , in if (seqnum_map != NULL) { ecl_kw_type * intehead_kw = file_map_iget_named_kw( seqnum_map , INTEHEAD_KW , 0); - sim_time = ecl_intehead_date( intehead_kw ); + sim_time = ecl_rsthead_date( intehead_kw ); file_map_free( seqnum_map ); } @@ -175,7 +175,7 @@ static int file_map_find_sim_time(const file_map_type * file_map , time_t sim_ti int index = 0; while (index < int_vector_size( intehead_index_list )) { const ecl_kw_type * intehead_kw = file_map_iget_kw( file_map , int_vector_iget( intehead_index_list , index )); - if (ecl_intehead_date( intehead_kw ) == sim_time) { + if (ecl_rsthead_date( intehead_kw ) == sim_time) { seqnum_index = index; break; } diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_rsthead.c b/ThirdParty/Ert/devel/libecl/src/ecl_rsthead.c new file mode 100644 index 0000000000..05995747cc --- /dev/null +++ b/ThirdParty/Ert/devel/libecl/src/ecl_rsthead.c @@ -0,0 +1,155 @@ +/* + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_rsthead.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 + +#include + +#include +#include +#include +#include + + +static time_t rsthead_date( int day , int month , int year) { + return util_make_date( day , month, year ); +} + + +time_t ecl_rsthead_date( const ecl_kw_type * intehead_kw ) { + return rsthead_date( ecl_kw_iget_int( intehead_kw , INTEHEAD_DAY_INDEX) , + ecl_kw_iget_int( intehead_kw , INTEHEAD_MONTH_INDEX) , + ecl_kw_iget_int( intehead_kw , INTEHEAD_YEAR_INDEX) ); +} + + + + +ecl_rsthead_type * ecl_rsthead_ialloc( const ecl_file_type * rst_file , int occurence) { + if (ecl_file_get_num_named_kw( rst_file , INTEHEAD_KW) > occurence) { + const ecl_kw_type * intehead_kw = ecl_file_iget_named_kw( rst_file , INTEHEAD_KW , occurence); + const ecl_kw_type * logihead_kw = ecl_file_iget_named_kw( rst_file , LOGIHEAD_KW , occurence); + const ecl_kw_type * doubhead_kw = ecl_file_iget_named_kw( rst_file , DOUBHEAD_KW , occurence); + + ecl_rsthead_type * rsthead = util_malloc( sizeof * rsthead ); + + { + const int * data = (const int *) ecl_kw_get_void_ptr( intehead_kw ); + + rsthead->day = data[INTEHEAD_DAY_INDEX]; + rsthead->month = data[INTEHEAD_MONTH_INDEX]; + rsthead->year = data[INTEHEAD_YEAR_INDEX]; + rsthead->version = data[INTEHEAD_IPROG_INDEX]; + rsthead->phase_sum = data[INTEHEAD_PHASE_INDEX]; + + rsthead->nx = data[INTEHEAD_NX_INDEX]; + rsthead->ny = data[INTEHEAD_NY_INDEX]; + rsthead->nz = data[INTEHEAD_NZ_INDEX]; + rsthead->nactive = data[INTEHEAD_NACTIVE_INDEX]; + + rsthead->nwells = data[INTEHEAD_NWELLS_INDEX]; + rsthead->niwelz = data[INTEHEAD_NIWELZ_INDEX]; + rsthead->nzwelz = data[INTEHEAD_NZWELZ_INDEX]; + + rsthead->niconz = data[INTEHEAD_NICONZ_INDEX]; + rsthead->ncwmax = data[INTEHEAD_NCWMAX_INDEX]; + + rsthead->nisegz = data[INTEHEAD_NISEGZ_INDEX]; + rsthead->nsegmx = data[INTEHEAD_NSEGMX_INDEX]; + rsthead->nswlmx = data[INTEHEAD_NSWLMX_INDEX]; + + // The only derived quantity + rsthead->sim_time = rsthead_date( rsthead->day , rsthead->month , rsthead->year ); + } + rsthead->dualp = ecl_kw_iget_bool( logihead_kw , LOGIHEAD_DUALP_INDEX); + rsthead->sim_days = ecl_kw_iget_double( doubhead_kw , DOUBHEAD_DAYS_INDEX ); + + return rsthead; + } else + return NULL; +} + + +ecl_rsthead_type * ecl_rsthead_alloc( const ecl_file_type * rst_file) { + return ecl_rsthead_ialloc( rst_file , 0 ); +} + + +void ecl_rsthead_fprintf( const ecl_rsthead_type * header , FILE * stream) { + fprintf(stream , "nx %d \n",header->nx); + fprintf(stream , "nwells %d \n",header->nwells); + fprintf(stream , "niwelz %d \n\n",header->niwelz); +} + + +bool ecl_rsthead_equal( const ecl_rsthead_type * header1 , const ecl_rsthead_type * header2) { + bool equal = true; + equal = equal && (header1->day == header2->day); + equal = equal && (header1->year == header2->year); + equal = equal && (header1->month == header2->month); + equal = equal && (header1->sim_time == header2->sim_time); + equal = equal && (header1->version == header2->version); + equal = equal && (header1->phase_sum == header2->phase_sum); + equal = equal && (header1->nx == header2->nx); + equal = equal && (header1->ny == header2->ny); + equal = equal && (header1->nz == header2->nz); + equal = equal && (header1->nactive == header2->nactive); + equal = equal && (header1->nwells == header2->nwells); + equal = equal && (header1->niwelz == header2->niwelz); + equal = equal && (header1->nzwelz == header2->nzwelz); + equal = equal && (header1->niconz == header2->niconz); + equal = equal && (header1->ncwmax == header2->ncwmax); + equal = equal && (header1->nisegz == header2->nisegz); + equal = equal && (header1->nsegmx == header2->nsegmx); + equal = equal && (header1->nswlmx == header2->nswlmx); + equal = equal && (header1->nlbrmx == header2->nlbrmx); + equal = equal && (header1->nilbrz == header2->nilbrz); + equal = equal && (header1->dualp == header2->dualp); + equal = equal && util_double_approx_equal(header1->sim_days , header2->sim_days ); + + return equal; +} + +void ecl_rsthead_fprintf_struct( const ecl_rsthead_type * header , FILE * stream) { + fprintf(stream , "{.day = %d,\n",header->day); + fprintf(stream , ".year = %d,\n",header->year); + fprintf(stream , ".month = %d,\n",header->month); + fprintf(stream , ".sim_time = %ld,\n",header->sim_time); + fprintf(stream , ".version = %d,\n",header->version); + fprintf(stream , ".phase_sum = %d,\n",header->phase_sum); + fprintf(stream , ".nx = %d,\n",header->nx); + fprintf(stream , ".ny = %d,\n",header->ny); + fprintf(stream , ".nz = %d,\n",header->nz); + fprintf(stream , ".nactive = %d,\n",header->nactive); + fprintf(stream , ".nwells = %d,\n",header->nwells); + fprintf(stream , ".niwelz = %d,\n",header->niwelz); + fprintf(stream , ".nzwelz = %d,\n",header->nzwelz); + fprintf(stream , ".niconz = %d,\n",header->niconz); + fprintf(stream , ".ncwmax = %d,\n",header->ncwmax); + fprintf(stream , ".nisegz = %d,\n",header->nisegz); + fprintf(stream , ".nsegmx = %d,\n",header->nsegmx); + fprintf(stream , ".nswlmx = %d,\n",header->nswlmx); + fprintf(stream , ".nlbrmx = %d,\n",header->nlbrmx); + fprintf(stream , ".nilbrz = %d,\n",header->nilbrz); + fprintf(stream , ".dualp = %d,\n",header->dualp); + fprintf(stream , ".sim_days = %g};\n",header->sim_days); +} + + +void ecl_rsthead_free( ecl_rsthead_type * rsthead ) { + free( rsthead ); +} diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_sum.c b/ThirdParty/Ert/devel/libecl/src/ecl_sum.c index 21b5f02ddc..f07e1de355 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_sum.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_sum.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -402,6 +403,9 @@ double ecl_sum_get_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days return ecl_sum_data_get_from_sim_days( ecl_sum->data , sim_days , node ); } +double ecl_sum_time2days( const ecl_sum_type * ecl_sum , time_t sim_time) { + return ecl_sum_data_time2days( ecl_sum->data , sim_time ); +} @@ -810,6 +814,10 @@ time_t ecl_sum_iget_sim_time( const ecl_sum_type * ecl_sum , int index ) { return ecl_sum_data_iget_sim_time( ecl_sum->data , index ); } +const time_interval_type * ecl_sum_get_sim_time( const ecl_sum_type * ecl_sum) { + return ecl_sum_data_get_sim_time( ecl_sum->data ); +} + time_t ecl_sum_get_data_start( const ecl_sum_type * ecl_sum ) { return ecl_sum_data_get_data_start( ecl_sum->data ); } diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_sum_data.c b/ThirdParty/Ert/devel/libecl/src/ecl_sum_data.c index 101a4990aa..ab087a0a27 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_sum_data.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_sum_data.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -212,10 +213,6 @@ struct ecl_sum_data_struct { int first_ministep; int last_ministep; double days_start; - time_t data_start_time; /* This is the first time_t we have data for; will typically - agree with sim_start, - but in the case of restarts it will be after sim_start. */ - time_t sim_end; double sim_length; int_vector_type * report_first_index ; /* Indexed by report_step - giving first internal_index in report_step. */ int_vector_type * report_last_index; /* Indexed by report_step - giving last internal_index in report_step. */ @@ -224,6 +221,9 @@ struct ecl_sum_data_struct { time_t __min_time; /* An internal member used during the load of restarted cases; see doc in ecl_sum_data_append_tstep. */ bool index_valid; + time_interval_type * sim_time; /* The time interval sim_time goes from the first time value where we have + data to the end of the simulation. In the case of restarts the start + value might disagree with the simulation start reported by the smspec file. */ }; @@ -236,6 +236,7 @@ struct ecl_sum_data_struct { vector_free( data->data ); int_vector_free( data->report_first_index ); int_vector_free( data->report_last_index ); + time_interval_free( data->sim_time ); free(data); } @@ -253,12 +254,11 @@ static void ecl_sum_data_clear_index( ecl_sum_data_type * data ) { data->first_report_step = 1024 * 1024; data->last_report_step = -1024 * 1024; data->days_start = 0; - data->data_start_time = -1; - data->sim_end = -1; data->sim_length = -1; data->first_ministep = -1; data->last_ministep = -1; data->index_valid = false; + time_interval_reopen( data->sim_time ); } @@ -270,7 +270,7 @@ ecl_sum_data_type * ecl_sum_data_alloc(ecl_smspec_type * smspec) { data->report_first_index = int_vector_alloc( 0 , -1 ); /* This -1 value is hard-wired around in the place - not good. */ data->report_last_index = int_vector_alloc( 0 , -1 ); - + data->sim_time = time_interval_alloc_open(); ecl_sum_data_clear_index( data ); return data; @@ -437,10 +437,11 @@ void ecl_sum_data_fwrite( const ecl_sum_data_type * data , const char * ecl_case +const time_interval_type * ecl_sum_data_get_sim_time( const ecl_sum_data_type * data) { return data->sim_time; } -time_t ecl_sum_data_get_sim_end (const ecl_sum_data_type * data ) { return data->sim_end; } +time_t ecl_sum_data_get_sim_end (const ecl_sum_data_type * data ) { return time_interval_get_end( data->sim_time ); } -time_t ecl_sum_data_get_data_start ( const ecl_sum_data_type * data ) { return data->data_start_time; } +time_t ecl_sum_data_get_data_start ( const ecl_sum_data_type * data ) { return time_interval_get_start( data->sim_time ); } double ecl_sum_data_get_first_day( const ecl_sum_data_type * data) { return data->days_start; } @@ -469,10 +470,10 @@ double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data ) { */ bool ecl_sum_data_check_sim_time( const ecl_sum_data_type * data , time_t sim_time) { - if ((sim_time < data->data_start_time) || (sim_time > data->sim_end)) - return false; - else + if (time_interval_contains( data->sim_time , sim_time ) || (sim_time == time_interval_get_end( data->sim_time))) return true; + else + return false; } @@ -524,14 +525,15 @@ bool ecl_sum_data_check_sim_days( const ecl_sum_data_type * data , double sim_da static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data , time_t sim_time) { - time_t data_start_time = data->data_start_time; + time_t data_start_time = time_interval_get_start( data->sim_time ); + time_t sim_end = time_interval_get_end( data->sim_time ); - if ((sim_time < data_start_time) || (sim_time > data->sim_end)) { + if (!ecl_sum_data_check_sim_time( data , sim_time )) { fprintf(stderr , "Simulation start: "); util_fprintf_date( ecl_smspec_get_start_time( data->smspec ) , stderr ); fprintf(stderr , "Data start......: "); util_fprintf_date( data_start_time , stderr ); - fprintf(stderr , "Simulation end .: "); util_fprintf_date( data->sim_end , stderr ); + fprintf(stderr , "Simulation end .: "); util_fprintf_date( sim_end , stderr ); fprintf(stderr , "Requested date .: "); util_fprintf_date( sim_time , stderr ); - util_abort("%s: invalid time_t instance:%d interval: [%d,%d]\n",__func__, sim_time , data_start_time , data->sim_end); + util_abort("%s: invalid time_t instance:%d interval: [%d,%d]\n",__func__, sim_time , data_start_time , sim_end); } /* @@ -705,9 +707,9 @@ static void ecl_sum_data_append_tstep__( ecl_sum_data_type * data , int ministep static void ecl_sum_data_update_end_info( ecl_sum_data_type * sum_data ) { const ecl_sum_tstep_type * last_ministep = vector_get_last_const( sum_data->data ); - sum_data->last_ministep = ecl_sum_tstep_get_ministep( last_ministep ); + sum_data->last_ministep = ecl_sum_tstep_get_ministep( last_ministep ); sum_data->sim_length = ecl_sum_tstep_get_sim_days( last_ministep ); - sum_data->sim_end = ecl_sum_tstep_get_sim_time( last_ministep ); + time_interval_update_end( sum_data->sim_time , ecl_sum_tstep_get_sim_time( last_ministep )); } static int cmp_ministep( const void * arg1 , const void * arg2) { @@ -749,7 +751,7 @@ static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) { will be a difference. */ sum_data->days_start = ecl_sum_tstep_get_sim_days( first_ministep ); - sum_data->data_start_time = ecl_sum_tstep_get_sim_time( first_ministep ); + time_interval_update_start( sum_data->sim_time , ecl_sum_tstep_get_sim_time( first_ministep )); } ecl_sum_data_update_end_info( sum_data ); @@ -1199,7 +1201,8 @@ int ecl_sum_data_get_report_step_from_days(const ecl_sum_data_type * data , doub int ecl_sum_data_get_report_step_from_time(const ecl_sum_data_type * data , time_t sim_time) { - if ((sim_time < data->data_start_time) || (sim_time > data->sim_end)) + + if (!ecl_sum_data_check_sim_time(data , sim_time)) return -1; { @@ -1232,6 +1235,11 @@ int ecl_sum_data_get_report_step_from_time(const ecl_sum_data_type * data , time } +double ecl_sum_data_time2days( const ecl_sum_data_type * data , time_t sim_time) { + time_t start_time = ecl_smspec_get_start_time( data->smspec ); + return util_difftime_days( start_time , sim_time ); +} + double ecl_sum_data_get_from_sim_days( const ecl_sum_data_type * data , double sim_days , const smspec_node_type * smspec_node) { time_t sim_time = ecl_smspec_get_start_time( data->smspec ); util_inplace_forward_days( &sim_time , sim_days ); diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_util.c b/ThirdParty/Ert/devel/libecl/src/ecl_util.c index 5be479866b..b41e6a4d4f 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_util.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_util.c @@ -1322,6 +1322,70 @@ bool ecl_util_valid_basename( const char * basename ) { } +/* + Will append time_t values corresponding to the first day in every + month in the open interval (start_date , end_date). Iff start_date + corresponds to the first date in a month the list will start with + start_date, otherwise the list will start with the first day in the + month following after start_date. + + If end_date corresponds to the first day of the month the list will + end with end_date, otherwise it will ende with the first day in the + month prior to end_date: + + (1,1,2000) , (10,3,2000) => {(1,1,2000) , (1,2,2000) , (1,3,2000) } + (10,1,2000) , (1,4,2000) => {(1,2,2000) , (1,3,2000) , (1,4,2000) } + + All time_t values added to the date list will be pure dates, + i.e. the time part will be 00:00:00; that also applies to start_date + and end_date where possible time parts will be normalized away prior + to insertion. +*/ + + +void ecl_util_append_month_range( time_t_vector_type * date_list , time_t start_date , time_t end_date , bool force_append_end) { + start_date = util_make_pure_date( start_date ); + end_date = util_make_pure_date( end_date ); + + if (util_is_first_day_in_month( start_date)) + time_t_vector_append( date_list , start_date ); + + { + time_t current_date = start_date; + while (true) { + int month,year; + util_set_date_values( current_date , NULL , &month , &year); + if (month == 12) { + month = 1; + year += 1; + } else + month += 1; + + current_date = util_make_date( 1 , month , year ); + if (current_date < end_date) + time_t_vector_append( date_list , current_date ); + else { + if (current_date == end_date) + time_t_vector_append( date_list , current_date ); + else if (force_append_end) + time_t_vector_append( date_list , end_date ); + break; + } + } + } +} + + + +void ecl_util_init_month_range( time_t_vector_type * date_list , time_t start_date , time_t end_date) { + time_t_vector_reset( date_list ); + if (!util_is_first_day_in_month( start_date )) + time_t_vector_append( date_list , util_make_pure_date(start_date)); + + ecl_util_append_month_range( date_list , start_date , end_date , true ); +} + + /*****************************************************************/ /* Small functions to support enum introspection. */ diff --git a/ThirdParty/Ert/devel/libecl/src/smspec_node.c b/ThirdParty/Ert/devel/libecl/src/smspec_node.c index 36250fee60..20b0f70ce5 100644 --- a/ThirdParty/Ert/devel/libecl/src/smspec_node.c +++ b/ThirdParty/Ert/devel/libecl/src/smspec_node.c @@ -65,6 +65,7 @@ struct smspec_node_struct { bool rate_variable; /* Is this a rate variable (i.e. WOPR) or a state variable (i.e. BPR). Relevant when doing time interpolation. */ bool total_variable; /* Is this a total variable like WOPT? */ bool need_nums; /* Do we use the NUMS vector - relevant for storing. */ + bool historical; /* Does the name end with 'H'? */ int params_index; /* The index of this variable (applies to all the vectors - in particular the PARAMS vectors of the summary files *.Snnnn / *.UNSMRY ). */ float default_value; /* Default value for this variable. */ }; @@ -234,8 +235,12 @@ static void smspec_node_set_invalid_flags( smspec_node_type * smspec_node) { smspec_node->rate_variable = false; smspec_node->total_variable = false; smspec_node->need_nums = false; + smspec_node->historical = false; } +static char LAST_CHAR(const char * s) { + return s[ strlen(s) - 1]; +} static void smspec_node_set_flags( smspec_node_type * smspec_node) { /* @@ -249,7 +254,7 @@ static void smspec_node_set_flags( smspec_node_type * smspec_node) { int ivar; for (ivar = 0; ivar < num_rate_vars; ivar++) { const char * var_substring = &smspec_node->keyword[1]; - if (util_string_equal( rate_vars[ivar] , var_substring)) { + if (strncmp( rate_vars[ivar] , var_substring , strlen( rate_vars[ivar] )) == 0) { is_rate = true; break; } @@ -257,6 +262,11 @@ static void smspec_node_set_flags( smspec_node_type * smspec_node) { smspec_node->rate_variable = is_rate; } + { + if (LAST_CHAR(smspec_node->keyword) == 'H') + smspec_node->historical = true; + } + /* This code checks in a predefined list whether a certain WGNAMES variable represents a total accumulated quantity. Only the last three @@ -265,7 +275,7 @@ static void smspec_node_set_flags( smspec_node_type * smspec_node) { The list below is all the keyowrds with 'Total' in the information from the tables 2.7 - 2.11 in the ECLIPSE fileformat documentation. Have - skipped some of the most exotic keywords (AND ALL THE HISTORICAL). + skipped some of the most exotic keywords. */ { bool is_total = false; @@ -278,7 +288,12 @@ static void smspec_node_set_flags( smspec_node_type * smspec_node) { int ivar; for (ivar = 0; ivar < num_total_vars; ivar++) { const char * var_substring = &smspec_node->keyword[1]; - if (util_string_equal( total_vars[ivar] , var_substring)) { + /* + We want to mark both FOPT and FOPTH as historical variables; + we use strncmp() to make certain that the trailing 'H' is + not included in the comparison. + */ + if (strncmp( total_vars[ivar] , var_substring , strlen( total_vars[ivar] )) == 0) { is_total = true; break; } @@ -761,6 +776,10 @@ bool smspec_node_is_total( const smspec_node_type * smspec_node ){ return smspec_node->total_variable; } +bool smspec_node_is_historical( const smspec_node_type * smspec_node ){ + return smspec_node->historical; +} + const char * smspec_node_get_unit( const smspec_node_type * smspec_node) { return smspec_node->unit; diff --git a/ThirdParty/Ert/devel/libecl/tests/CMakeLists.txt b/ThirdParty/Ert/devel/libecl/tests/CMakeLists.txt index 8b87e485be..b4beb6f651 100644 --- a/ThirdParty/Ert/devel/libecl/tests/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libecl/tests/CMakeLists.txt @@ -1,18 +1,55 @@ add_executable( ecl_coarse_test ecl_coarse_test.c ) target_link_libraries( ecl_coarse_test ecl ) +add_test( ecl_coarse_test ${EXECUTABLE_OUTPUT_PATH}/ecl_coarse_test ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/LGCcase/LGC_TESTCASE2 ) + add_executable( ecl_restart_test ecl_restart_test.c ) target_link_libraries( ecl_restart_test ecl ) +add_test( ecl_restart_test ${EXECUTABLE_OUTPUT_PATH}/ecl_restart_test ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST ) + + add_executable( ecl_lgr_test ecl_lgr_test.c ) target_link_libraries( ecl_lgr_test ecl ) - -add_test( ecl_coarse_test ${EXECUTABLE_OUTPUT_PATH}/ecl_coarse_test ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/LGCcase/LGC_TESTCASE2 ) -add_test( ecl_restart_test ${EXECUTABLE_OUTPUT_PATH}/ecl_restart_test ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST ) add_test( ecl_lgr_test1 ${EXECUTABLE_OUTPUT_PATH}/ecl_lgr_test ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/10kcase/TEST10K_FLT_LGR_NNC.EGRID) add_test( ecl_lgr_test2 ${EXECUTABLE_OUTPUT_PATH}/ecl_lgr_test ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/10kcase/TEST10K_FLT_LGR_NNC.GRID) + +add_executable( ecl_grid_simple ecl_grid_simple.c ) +target_link_libraries( ecl_grid_simple ecl ) +add_test( ecl_grid_simple ${EXECUTABLE_OUTPUT_PATH}/ecl_grid_simple ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID ) + + +add_executable( ecl_kw_grdecl ecl_kw_grdecl.c ) +target_link_libraries( ecl_kw_grdecl ecl ) +add_test( ecl_kw_grdecl ${EXECUTABLE_OUTPUT_PATH}/ecl_kw_grdecl ) + +add_executable( ecl_kw_equal ecl_kw_equal.c ) +target_link_libraries( ecl_kw_equal ecl ) +add_test( ecl_kw_equal ${EXECUTABLE_OUTPUT_PATH}/ecl_kw_equal ) + + +add_executable( ecl_dualp ecl_dualp.c ) +target_link_libraries( ecl_dualp ecl ) +add_test( ecl_dualp ${EXECUTABLE_OUTPUT_PATH}/ecl_dualp ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/LGCcase/LGC_TESTCASE2 ) + +add_executable( ecl_util_month_range ecl_util_month_range.c ) +target_link_libraries( ecl_util_month_range ecl ) +add_test( ecl_util_month_range ${EXECUTABLE_OUTPUT_PATH}/ecl_util_month_range ) + +add_executable( ecl_sum_test ecl_sum_test.c ) +target_link_libraries( ecl_sum_test ecl ) +add_test( ecl_sum_test ${EXECUTABLE_OUTPUT_PATH}/ecl_sum_test ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE ) + +add_executable( ecl_rsthead ecl_rsthead.c ) +target_link_libraries( ecl_rsthead ecl ) +add_test( ecl_rsthead ${EXECUTABLE_OUTPUT_PATH}/ecl_rsthead ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST + ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/DualPoro/DUALPORO.X0005 ) + set_property( TEST ecl_coarse_test PROPERTY LABELS Statoil ) set_property( TEST ecl_restart_test PROPERTY LABELS Statoil ) set_property( TEST ecl_lgr_test1 PROPERTY LABELS Statoil ) set_property( TEST ecl_lgr_test2 PROPERTY LABELS Statoil ) +set_property( TEST ecl_grid_simple PROPERTY LABELS Statoil ) +set_property( TEST ecl_dualp PROPERTY LABELS Statoil ) +set_property( TEST ecl_sum_test PROPERTY LABELS Statoil ) diff --git a/ThirdParty/Ert/devel/libecl/tests/ecl_dualp.c b/ThirdParty/Ert/devel/libecl/tests/ecl_dualp.c new file mode 100644 index 0000000000..5b5da737f3 --- /dev/null +++ b/ThirdParty/Ert/devel/libecl/tests/ecl_dualp.c @@ -0,0 +1,76 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_dualp.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include + +#include +#include +#include +#include + +int main(int argc , char ** argv) { + const char * case_path = argv[1]; + char * grid_file = ecl_util_alloc_filename( NULL , case_path , ECL_EGRID_FILE , false , 0 ); + char * init_file = ecl_util_alloc_filename( NULL , case_path , ECL_INIT_FILE , false , 0 ); + char * rst_file = ecl_util_alloc_filename( NULL , case_path , ECL_RESTART_FILE , false , 0 ); + + ecl_grid_type * ecl_grid = ecl_grid_alloc( grid_file ); + ecl_file_type * RST_file = ecl_file_open( rst_file ); + ecl_file_type * INIT_file = ecl_file_open( init_file ); + ecl_file_type * GRID_file = ecl_file_open( grid_file ); + + { + ecl_kw_type * actnum = ecl_file_iget_named_kw( GRID_file , "ACTNUM" , 0 ); + ecl_kw_type * swat = ecl_file_iget_named_kw( RST_file , "SWAT" , 0 ); + ecl_kw_type * permx = ecl_file_iget_named_kw( INIT_file , "PERMX" , 0 ); + int fracture_size = ecl_grid_get_nactive_fracture( ecl_grid ); + int matrix_size = ecl_grid_get_nactive( ecl_grid ); + + test_assert_int_equal( fracture_size + matrix_size , ecl_kw_get_size( swat )); + test_assert_int_equal( fracture_size + matrix_size , ecl_kw_get_size( permx )); + + { + int gi; + int matrix_index = 0; + int fracture_index = 0; + + for (gi = 0; gi < ecl_grid_get_global_size( ecl_grid ); gi++) { + if (ecl_kw_iget_int( actnum , gi ) & ACTIVE_MATRIX) { + test_assert_int_equal( ecl_grid_get_active_index1( ecl_grid , gi ) , matrix_index); + test_assert_int_equal( ecl_grid_get_global_index1A( ecl_grid , matrix_index ) , gi); + matrix_index++; + } + + if (ecl_kw_iget_int( actnum , gi ) & ACTIVE_FRACTURE) { + test_assert_int_equal( ecl_grid_get_active_fracture_index1( ecl_grid , gi ) , fracture_index); + test_assert_int_equal( ecl_grid_get_global_index1F( ecl_grid , fracture_index ) , gi); + fracture_index++; + } + } + } + } + + + ecl_file_close( RST_file ); + ecl_file_close( INIT_file ); + ecl_grid_free( ecl_grid ); + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libecl/tests/ecl_grid_simple.c b/ThirdParty/Ert/devel/libecl/tests/ecl_grid_simple.c new file mode 100644 index 0000000000..37bcbbf180 --- /dev/null +++ b/ThirdParty/Ert/devel/libecl/tests/ecl_grid_simple.c @@ -0,0 +1,36 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_grid_simple.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include + +#include + + + +int main(int argc , char ** argv) { + const char * grid_file = argv[1]; + ecl_grid_type * ecl_grid = ecl_grid_alloc( grid_file ); + + test_assert_int_equal( ecl_grid_get_nactive_fracture( ecl_grid ) , 0 ); + test_assert_int_equal( ecl_grid_get_active_fracture_index1( ecl_grid , 10 ) , -1 ); + + ecl_grid_free( ecl_grid ); + exit(0); +} diff --git a/ThirdParty/Ert/devel/libecl/tests/ecl_kw_equal.c b/ThirdParty/Ert/devel/libecl/tests/ecl_kw_equal.c new file mode 100644 index 0000000000..4ec147e84e --- /dev/null +++ b/ThirdParty/Ert/devel/libecl/tests/ecl_kw_equal.c @@ -0,0 +1,65 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_kw_equal.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include + + +int main(int argc , char ** argv) { + ecl_kw_type * ecl_kw1 = ecl_kw_alloc( "KW" , 10 , ECL_INT_TYPE ); + int data[10]; + int i; + for (i=0; i < 10; i++) { + ecl_kw_iset_int(ecl_kw1 , i , i ); + data[i] = i; + } + + { + ecl_kw_type * ecl_kw2 = ecl_kw_alloc_copy( ecl_kw1 ); + + test_assert_true( ecl_kw_equal( ecl_kw1 , ecl_kw2 )); + + ecl_kw_iset_int( ecl_kw2 , 1 , 77 ); + test_assert_false( ecl_kw_equal( ecl_kw1 , ecl_kw2 )); + ecl_kw_iset_int( ecl_kw2 , 1 , 1 ); + test_assert_true( ecl_kw_equal( ecl_kw1 , ecl_kw2 )); + + ecl_kw_set_header_name( ecl_kw2 , "TEST" ); + test_assert_false( ecl_kw_equal( ecl_kw1 , ecl_kw2 )); + test_assert_true( ecl_kw_content_equal( ecl_kw1 , ecl_kw2 )); + ecl_kw_free( ecl_kw2 ); + } + + { + ecl_kw_type * ecl_ikw = ecl_kw_alloc_new_shared( "KW" , 10 , ECL_INT_TYPE , data); + ecl_kw_type * ecl_fkw = ecl_kw_alloc_new_shared( "KW" , 10 , ECL_FLOAT_TYPE , data); + + test_assert_true( ecl_kw_content_equal( ecl_kw1 , ecl_ikw )); + test_assert_false( ecl_kw_content_equal( ecl_kw1 , ecl_fkw )); + } + + test_assert_true( ecl_kw_data_equal( ecl_kw1 , data )); + data[0] = 99; + test_assert_false( ecl_kw_data_equal( ecl_kw1 , data )); + + + +} diff --git a/ThirdParty/Ert/devel/libecl/tests/ecl_kw_grdecl.c b/ThirdParty/Ert/devel/libecl/tests/ecl_kw_grdecl.c new file mode 100644 index 0000000000..5b68d278eb --- /dev/null +++ b/ThirdParty/Ert/devel/libecl/tests/ecl_kw_grdecl.c @@ -0,0 +1,70 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_kw_grdecl.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include + +int main(int argc , char ** argv) { + int i; + ecl_kw_type * ecl_kw = ecl_kw_alloc("HEAD" , 10 , ECL_INT_TYPE); + + for (i=0; i < 10; i++) + ecl_kw_iset_int(ecl_kw , i , i ); + + { + FILE * stream = util_fopen( "FILE.grdecl" , "w"); + + ecl_kw_fprintf_grdecl(ecl_kw , stream ); + fclose(stream); + + stream = util_fopen( "FILE.grdecl" , "r"); + { + ecl_kw_type * ecl_kw2 = ecl_kw_fscanf_alloc_grdecl( stream , "HEAD" , 10 , ECL_INT_TYPE); + + test_assert_not_NULL( ecl_kw2 ); + test_assert_true( ecl_kw_equal( ecl_kw , ecl_kw2)); + ecl_kw_free( ecl_kw2 ); + } + fclose( stream ); + + stream = util_fopen( "FILE.grdecl" , "w"); + ecl_kw_fprintf_grdecl__(ecl_kw , "HEAD1234" , stream ); + fclose( stream ); + + stream = util_fopen( "FILE.grdecl" , "r"); + { + ecl_kw_type * ecl_kw2 = ecl_kw_fscanf_alloc_grdecl( stream , "HEAD" , 10 , ECL_INT_TYPE); + + test_assert_NULL( ecl_kw2 ); + ecl_kw2 = ecl_kw_fscanf_alloc_grdecl( stream , "HEAD1234" , 10 , ECL_INT_TYPE); + test_assert_not_NULL( ecl_kw2 ); + + test_assert_string_equal( ecl_kw_get_header( ecl_kw2 ) , "HEAD1234" ); + test_assert_true( ecl_kw_content_equal( ecl_kw , ecl_kw2 )); + ecl_kw_free( ecl_kw2 ); + } + fclose( stream ); + + } + ecl_kw_free( ecl_kw ); + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libecl/tests/ecl_rsthead.c b/ThirdParty/Ert/devel/libecl/tests/ecl_rsthead.c new file mode 100644 index 0000000000..0c99f0fd6a --- /dev/null +++ b/ThirdParty/Ert/devel/libecl/tests/ecl_rsthead.c @@ -0,0 +1,108 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_rst_header.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include + +#include +#include +#include +#include +#include + + +void test_file( const char * filename , int occurence , bool exists , const ecl_rsthead_type * true_header) { + ecl_file_type * rst_file = ecl_file_open( filename ); + ecl_rsthead_type * rst_head = ecl_rsthead_ialloc( rst_file , occurence); + + if (exists) { + test_assert_not_NULL( rst_head ); + + if (occurence == 0) { + ecl_rsthead_type * rst_head0 = ecl_rsthead_alloc( rst_file ); + + test_assert_true( ecl_rsthead_equal( rst_head , rst_head0 )); + ecl_rsthead_free( rst_head0 ); + } + test_assert_true( ecl_rsthead_equal( rst_head , true_header )); + + ecl_rsthead_free( rst_head ); + } else + test_assert_NULL( rst_head ); + +} + + +int main(int argc , char ** argv) { + ecl_rsthead_type true1 = {.day = 1, + .year = 2000, + .month = 1, + .sim_time = (time_t) 946681200, + .version = 100, + .phase_sum = 7, + .nx = 40, + .ny = 64, + .nz = 14, + .nactive = 34770, + .nwells = 3, + .niwelz = 145, + .nzwelz = 3, + .niconz = 20, + .ncwmax = 120, + .nisegz = 18, + .nsegmx = 1, + .nswlmx = 1, + .nlbrmx = -1, + .nilbrz = -1, + .dualp = 0, + .sim_days = 0}; + + ecl_rsthead_type true2 = {.day = 22, + .year = 1990, + .month = 1, + .sim_time = (time_t) 632962800, + .version = 100, + .phase_sum = 7, + .nx = 4, + .ny = 4, + .nz = 4, + .nactive = 64, + .nwells = 3, + .niwelz = 147, + .nzwelz = 3, + .niconz = 20, + .ncwmax = 13, + .nisegz = 18, + .nsegmx = 1, + .nswlmx = 1, + .nlbrmx = -1, + .nilbrz = -1, + .dualp = 1, + .sim_days = 21}; + + const char * unified_file = argv[1]; + const char * Xfile = argv[2]; + + + test_file( unified_file , 0 , true , &true1 ); + test_file( unified_file , 100 , false , NULL ); + test_file( Xfile , 0 , true , &true2 ); + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libecl/tests/ecl_sum_test.c b/ThirdParty/Ert/devel/libecl/tests/ecl_sum_test.c new file mode 100644 index 0000000000..beb85d875d --- /dev/null +++ b/ThirdParty/Ert/devel/libecl/tests/ecl_sum_test.c @@ -0,0 +1,66 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_sum_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include + +#include + + +void test_time_range( const ecl_sum_type * ecl_sum ) { + // Hardcoded Gurbat case values + time_t start = util_make_date( 1,1,2000); + time_t end = util_make_date( 31,12,2004 ); + + test_assert_time_t_equal( ecl_sum_get_start_time( ecl_sum ) , start ); + test_assert_time_t_equal( ecl_sum_get_end_time( ecl_sum ) , end ); + test_assert_time_t_equal( ecl_sum_get_data_start(ecl_sum) , start); +} + + +void test_days( const ecl_sum_type * ecl_sum ) { + time_t date1 = util_make_date( 1,1,2000); + time_t date2 = util_make_date( 31,12,2004 ); + time_t date3 = util_make_date( 2,1,2000 ); + + double days1 = ecl_sum_time2days( ecl_sum , date1 ); + double days2 = ecl_sum_time2days( ecl_sum , date2); + double days3 = ecl_sum_time2days( ecl_sum , date3 ); + + test_assert_double_equal( days1 , 0 ); + test_assert_double_equal( days2 , 1826 ); + test_assert_double_equal( days3 , 1 ); +} + + + + + +int main( int argc , char ** argv) { + const char * casename = argv[1]; + + ecl_sum_type * ecl_sum = ecl_sum_fread_alloc_case( casename , ":"); + + test_time_range( ecl_sum ); + test_days( ecl_sum ); + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libecl/tests/ecl_util_month_range.c b/ThirdParty/Ert/devel/libecl/tests/ecl_util_month_range.c new file mode 100644 index 0000000000..f95c8ba6cf --- /dev/null +++ b/ThirdParty/Ert/devel/libecl/tests/ecl_util_month_range.c @@ -0,0 +1,124 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_util_month_range.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include + +#include + + + +void test_body( time_t_vector_type * date_list , int offset) { + int i; + for (i=offset; i < (time_t_vector_size( date_list ) - 1); i++) { + int month,year; + time_t current_date = time_t_vector_iget( date_list , i ); + test_assert_true( util_is_first_day_in_month( current_date )); + util_set_date_values( current_date , NULL , &month , &year); + if (i > offset) { + time_t prev_date = time_t_vector_iget( date_list , i - 1 ); + int prev_month , prev_year; + util_set_date_values( prev_date , NULL , &prev_month , &prev_year); + + if (prev_year == year) + test_assert_int_equal( month , prev_month + 1); + else { + test_assert_int_equal( month , 1); + test_assert_int_equal( prev_month , 12); + test_assert_int_equal( year - prev_year , 1); + } + } + test_assert_time_t_equal( current_date , util_make_pure_date( current_date )); + } +} + + +void test_append( const char * name , time_t_vector_type * date_list , time_t date1 , time_t date2, bool force_append_end) { + int offset = time_t_vector_size( date_list ); + + printf("%s ...",name); + fflush( stdout ); + + ecl_util_append_month_range( date_list , date1 , date2 , force_append_end); + + // The start: + test_assert_true( util_make_pure_date(date1) <= time_t_vector_iget( date_list , offset)); + + // The body: + test_body( date_list , offset ); + + // The tail: + if ( force_append_end ) + test_assert_time_t_equal( time_t_vector_get_last( date_list ) , util_make_pure_date(date2)); + else + test_assert_true( util_is_first_day_in_month( time_t_vector_get_last( date_list ))); + + + printf(" OK \n"); +} + + +void test_init( const char * name , time_t_vector_type * date_list , time_t start_date , time_t end_date) { + printf("%s ...",name); + fflush( stdout ); + { + ecl_util_init_month_range( date_list , start_date , end_date ); + test_assert_time_t_equal( time_t_vector_get_first( date_list ) , util_make_pure_date( start_date )); + test_body( date_list , 1 ); + test_assert_time_t_equal( time_t_vector_get_last( date_list ) , util_make_pure_date(end_date )); + } + printf(" OK \n"); +} + + +int main(int argc , char ** argv) { + time_t date1 = util_make_datetime(0,2,0,1,1,2000); + time_t date2 = util_make_datetime(0,3,0,1,1,2005); + time_t date3 = util_make_datetime(0,4,0,10,1,2000); + time_t date4 = util_make_datetime(0,5,0,10,1,2005); + + + + { + time_t_vector_type * date_list = time_t_vector_alloc(0 ,0 ); + test_append( "Append Test1" , date_list , date1 , date2 , true); + test_append( "Append Test2" , date_list , date1 , date2 , false); + test_append( "Append Test3" , date_list , date1 , date4 , true); + test_append( "Append Test4" , date_list , date1 , date4 , false); + test_append( "Append Test5" , date_list , date3 , date2 , true); + test_append( "Append Test6" , date_list , date3 , date2 , false); + test_append( "Append Test7" , date_list , date3 , date4 , true); + test_append( "Append Test8" , date_list , date3 , date4 , false); + time_t_vector_free( date_list ); + } + { + time_t_vector_type * date_list = time_t_vector_alloc(0 ,0 ); + + test_init( "Init Test1" , date_list , date1 , date2 ); + test_init( "Init Test2" , date_list , date1 , date4 ); + test_init( "Init Test3" , date_list , date3 , date2 ); + test_init( "Init Test4" , date_list , date3 , date4 ); + + time_t_vector_free( date_list ); + } + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libecl_well/CMakeLists.txt b/ThirdParty/Ert/devel/libecl_well/CMakeLists.txt index c5e65c48a3..3edab07684 100644 --- a/ThirdParty/Ert/devel/libecl_well/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libecl_well/CMakeLists.txt @@ -3,6 +3,6 @@ if (BUILD_APPLICATONS) add_subdirectory( applications ) endif() -#if (BUILD_TESTS) -# add_subdirectory( tests ) -#endif() +if (BUILD_TESTS) + add_subdirectory( tests ) +endif() diff --git a/ThirdParty/Ert/devel/libecl_well/applications/CMakeLists.txt b/ThirdParty/Ert/devel/libecl_well/applications/CMakeLists.txt index b7fb0639dc..4e4b78d7d6 100644 --- a/ThirdParty/Ert/devel/libecl_well/applications/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libecl_well/applications/CMakeLists.txt @@ -12,9 +12,11 @@ foreach(prog ${program_list}) set (destination ${CMAKE_INSTALL_PREFIX}/bin) endif() - install(TARGETS ${prog} DESTINATION ${destination}) - if (INSTALL_GROUP) - install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/${prog})") - install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/${prog})") + if (INSTALL_ERT) + install(TARGETS ${prog} DESTINATION ${destination}) + if (INSTALL_GROUP) + install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/${prog})") + install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/${prog})") + endif() endif() endforeach() diff --git a/ThirdParty/Ert/devel/libecl_well/applications/well_info_test.c b/ThirdParty/Ert/devel/libecl_well/applications/well_info_test.c index b66fd9e66d..a6f368c206 100644 --- a/ThirdParty/Ert/devel/libecl_well/applications/well_info_test.c +++ b/ThirdParty/Ert/devel/libecl_well/applications/well_info_test.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include diff --git a/ThirdParty/Ert/devel/libecl_well/include/ert/ecl_well/well_conn.h b/ThirdParty/Ert/devel/libecl_well/include/ert/ecl_well/well_conn.h index d4b56920ba..f6b1194cca 100644 --- a/ThirdParty/Ert/devel/libecl_well/include/ert/ecl_well/well_conn.h +++ b/ThirdParty/Ert/devel/libecl_well/include/ert/ecl_well/well_conn.h @@ -27,7 +27,7 @@ extern "C" { #include -#include +#include typedef enum { well_conn_dirX = 1, @@ -43,8 +43,8 @@ extern "C" { void well_conn_free( well_conn_type * conn); void well_conn_free__( void * arg ); - well_conn_type * well_conn_alloc( const ecl_kw_type * icon_kw , const ecl_kw_type * iseg_kw , const ecl_intehead_type * header , int well_nr , int seg_well_nr , int conn_nr); - well_conn_type * well_conn_alloc_wellhead( const ecl_kw_type * iwel_kw , const ecl_intehead_type * header , int well_nr); + well_conn_type * well_conn_alloc( const ecl_kw_type * icon_kw , const ecl_kw_type * iseg_kw , const ecl_rsthead_type * header , int well_nr , int seg_well_nr , int conn_nr); + well_conn_type * well_conn_alloc_wellhead( const ecl_kw_type * iwel_kw , const ecl_rsthead_type * header , int well_nr); int well_conn_get_branch(const well_conn_type * conn); int well_conn_get_i(const well_conn_type * conn); @@ -53,6 +53,8 @@ extern "C" { well_conn_dir_enum well_conn_get_dir(const well_conn_type * conn); bool well_conn_open( const well_conn_type * conn ); int well_conn_get_segment( const well_conn_type * conn ); + bool well_conn_fracture_connection( const well_conn_type * conn); + bool well_conn_matrix_connection( const well_conn_type * conn); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libecl_well/include/ert/ecl_well/well_state.h b/ThirdParty/Ert/devel/libecl_well/include/ert/ecl_well/well_state.h index 423e57c40c..0db96bc313 100644 --- a/ThirdParty/Ert/devel/libecl_well/include/ert/ecl_well/well_state.h +++ b/ThirdParty/Ert/devel/libecl_well/include/ert/ecl_well/well_state.h @@ -27,7 +27,6 @@ extern "C" { #include #include -#include #include #include diff --git a/ThirdParty/Ert/devel/libecl_well/src/CMakeLists.txt b/ThirdParty/Ert/devel/libecl_well/src/CMakeLists.txt index fda632db5c..59182ea3c8 100644 --- a/ThirdParty/Ert/devel/libecl_well/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libecl_well/src/CMakeLists.txt @@ -10,10 +10,11 @@ set_target_properties( ecl_well PROPERTIES VERSION 1.0 SOVERSION 1.0 ) target_link_libraries( ecl_well ecl ) #----------------------------------------------------------------- -install(TARGETS ecl_well DESTINATION ${CMAKE_INSTALL_LIBDIR}) -foreach(header ${header_files}) - install(FILES ../include/ert/ecl_well/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/ecl_well) -endforeach() - +if (INSTALL_ERT) + install(TARGETS ecl_well DESTINATION ${CMAKE_INSTALL_LIBDIR}) + foreach(header ${header_files}) + install(FILES ../include/ert/ecl_well/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/ecl_well) + endforeach() +endif() diff --git a/ThirdParty/Ert/devel/libecl_well/src/well_conn.c b/ThirdParty/Ert/devel/libecl_well/src/well_conn.c index bd733d09a1..0d10cd786d 100644 --- a/ThirdParty/Ert/devel/libecl_well/src/well_conn.c +++ b/ThirdParty/Ert/devel/libecl_well/src/well_conn.c @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -37,7 +38,8 @@ struct well_conn_struct { int k; well_conn_dir_enum dir; bool open; - int segment; // -1: Ordinary well + int segment; // -1: Ordinary well + bool matrix_connection; // k >= nz => fracture (and k -= nz ) /*-----------------------------------------------------------------*/ /* If the segment field == -1 - i.e. an ordinary well, the outlet_segment is rubbish and should not be consulted. @@ -47,10 +49,23 @@ struct well_conn_struct { }; +static void well_conn_set_k( well_conn_type * conn , const ecl_rsthead_type * header , int icon_k) { + conn->k = icon_k; + conn->matrix_connection = true; + + if (header->dualp) { + int geometric_nz = header->nz / 2; + if (icon_k >= geometric_nz) { + conn->k -= geometric_nz; + conn->matrix_connection = false; + } + } +} -well_conn_type * well_conn_alloc_wellhead( const ecl_kw_type * iwel_kw , const ecl_intehead_type * header , int well_nr) { + +well_conn_type * well_conn_alloc_wellhead( const ecl_kw_type * iwel_kw , const ecl_rsthead_type * header , int well_nr) { const int iwel_offset = header->niwelz * well_nr; int conn_i = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_HEADI_ITEM ); @@ -59,8 +74,11 @@ well_conn_type * well_conn_alloc_wellhead( const ecl_kw_type * iwel_kw , const e conn->i = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_HEADI_ITEM ) - 1; conn->j = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_HEADJ_ITEM ) - 1; - conn->k = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_HEADK_ITEM ) - 1; - + { + int icon_k = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_HEADK_ITEM ) - 1; + well_conn_set_k( conn , header , icon_k); + } + conn->open = true; // This is not really specified anywhere. conn->branch = 0; conn->segment = 0; @@ -72,12 +90,16 @@ well_conn_type * well_conn_alloc_wellhead( const ecl_kw_type * iwel_kw , const e } -static well_conn_type * well_conn_alloc__( const ecl_kw_type * icon_kw , int icon_offset) { +static well_conn_type * well_conn_alloc__( const ecl_kw_type * icon_kw , const ecl_rsthead_type * header , int icon_offset) { well_conn_type * conn = util_malloc( sizeof * conn ); conn->i = ecl_kw_iget_int( icon_kw , icon_offset + ICON_I_ITEM ) - 1; conn->j = ecl_kw_iget_int( icon_kw , icon_offset + ICON_J_ITEM ) - 1; - conn->k = ecl_kw_iget_int( icon_kw , icon_offset + ICON_K_ITEM ) - 1; + { + int icon_k = ecl_kw_iget_int( icon_kw , icon_offset + ICON_K_ITEM ) - 1; + well_conn_set_k( conn , header , icon_k); + } + conn->segment = ecl_kw_iget_int( icon_kw , icon_offset + ICON_SEGMENT_ITEM ) - 1; conn->outlet_segment = -999; @@ -91,7 +113,7 @@ static well_conn_type * well_conn_alloc__( const ecl_kw_type * icon_kw , int ico */ well_conn_type * well_conn_alloc( const ecl_kw_type * icon_kw , const ecl_kw_type * iseg_kw , - const ecl_intehead_type * header , + const ecl_rsthead_type * header , int well_nr , int seg_well_nr , int conn_nr ) { @@ -99,7 +121,7 @@ well_conn_type * well_conn_alloc( const ecl_kw_type * icon_kw , const int icon_offset = header->niconz * ( header->ncwmax * well_nr + conn_nr ); int IC = ecl_kw_iget_int( icon_kw , icon_offset + ICON_IC_ITEM ); if (IC > 0) { - well_conn_type * conn = well_conn_alloc__( icon_kw , icon_offset ); + well_conn_type * conn = well_conn_alloc__( icon_kw , header , icon_offset ); { int int_status = ecl_kw_iget_int( icon_kw , icon_offset + ICON_STATUS_ITEM ); if (int_status > 0) @@ -204,4 +226,11 @@ int well_conn_get_segment( const well_conn_type * conn ) { return conn->segment; } +bool well_conn_fracture_connection( const well_conn_type * conn) { + return !conn->matrix_connection; +} + +bool well_conn_matrix_connection( const well_conn_type * conn) { + return conn->matrix_connection; +} diff --git a/ThirdParty/Ert/devel/libecl_well/src/well_info.c b/ThirdParty/Ert/devel/libecl_well/src/well_info.c index 37eb6a036a..6bbf38d48f 100644 --- a/ThirdParty/Ert/devel/libecl_well/src/well_info.c +++ b/ThirdParty/Ert/devel/libecl_well/src/well_info.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -287,14 +287,14 @@ static void well_info_add_state( well_info_type * well_info , well_state_type * */ void well_info_add_wells( well_info_type * well_info , ecl_file_type * rst_file , int report_nr) { - ecl_intehead_type * global_header = ecl_intehead_alloc( ecl_file_iget_named_kw( rst_file , INTEHEAD_KW , 0 )); + ecl_rsthead_type * global_header = ecl_rsthead_alloc( rst_file ); int well_nr; for (well_nr = 0; well_nr < global_header->nwells; well_nr++) { well_state_type * well_state = well_state_alloc( rst_file , report_nr , well_nr ); if (well_state != NULL) well_info_add_state( well_info , well_state ); } - ecl_intehead_free( global_header ); + ecl_rsthead_free( global_header ); } /** diff --git a/ThirdParty/Ert/devel/libecl_well/src/well_state.c b/ThirdParty/Ert/devel/libecl_well/src/well_state.c index dc855b7883..ed4c3d06cc 100644 --- a/ThirdParty/Ert/devel/libecl_well/src/well_state.c +++ b/ThirdParty/Ert/devel/libecl_well/src/well_state.c @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include #include @@ -96,7 +96,7 @@ well_path_type * well_state_add_path( well_state_type * well_state , const ecl_f } -void well_state_add_wellhead( well_state_type * well_state , const ecl_intehead_type * header , const ecl_kw_type * iwel_kw , int well_nr , const char * grid_name , int grid_nr) { +void well_state_add_wellhead( well_state_type * well_state , const ecl_rsthead_type * header , const ecl_kw_type * iwel_kw , int well_nr , const char * grid_name , int grid_nr) { well_conn_type * wellhead = well_conn_alloc_wellhead( iwel_kw , header , well_nr ); if (wellhead != NULL) { @@ -113,7 +113,7 @@ void well_state_add_wellhead( well_state_type * well_state , const ecl_intehead_ */ static void well_state_add_connections( well_state_type * well_state , const ecl_file_type * rst_file , int grid_nr, int well_nr ) { - ecl_intehead_type * header = ecl_intehead_alloc( ecl_file_iget_named_kw( rst_file , INTEHEAD_KW , 0 )); + ecl_rsthead_type * header = ecl_rsthead_alloc( rst_file ); const ecl_kw_type * icon_kw = ecl_file_iget_named_kw( rst_file , ICON_KW , 0); const ecl_kw_type * iwel_kw = ecl_file_iget_named_kw( rst_file , IWEL_KW , 0); const int iwel_offset = header->niwelz * well_nr; @@ -152,7 +152,7 @@ static void well_state_add_connections( well_state_type * well_state , const ec well_path_add_conn( path , conn ); } } - ecl_intehead_free( header ); + ecl_rsthead_free( header ); } /* @@ -167,14 +167,16 @@ static int well_state_get_lgr_well_nr( const well_state_type * well_state , cons int well_nr = -1; if (ecl_file_has_kw( ecl_file , ZWEL_KW)) { + ecl_rsthead_type * header = ecl_rsthead_alloc( ecl_file ); // const ecl_kw_type * zwel_kw = ecl_file_iget_named_kw( ecl_file , ZWEL_KW , 0); - int num_wells = ecl_kw_get_size( zwel_kw ); + int num_wells = header->nwells; well_nr = 0; while (true) { bool found = false; { - char * lgr_well_name = util_alloc_strip_copy( ecl_kw_iget_ptr( zwel_kw , well_nr) ); + char * lgr_well_name = util_alloc_strip_copy( ecl_kw_iget_ptr( zwel_kw , well_nr * header->nzwelz) ); + if ( strcmp( well_state->name , lgr_well_name) == 0) found = true; else @@ -189,7 +191,9 @@ static int well_state_get_lgr_well_nr( const well_state_type * well_state , cons well_nr = -1; break; } + } + ecl_rsthead_free( header ); } return well_nr; } @@ -197,8 +201,8 @@ static int well_state_get_lgr_well_nr( const well_state_type * well_state , cons well_state_type * well_state_alloc( ecl_file_type * ecl_file , int report_nr , int global_well_nr) { if (ecl_file_has_kw( ecl_file , IWEL_KW)) { - well_state_type * well_state = NULL; - ecl_intehead_type * global_header = ecl_intehead_alloc( ecl_file_iget_named_kw( ecl_file , INTEHEAD_KW , 0 )); + well_state_type * well_state = NULL; + ecl_rsthead_type * global_header = ecl_rsthead_alloc( ecl_file ); const ecl_kw_type * global_iwel_kw = ecl_file_iget_named_kw( ecl_file , IWEL_KW , 0); const ecl_kw_type * global_zwel_kw = ecl_file_iget_named_kw( ecl_file , ZWEL_KW , 0); @@ -263,7 +267,6 @@ well_state_type * well_state_alloc( ecl_file_type * ecl_file , int report_nr , ecl_file_subselect_block( ecl_file , LGR_KW , lgr_nr ); // { // Restrict the file view int well_nr = well_state_get_lgr_well_nr( well_state , ecl_file); // to one LGR block. - // if (well_nr >= 0) // well_state_add_connections( well_state , ecl_file , lgr_nr + 1, well_nr ); // } // @@ -272,7 +275,7 @@ well_state_type * well_state_alloc( ecl_file_type * ecl_file , int report_nr , } } } - ecl_intehead_free( global_header ); + ecl_rsthead_free( global_header ); return well_state; } else /* This seems a bit weird - have come over E300 restart files without the IWEL keyword. */ diff --git a/ThirdParty/Ert/devel/libecl_well/src/well_ts.c b/ThirdParty/Ert/devel/libecl_well/src/well_ts.c index 8604aff2e0..dbf15442d5 100644 --- a/ThirdParty/Ert/devel/libecl_well/src/well_ts.c +++ b/ThirdParty/Ert/devel/libecl_well/src/well_ts.c @@ -101,6 +101,7 @@ static well_node_type * well_node_alloc( well_state_type * well_state) { static UTIL_SAFE_CAST_FUNCTION( well_node , WELL_NODE_TYPE_ID ) +static UTIL_SAFE_CAST_FUNCTION_CONST( well_node , WELL_NODE_TYPE_ID ) static void well_node_free( well_node_type * well_node ) { @@ -113,6 +114,20 @@ static void well_node_free__( void * arg ) { well_node_free( node ); } +static int well_node_time_cmp( const void * arg1 , const void * arg2) { + const well_node_type * node1 = well_node_safe_cast_const( arg1 ); + const well_node_type * node2 = well_node_safe_cast_const( arg2 ); + + if (node1->sim_time < node2->sim_time) + return -1; + else if (node1->sim_time == node2->sim_time) + return 0; + else + return 1; + +} + + /*****************************************************************/ static well_ts_type * well_ts_alloc_empty( ) { @@ -144,13 +159,13 @@ static int well_ts_get_index__( const well_ts_type * well_ts , int report_step , if (use_report) { if (report_step < first_node->report_nr) - return 0; // Before the start + return -1; // Before the start if (report_step >= last_node->report_nr) return size - 1; // After end } else { if (sim_time < first_node->sim_time) - return 0; // Before the start + return -1; // Before the start if (sim_time >= last_node->sim_time) return size - 1; // After end @@ -247,33 +262,15 @@ static int well_ts_get_index( const well_ts_type * well_ts , int report_step , t void well_ts_add_well( well_ts_type * well_ts , well_state_type * well_state ) { well_node_type * new_node = well_node_alloc( well_state ); + vector_append_owned_ref( well_ts->ts , new_node , well_node_free__ ); - if (vector_get_size( well_ts->ts ) == 0) - // The first element in the vector - vector_append_owned_ref( well_ts->ts , new_node , well_node_free__ ); - else { + if (vector_get_size( well_ts->ts ) > 1) { const well_node_type * last_node = vector_get_last_const(well_ts->ts ); - if (new_node->sim_time > last_node->sim_time) - // This is the fast path which will apply when the well_state objects - // are added in a time-ordered fashion. - vector_append_owned_ref( well_ts->ts , new_node , well_node_free__ ); - else { - // Use binary search through the vector to determine the - // new location - int index = well_ts_get_index( well_ts , new_node->report_nr , -1 , true); - if (index < 0) - index = 0; - - { - const well_node_type * exnode = vector_iget_const( well_ts->ts , index ); - if (exnode->report_nr == new_node->report_nr) - // Replace the exsisting node - vector_iset_owned_ref( well_ts->ts , index , new_node , well_node_free__ ); - else - // Insert a new node - pushing the existing to the right. - vector_insert_owned_ref( well_ts->ts , index , new_node , well_node_free__ ); - } - } + if (new_node->sim_time < last_node->sim_time) + // The new node is chronologically before the previous node; + // i.e. we must sort the nodes in time. This should probably happen + // quite seldom: + vector_sort( well_ts->ts , well_node_time_cmp ); } } diff --git a/ThirdParty/Ert/devel/libecl_well/tests/CMakeLists.txt b/ThirdParty/Ert/devel/libecl_well/tests/CMakeLists.txt new file mode 100644 index 0000000000..27427e453c --- /dev/null +++ b/ThirdParty/Ert/devel/libecl_well/tests/CMakeLists.txt @@ -0,0 +1,16 @@ +add_executable( well_ts well_ts.c ) +target_link_libraries( well_ts ecl_well ) +add_test( well_ts ${EXECUTABLE_OUTPUT_PATH}/well_ts ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/CO2case/BASE_CASE ) +set_property( TEST well_ts PROPERTY LABELS Statoil ) + + +add_executable( well_dualp well_dualp.c ) +target_link_libraries( well_dualp ecl_well ) +add_test( well_dualp ${EXECUTABLE_OUTPUT_PATH}/well_dualp ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST + ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/DualPoro/DUALPORO.X0005 ) + + +add_executable( well_lgr_load well_lgr_load.c ) +target_link_libraries( well_lgr_load ecl_well ) +add_test( well_lgr_load ${EXECUTABLE_OUTPUT_PATH}/well_lgr_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/0.9.2_LGR/BASE_REF_XY3Z1_T30_WI.X0003) +set_property( TEST well_lgr_load PROPERTY LABELS Statoil ) diff --git a/ThirdParty/Ert/devel/libecl_well/tests/well_dualp.c b/ThirdParty/Ert/devel/libecl_well/tests/well_dualp.c new file mode 100644 index 0000000000..cfe901c298 --- /dev/null +++ b/ThirdParty/Ert/devel/libecl_well/tests/well_dualp.c @@ -0,0 +1,65 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_dualp.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + + +void test_rstfile( const char * filename , bool fracture_connection) { + ecl_file_type * rst_file = ecl_file_open( filename ); + const ecl_kw_type * iwel_kw = ecl_file_iget_named_kw( rst_file , IWEL_KW , 0); + ecl_rsthead_type * header = ecl_rsthead_alloc( rst_file ); + + well_conn_type * wellhead = well_conn_alloc_wellhead( iwel_kw , header , 0 ); + + if (fracture_connection) { + test_assert_true( well_conn_fracture_connection( wellhead )); + test_assert_false( well_conn_matrix_connection( wellhead )); + } else { + test_assert_false( well_conn_fracture_connection( wellhead )); + test_assert_true( well_conn_matrix_connection( wellhead )); + } + + test_assert_true( well_conn_get_k( wellhead ) < header->nz ); + + ecl_rsthead_free( header ); + well_conn_free( wellhead ); + ecl_file_close( rst_file ); +} + + +int main(int argc , char ** argv) { + const char * matrix_rstfile = argv[1]; + const char * fracture_rstfile = argv[2]; + + test_rstfile( fracture_rstfile , true); + test_rstfile( matrix_rstfile , false ); + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libecl_well/tests/well_lgr_load.c b/ThirdParty/Ert/devel/libecl_well/tests/well_lgr_load.c new file mode 100644 index 0000000000..d3a3b477c6 --- /dev/null +++ b/ThirdParty/Ert/devel/libecl_well/tests/well_lgr_load.c @@ -0,0 +1,66 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_lgr_load.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + + + +int main( int argc , char ** argv) { + signal(SIGSEGV , util_abort_signal); /* Segmentation violation, i.e. overwriting memory ... */ + signal(SIGTERM , util_abort_signal); /* If killing the enkf program with SIGTERM (the default kill signal) you will get a backtrace. + Killing with SIGKILL (-9) will not give a backtrace.*/ + signal(SIGABRT , util_abort_signal); /* Signal abort. */ + { + well_info_type * well_info = well_info_alloc( NULL ); + int i; + for (i=1; i < argc; i++) { + printf("Loading file: %s \n",argv[i]); + well_info_load_rstfile( well_info , argv[i]); + } + + // List all wells: + { + int iwell; + for (iwell = 0; iwell < well_info_get_num_wells( well_info ); iwell++) { + well_ts_type * well_ts = well_info_get_ts( well_info , well_info_iget_well_name( well_info , iwell)); + well_state_type * well_state = well_ts_get_last_state( well_ts ); + + well_state_summarize( well_state , stdout ); + printf("\n"); + } + } + well_info_free( well_info ); + } + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libecl_well/tests/well_ts.c b/ThirdParty/Ert/devel/libecl_well/tests/well_ts.c new file mode 100644 index 0000000000..33b1d4c0fb --- /dev/null +++ b/ThirdParty/Ert/devel/libecl_well/tests/well_ts.c @@ -0,0 +1,71 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_ts.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include + +#include + +#include + + +int main(int argc , char ** argv) { + const char * case_path = argv[1]; + stringlist_type * file_list = stringlist_alloc_new( ); + ecl_util_select_filelist( NULL , case_path , ECL_RESTART_FILE , false , file_list); + + printf("Searching in:%s \n",case_path); + test_assert_int_equal( 4 , stringlist_get_size( file_list )); + stringlist_sort( file_list , (string_cmp_ftype *) util_strcmp_int ); + + + { + int i; + for (i=0; i < stringlist_get_size( file_list); i++) { + char * ext; + char * target_ext = util_alloc_sprintf("X%04d" , i); + util_alloc_file_components( stringlist_iget( file_list , i ) , NULL , NULL , &ext); + + test_assert_string_equal( ext , target_ext); + free( ext ); + free( target_ext ); + } + } + { + well_info_type * well_info = well_info_alloc( NULL ); + int i; + for (i=0; i < stringlist_get_size( file_list ); i++) + well_info_load_rstfile( well_info , stringlist_iget(file_list , i)); + well_info_free( well_info ); + } + + { + well_info_type * well_info = well_info_alloc( NULL ); + int i; + stringlist_reverse( file_list ); + for (i=0; i < stringlist_get_size( file_list ); i++) + well_info_load_rstfile( well_info , stringlist_iget(file_list , i)); + well_info_free( well_info ); + } + + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libenkf/CMakeLists.txt b/ThirdParty/Ert/devel/libenkf/CMakeLists.txt index 9db4a4c5e8..d6f06317db 100644 --- a/ThirdParty/Ert/devel/libenkf/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libenkf/CMakeLists.txt @@ -1,6 +1,5 @@ add_subdirectory( src ) add_subdirectory( applications/ert_tui ) - -#if (BUILD_TESTS) -# add_subdirectory( tests ) -#endif() +if (BUILD_TESTS) + add_subdirectory( tests ) +endif() diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/bin/gert b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/bin/gert index 8259885d13..b7878a3c89 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/bin/gert +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/bin/gert @@ -1,58 +1,14 @@ #!/bin/bash - - -if [ -z "$1" ] -then - echo - echo "A configuration file must be specified, or if you want to create a new" - echo "configuration: enter the path to the new (non-existing) configuration file." - echo " ertgui.sh ert_configuration_file" - echo - echo "Options (for debugging):" - echo " gert debug ert_configuration_file" - echo " gert strace ert_configuration_file" - echo " gert local .... will use the Python code in your working copy" - echo - exit -fi - -# -# setup the SDP environment -# export ERT_SITE_CONFIG=/project/res/etc/ERT/site-config -export QT_EXPERIMENTAL=1 -export PYTHON_EXPERIMENTAL=1 -source /project/res/SDP_bashrc > /dev/null -set PYTHON=2.4 ; source /prog/sdpsoft/environment.sh > /dev/null +BASEDIR=$(dirname $0) +export PYTHONPATH=~/ert/ert/devel/python/python:$BASEDIR/../lib:$PYTHONPATH +export GERT_SHARE_PATH=$BASEDIR/../share +export LD_LIBRARY_PATH=~/ert/ert/build/lib64:$LD_LIBRARY_PATH +ert_gui_dir=$BASEDIR/../lib/ert_gui/ -export ERT_LD_PATH=$SDP_BINDIST/lib/python/lib - -ORIGINAL_DIRECTORY=$PWD - -if [ "$1" = "local" ] -then - # The user has given "local" as the first argument, meaning that we should - # run based on Python code in the users current working directory, and not - # the centraly installed code. - BASEDIR=$(dirname $0) - export ert_gui_dir=$BASEDIR/../ - shift -else - export ert_gui_dir=$SDP_BINDIST/lib/python/gert -fi echo "Loading python GUI code from.......:" $ert_gui_dir echo "-----------------------------------------------------------------" -if [ "$1" = "debug" ] -then - export CONFIG_FILE="$2" - gdb python --command=$ert_gui_dir/bin/gdbcommands -elif [ "$1" = "strace" ] -then - strace -e trace=file python $ert_gui_dir/code/main.py "$2" -else - python $ert_gui_dir/code/main.py "$1" -fi +python $ert_gui_dir/gert_main.py "$1" -cd "$ORIGINAL_DIRECTORY" diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/gert_main.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/gert_main.py index 8ee008e0fc..828d8f4483 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/gert_main.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/gert_main.py @@ -114,6 +114,8 @@ from PyQt4 import QtGui, QtCore import sys import os +from ert.ert.ertwrapper import ErtWrapper + import ert_gui.widgets.util import ert_gui.widgets.help ert_gui.widgets.help.help_prefix = os.getenv("GERT_SHARE_PATH")+ "/help/" @@ -130,7 +132,6 @@ from ert_gui.pages.init.initpanel import InitPanel from ert_gui.pages.run.runpanel import RunPanel from ert_gui.pages.config.configpages import ConfigPages from ert_gui.pages.plot.plotpanel import PlotPanel -from ert.ertwrapper import ErtWrapper from ert_gui.widgets.helpedwidget import ContentModel from ert_gui.widgets.util import resourceImage, resourceIcon @@ -186,7 +187,7 @@ window.setSaveFunction(ert.save) splash.showMessage("Creating GUI...", color=QtCore.Qt.white) app.processEvents() -window.addPage("Configuration", resourceIcon("config"), ConfigPages(window)) +#window.addPage("Configuration", resourceIcon("config"), ConfigPages(window)) window.addPage("Init", resourceIcon("db"), InitPanel(window)) window.addPage("Run", resourceIcon("run"), RunPanel(window)) window.addPage("Plots", resourceIcon("plot"), PlotPanel()) diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/analysis.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/analysis.py index da2e6697c6..1a6d312eb4 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/analysis.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/analysis.py @@ -19,41 +19,30 @@ # Analysis tab # ---------------------------------------------------------------------------------------------- from ert_gui.widgets.checkbox import CheckBox -import ert.ertwrapper as ertwrapper from ert_gui.widgets.spinnerwidgets import IntegerSpinner, DoubleSpinner, DoubleSpinner import ert_gui.widgets.tablewidgets from ert_gui.widgets.pathchooser import PathChooser from ert_gui.widgets.combochoice import ComboChoice from PyQt4 import QtGui +import ert.enkf def createAnalysisPage(configPanel, parent): configPanel.startPage("Analysis") r = configPanel.addRow(CheckBox(parent, "ENKF rerun", "config/analysis/enkf_rerun", "Perform rerun")) - r.initialize = lambda ert : [ert.prototype("int analysis_config_get_rerun(long)"), - ert.prototype("void analysis_config_set_rerun(long, bool)")] r.getter = lambda ert : ert.enkf.analysis_config_get_rerun(ert.analysis_config) r.setter = lambda ert, value : ert.enkf.analysis_config_set_rerun(ert.analysis_config, value) r = configPanel.addRow(IntegerSpinner(parent, "Rerun start", "config/analysis/rerun_start", 0, 100000)) - r.initialize = lambda ert : [ert.prototype("int analysis_config_get_rerun_start(long)"), - ert.prototype("void analysis_config_set_rerun_start(long, int)")] r.getter = lambda ert : ert.enkf.analysis_config_get_rerun_start(ert.analysis_config) r.setter = lambda ert, value : ert.enkf.analysis_config_set_rerun_start(ert.analysis_config, value) r = configPanel.addRow(PathChooser(parent, "ENKF schedule file", "config/analysis/enkf_sched_file")) - r.initialize = lambda ert : [ert.prototype("char* model_config_get_enkf_sched_file(long)"), - ert.prototype("long enkf_main_get_model_config(long)"), - ert.prototype("void model_config_set_enkf_sched_file(long, char*)")] r.getter = lambda ert : ert.enkf.model_config_get_enkf_sched_file(ert.enkf.enkf_main_get_model_config(ert.main)) r.setter = lambda ert, value : ert.enkf.model_config_set_enkf_sched_file(ert.enkf.enkf_main_get_model_config(ert.main), str(value)) r = configPanel.addRow(ert_gui.widgets.tablewidgets.KeywordList(parent, "Local config", "config/analysis/local_config")) r.newKeywordPopup = lambda list : QtGui.QFileDialog.getOpenFileName(r, "Select a path", "") - r.initialize = lambda ert : [ert.prototype("long local_config_get_config_files(long)"), - ert.prototype("long enkf_main_get_local_config(long)"), - ert.prototype("void local_config_clear_config_files(long)"), - ert.prototype("void local_config_add_config_file(long, char*)")] def get_local_config_files(ert): local_config = ert.enkf.enkf_main_get_local_config(ert.main) @@ -72,8 +61,6 @@ def createAnalysisPage(configPanel, parent): r.setter = add_config_file r = configPanel.addRow(PathChooser(parent, "Update log", "config/analysis/update_log")) - r.initialize = lambda ert : [ert.prototype("char* analysis_config_get_log_path(long)"), - ert.prototype("void analysis_config_set_log_path(long, char*)")] r.getter = lambda ert : ert.enkf.analysis_config_get_log_path(ert.analysis_config) r.setter = lambda ert, value : ert.enkf.analysis_config_set_log_path(ert.analysis_config, str(value)) @@ -81,14 +68,10 @@ def createAnalysisPage(configPanel, parent): configPanel.startGroup("EnKF") r = configPanel.addRow(DoubleSpinner(parent, "Alpha", "config/analysis/enkf_alpha", 0, 100000, 2)) - r.initialize = lambda ert : [ert.prototype("double analysis_config_get_alpha(long)"), - ert.prototype("void analysis_config_set_alpha(long, double)")] r.getter = lambda ert : ert.enkf.analysis_config_get_alpha(ert.analysis_config) r.setter = lambda ert, value : ert.enkf.analysis_config_set_alpha(ert.analysis_config, value) r = configPanel.addRow(CheckBox(parent, "Merge Observations", "config/analysis/enkf_merge_observations", "Perform merge")) - r.initialize = lambda ert : [ert.prototype("bool analysis_config_get_merge_observations(long)"), - ert.prototype("void analysis_config_set_merge_observations(long, int)")] r.getter = lambda ert : ert.enkf.analysis_config_get_merge_observations(ert.analysis_config) r.setter = lambda ert, value : ert.enkf.analysis_config_set_merge_observations(ert.analysis_config, value) @@ -96,15 +79,11 @@ def createAnalysisPage(configPanel, parent): enkf_mode_type = {"ENKF_STANDARD" : 10, "ENKF_SQRT" : 20} enkf_mode_type_inverted = {10 : "ENKF_STANDARD" , 20 : "ENKF_SQRT"} r = configPanel.addRow(ComboChoice(parent, enkf_mode_type.keys(), "Mode", "config/analysis/enkf_mode")) - r.initialize = lambda ert : [ert.prototype("int analysis_config_get_enkf_mode(long)"), - ert.prototype("void analysis_config_set_enkf_mode(long, int)")] r.getter = lambda ert : enkf_mode_type_inverted[ert.enkf.analysis_config_get_enkf_mode(ert.analysis_config)] r.setter = lambda ert, value : ert.enkf.analysis_config_set_enkf_mode(ert.analysis_config, enkf_mode_type[str(value)]) r = configPanel.addRow(DoubleSpinner(parent, "Truncation", "config/analysis/enkf_truncation", 0, 1, 2)) - r.initialize = lambda ert : [ert.prototype("double analysis_config_get_truncation(long)"), - ert.prototype("void analysis_config_set_truncation(long, double)")] r.getter = lambda ert : ert.enkf.analysis_config_get_truncation(ert.analysis_config) r.setter = lambda ert, value : ert.enkf.analysis_config_set_truncation(ert.analysis_config, value) diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/eclipse.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/eclipse.py index 303629ca30..4a5504dc27 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/eclipse.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/eclipse.py @@ -20,60 +20,43 @@ # ---------------------------------------------------------------------------------------------- from ert_gui.widgets.pathchooser import PathChooser from ert_gui.widgets.tablewidgets import KeywordTable, KeywordList -import ert.ertwrapper as ertwrapper from ert_gui.widgets.configpanel import ConfigPanel +import ert.enkf def createEclipsePage(configPanel, parent): configPanel.startPage("Eclipse") r = configPanel.addRow(PathChooser(parent, "Eclipse Base", "config/eclipse/eclbase", path_format=True)) - r.initialize = lambda ert : [ert.prototype("char* ecl_config_get_eclbase(long)"), - ert.prototype("void enkf_main_set_eclbase(long, char*)")] r.getter = lambda ert : ert.enkf.ecl_config_get_eclbase(ert.ecl_config) r.setter = lambda ert, value : ert.enkf.enkf_main_set_eclbase(ert.main , str(value)) r = configPanel.addRow(PathChooser(parent, "Data file", "config/eclipse/data_file", show_files=True)) - r.initialize = lambda ert : [ert.prototype("char* ecl_config_get_data_file(long)"), - ert.prototype("void enkf_main_set_data_file(long, char*)")] r.getter = lambda ert : ert.enkf.ecl_config_get_data_file(ert.ecl_config) r.setter = lambda ert, value : ert.enkf.enkf_main_set_data_file(ert.main , str(value)) r = configPanel.addRow(PathChooser(parent, "Grid", "config/eclipse/grid", show_files=True)) - r.initialize = lambda ert : [ert.prototype("char* ecl_config_get_gridfile(long)"), - ert.prototype("void ecl_config_set_grid(long, char*)")] r.getter = lambda ert : ert.enkf.ecl_config_get_gridfile(ert.ecl_config) r.setter = lambda ert, value : ert.enkf.ecl_config_set_grid(ert.ecl_config, str(value)) r = configPanel.addRow(PathChooser(parent, "Schedule file" , "config/eclipse/schedule_file" , show_files = True)) - r.initialize = lambda ert : [ert.prototype("char* ecl_config_get_schedule_file(long)"), - ert.prototype("void ecl_config_set_schedule_file(long, char*)")] r.getter = lambda ert : ert.enkf.ecl_config_get_schedule_file(ert.ecl_config) r.setter = lambda ert, value : ert.enkf.ecl_config_set_schedule_file(ert.ecl_config, str(value)) r = configPanel.addRow(PathChooser(parent, "Init section", "config/eclipse/init_section", show_files=True)) - r.initialize = lambda ert : [ert.prototype("char* ecl_config_get_init_section(long)"), - ert.prototype("void ecl_config_set_init_section(long, char*)")] r.getter = lambda ert : ert.enkf.ecl_config_get_init_section(ert.ecl_config) r.setter = lambda ert, value : ert.enkf.ecl_config_set_init_section(ert.ecl_config, str(value)) r = configPanel.addRow(PathChooser(parent, "Refcase", "config/eclipse/refcase", show_files=True)) - r.initialize = lambda ert : [ert.prototype("char* ecl_config_get_refcase_name(long)"), - ert.prototype("void ecl_config_load_refcase(long, char*)")] r.getter = lambda ert : ert.enkf.ecl_config_get_refcase_name(ert.ecl_config) r.setter = lambda ert, value : ert.enkf.ecl_config_load_refcase(ert.ecl_config, str(value)) r = configPanel.addRow(PathChooser(parent, "Schedule prediction file", "config/eclipse/schedule_prediction_file", show_files=True)) - r.initialize = lambda ert : [ert.prototype("char* enkf_main_get_schedule_prediction_file(long)"), - ert.prototype("void enkf_main_set_schedule_prediction_file(long, char*)")] r.getter = lambda ert : ert.enkf.enkf_main_get_schedule_prediction_file(ert.main) r.setter = lambda ert, value : ert.enkf.enkf_main_set_schedule_prediction_file(ert.main, ert.nonify( value )) r = configPanel.addRow(KeywordTable(parent, "Data keywords", "config/eclipse/data_kw")) - r.initialize = lambda ert : [ert.prototype("long enkf_main_get_data_kw(long)"), - ert.prototype("void enkf_main_clear_data_kw(long)"), - ert.prototype("void enkf_main_add_data_kw(long, char*, char*)")] r.getter = lambda ert : ert.getSubstitutionList(ert.enkf.enkf_main_get_data_kw(ert.main)) def add_data_kw(ert, listOfKeywords): @@ -93,9 +76,6 @@ def createEclipsePage(configPanel, parent): internalPanel.startPage("Static keywords") r = internalPanel.addRow(KeywordList(parent, "", "config/eclipse/add_static_kw")) - r.initialize = lambda ert : [ert.prototype("long ecl_config_get_static_kw_list(long)"), - ert.prototype("void ecl_config_clear_static_kw(long)"), - ert.prototype("void ecl_config_add_static_kw(long, char*)")] r.getter = lambda ert : ert.getStringList(ert.enkf.ecl_config_get_static_kw_list(ert.ecl_config)) def add_static_kw(ert, listOfKeywords): diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/ensemble.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/ensemble.py index ecb9a8177c..ba40fec8f1 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/ensemble.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/ensemble.py @@ -20,19 +20,16 @@ # ---------------------------------------------------------------------------------------------- from PyQt4 import QtGui, QtCore from ert_gui.widgets.spinnerwidgets import IntegerSpinner -import ert.ertwrapper as ertwrapper from parameters.parameterpanel import ParameterPanel, enums from parameters.parametermodels import SummaryModel, DataModel, FieldModel, KeywordModel -from ert.enums import field_type -from ert.enums import truncation_type -from ert.enums import gen_data_file_format +from ert.ert.enums import field_type +from ert.ert.enums import truncation_type +from ert.ert.enums import gen_data_file_format def createEnsemblePage(configPanel, parent): configPanel.startPage("Ensemble") r = configPanel.addRow(IntegerSpinner(parent, "Number of realizations", "config/ensemble/num_realizations", 1, 10000)) - r.initialize = lambda ert : [ert.prototype("int enkf_main_get_ensemble_size(long)"), - ert.prototype("void enkf_main_resize_ensemble(int)")] r.getter = lambda ert : ert.enkf.enkf_main_get_ensemble_size(ert.main) r.setter = lambda ert, value : ert.enkf.enkf_main_resize_ensemble(ert.main, value) @@ -44,51 +41,6 @@ def createEnsemblePage(configPanel, parent): r = configPanel.addRow(ParameterPanel(parent, "", "")) # no help file necessary parent.connect(r, QtCore.SIGNAL("contentsChanged()"), lambda : r.modelEmit("ensembleUpdated()")) - def initialize(ert): - ert.prototype("long ensemble_config_get_node(long, char*)") - ert.prototype("long ensemble_config_alloc_keylist(long)") - ert.prototype("long ensemble_config_add_summary(long, char*)") - ert.prototype("long ensemble_config_add_gen_kw(long, char*)") - ert.prototype("long ensemble_config_add_gen_data(long, char*)") - ert.prototype("long ensemble_config_add_field(long, char*, long)") - - ert.prototype("void enkf_main_del_node(long, char*)") - ert.prototype("long ecl_config_get_grid(long)") - - ert.prototype("long enkf_config_node_get_impl_type(long)") - ert.prototype("long enkf_config_node_get_ref(long)") - ert.prototype("bool enkf_config_node_is_valid(long)") - ert.prototype("char* enkf_config_node_get_min_std_file(long)") - ert.prototype("char* enkf_config_node_get_enkf_outfile(long)") - ert.prototype("char* enkf_config_node_get_enkf_infile(long)") - ert.prototype("void enkf_config_node_update_gen_kw(long, char*, char*, char*, char*, char*)") - ert.prototype("void enkf_config_node_update_state_field(long, int, double, double)") - ert.prototype("void enkf_config_node_update_parameter_field(long, char*, char*, char*, int, double, double, char*, char*)") - ert.prototype("void enkf_config_node_update_general_field(long, char*, char*, char*, char*, int, double, double, char*, char*, char*)") - ert.prototype("void enkf_config_node_update_gen_data(long, int, int, char*, char*, char*, char*, char*, char*)") - - ert.prototype("char* gen_kw_config_get_template_file(long)") - ert.prototype("char* gen_kw_config_get_init_file_fmt(long)") - ert.prototype("char* gen_kw_config_get_parameter_file(long)") - - ert.prototype("long gen_data_config_get_output_format(long)") - ert.prototype("long gen_data_config_get_input_format(long)") - ert.prototype("char* gen_data_config_get_template_file(long)") - ert.prototype("char* gen_data_config_get_template_key(long)") - ert.prototype("char* gen_data_config_get_init_file_fmt(long)") - - ert.prototype("int field_config_get_type(long)") - ert.prototype("int field_config_get_truncation_mode(long)") - ert.prototype("double field_config_get_truncation_min(long)") - ert.prototype("double field_config_get_truncation_max(long)") - ert.prototype("char* field_config_get_init_transform_name(long)") - ert.prototype("char* field_config_get_output_transform_name(long)") - ert.prototype("char* field_config_get_init_file_fmt(long)") - - - - r.initialize = initialize - def getEnsembleParameters(ert): keys = ert.getStringList(ert.enkf.ensemble_config_alloc_keylist(ert.ensemble_config), free_after_use=True) diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/jobs/jobsdialog.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/jobs/jobsdialog.py index b87614badb..468009b714 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/jobs/jobsdialog.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/jobs/jobsdialog.py @@ -22,7 +22,6 @@ from ert_gui.widgets.tablewidgets import KeywordTable from ert_gui.widgets.tablewidgets import KeywordList from ert_gui.widgets.stringbox import StringBox import os -from ert.ertwrapper import c_char_p, c_int from ert_gui.widgets.spinnerwidgets import IntegerSpinner import ert_gui.widgets.util from ert_gui.widgets.helpedwidget import ContentModelProxy @@ -158,34 +157,6 @@ class JobConfigPanel(ConfigPanel): self.addRow(widget, label) - def initialize(self, ert): - if not self.initialized: - ert.prototype("long site_config_get_installed_jobs(long)") - ert.prototype("char* ext_job_get_stdin_file(long)",lib=ert.job_queue) - ert.prototype("void ext_job_set_stdin_file(long, char*)", lib=ert.job_queue) - ert.prototype("char* ext_job_get_stdout_file(long)", lib=ert.job_queue) - ert.prototype("void ext_job_set_stdout_file(long, char*)", lib=ert.job_queue) - ert.prototype("char* ext_job_get_stderr_file(long)", lib=ert.job_queue) - ert.prototype("void ext_job_set_stderr_file(long, char*)", lib=ert.job_queue) - ert.prototype("char* ext_job_get_target_file(long)", lib=ert.job_queue) - ert.prototype("void ext_job_set_target_file(long, char*)", lib=ert.job_queue) - ert.prototype("char* ext_job_get_executable(long)", lib=ert.job_queue) - ert.prototype("void ext_job_set_executable(long, char*)", lib=ert.job_queue) - ert.prototype("char* ext_job_get_private_args_as_string(long)", lib=ert.job_queue) - ert.prototype("void ext_job_set_private_args_from_string(long, char*)", lib=ert.job_queue) - ert.prototype("int ext_job_get_max_running(long)", lib=ert.job_queue) - ert.prototype("void ext_job_set_max_running(long, int)", lib=ert.job_queue) - ert.prototype("int ext_job_get_max_running_minutes(long)", lib=ert.job_queue) - ert.prototype("void ext_job_set_max_running_minutes(long, int)", lib=ert.job_queue) - ert.prototype("long ext_job_get_environment(long)", lib=ert.job_queue) - ert.prototype("void ext_job_add_environment(long, char*, char*)", lib=ert.job_queue) - ert.prototype("void ext_job_clear_environment(long)", lib=ert.job_queue) - ert.prototype("void ext_job_save(long)", lib=ert.job_queue) - ert.prototype("long ext_joblist_get_job(long, char*)", lib=ert.job_queue) - - self.initialized = True - - def setJob(self, job): self.job = job diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/observations.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/observations.py index 5b95a406e9..e7f0609726 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/observations.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/observations.py @@ -20,15 +20,13 @@ # ---------------------------------------------------------------------------------------------- from ert_gui.widgets.combochoice import ComboChoice from ert_gui.widgets.pathchooser import PathChooser -from ert.enums import history_source_type +from ert.ert.enums import history_source_type from ert_gui.widgets.reloadbutton import ReloadButton def createObservationsPage(configPanel, parent): configPanel.startPage("Observations") r = configPanel.addRow(ComboChoice(parent, history_source_type.values(), "History source", "config/observations/history_source")) - r.initialize = lambda ert : [ert.prototype("int model_config_get_history_source(long)"), - ert.prototype("void model_config_set_history_source(long, int)")] def get_history_source(ert): history_source = ert.enkf.model_config_get_history_source(ert.model_config) @@ -44,9 +42,6 @@ def createObservationsPage(configPanel, parent): r = configPanel.addRow(PathChooser(parent, "Observations config", "config/observations/obs_config", True)) - r.initialize = lambda ert : [ert.prototype("long enkf_main_get_obs(long)"), - ert.prototype("char* enkf_obs_get_config_file(long)"), - ert.prototype("void enkf_main_load_obs(long, char*)")] def get_obs(ert): obs = ert.enkf.enkf_main_get_obs(ert.main) @@ -61,7 +56,6 @@ def createObservationsPage(configPanel, parent): r = configPanel.addRow(ReloadButton(parent, "Reload Observations", "config/observations/reload_observation", "Reload")) - r.initialize = lambda ert : [ert.prototype("void enkf_main_reload_obs(long)")] r.getter = lambda ert : ert.enkf.enkf_main_reload_obs(ert.main) diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/parameters/datapanel.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/parameters/datapanel.py index 90e79683bc..3c7ba91618 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/parameters/datapanel.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/parameters/datapanel.py @@ -20,7 +20,7 @@ from ert_gui.widgets.combochoice import ComboChoice from ert_gui.widgets.stringbox import DoubleBox from ert_gui.widgets.pathchooser import PathChooser from parametermodels import DataModel -import ert.enums as enums +import ert.ert.enums as enums import ert_gui.widgets.helpedwidget class DataPanel(QtGui.QFrame): diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/parameters/fieldpanel.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/parameters/fieldpanel.py index b5a25b3ed9..6120bc5575 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/parameters/fieldpanel.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/parameters/fieldpanel.py @@ -20,7 +20,7 @@ from ert_gui.widgets.combochoice import ComboChoice from ert_gui.widgets.stringbox import DoubleBox from ert_gui.widgets.pathchooser import PathChooser from parametermodels import FieldModel -from ert.enums import field_type +from ert.ert.enums import field_type from ert_gui.widgets.helpedwidget import ContentModel class FieldPanel(QtGui.QFrame): diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/parameters/parametermodels.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/parameters/parametermodels.py index e5cfc9afde..69e6876e08 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/parameters/parametermodels.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/parameters/parametermodels.py @@ -15,7 +15,7 @@ # for more details. -from ert.enums import enkf_impl_type, field_type +from ert.ert.enums import enkf_impl_type, field_type from PyQt4.QtCore import QObject from PyQt4.Qt import SIGNAL diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/plot.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/plot.py index 1476286ac0..268e8d4391 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/plot.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/plot.py @@ -22,50 +22,35 @@ from ert_gui.widgets.pathchooser import PathChooser from ert_gui.widgets.combochoice import ComboChoice from ert_gui.widgets.spinnerwidgets import IntegerSpinner -import ert.ertwrapper as ertwrapper def createPlotPage(configPanel, parent): configPanel.startPage("Plot") r = configPanel.addRow(PathChooser(parent, "Output path", "config/plot/path")) - r.initialize = lambda ert : [ert.prototype("char* plot_config_get_path(long)"), - ert.prototype("void plot_config_set_path(long, char*)")] r.getter = lambda ert : ert.enkf.plot_config_get_path(ert.plot_config) r.setter = lambda ert, value : ert.enkf.plot_config_set_path(ert.plot_config, str(value)) r = configPanel.addRow(ComboChoice(parent, ["PLPLOT", "TEXT"], "Driver", "config/plot/plot_driver")) - r.initialize = lambda ert : [ert.prototype("char* plot_config_get_driver(long)"), - ert.prototype("void plot_config_set_driver(long, char*)")] r.getter = lambda ert : ert.enkf.plot_config_get_driver(ert.plot_config) r.setter = lambda ert, value : ert.enkf.plot_config_set_driver(ert.plot_config, str(value)) r = configPanel.addRow(IntegerSpinner(parent, "Errorbar max", "config/plot/plot_errorbar_max", 1, 10000000)) - r.initialize = lambda ert : [ert.prototype("int plot_config_get_errorbar_max(long)"), - ert.prototype("void plot_config_set_errorbar_max(long, int)")] r.getter = lambda ert : ert.enkf.plot_config_get_errorbar_max(ert.plot_config) r.setter = lambda ert, value : ert.enkf.plot_config_set_errorbar_max(ert.plot_config, value) r = configPanel.addRow(IntegerSpinner(parent, "Width", "config/plot/width", 1, 10000)) - r.initialize = lambda ert : [ert.prototype("int plot_config_get_width(long)"), - ert.prototype("void plot_config_set_width(long, int)")] r.getter = lambda ert : ert.enkf.plot_config_get_width(ert.plot_config) r.setter = lambda ert, value : ert.enkf.plot_config_set_width(ert.plot_config, value) r = configPanel.addRow(IntegerSpinner(parent, "Height", "config/plot/plot_height", 1, 10000)) - r.initialize = lambda ert : [ert.prototype("int plot_config_get_height(long)"), - ert.prototype("void plot_config_set_height(long, int)")] r.getter = lambda ert : ert.enkf.plot_config_get_height(ert.plot_config) r.setter = lambda ert, value : ert.enkf.plot_config_set_height(ert.plot_config, value) r = configPanel.addRow(PathChooser(parent, "Image Viewer", "config/plot/image_viewer", True)) - r.initialize = lambda ert : [ert.prototype("char* plot_config_get_viewer(long)"), - ert.prototype("void plot_config_set_viewer(long, char*)")] r.getter = lambda ert : ert.enkf.plot_config_get_viewer(ert.plot_config) r.setter = lambda ert, value : ert.enkf.plot_config_set_viewer(ert.plot_config, str(value)) r = configPanel.addRow(ComboChoice(parent, ["bmp", "jpg", "png", "tif"], "Image type", "config/plot/image_type")) - r.initialize = lambda ert : [ert.prototype("char* plot_config_get_image_type(long)"), - ert.prototype("void plot_config_set_image_type(long, char*)")] r.getter = lambda ert : ert.enkf.plot_config_get_image_type(ert.plot_config) r.setter = lambda ert, value : ert.enkf.plot_config_set_image_type(ert.plot_config, str(value)) diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/queuesystem.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/queuesystem.py index f024cf463d..9f82da1f5e 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/queuesystem.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/queuesystem.py @@ -20,7 +20,6 @@ # ---------------------------------------------------------------------------------------------- from ert_gui.widgets.configpanel import ConfigPanel from ert_gui.widgets.combochoice import ComboChoice -import ert.ertwrapper as ertwrapper from ert_gui.widgets.stringbox import StringBox from ert_gui.widgets.pathchooser import PathChooser from ert_gui.widgets.spinnerwidgets import IntegerSpinner @@ -30,8 +29,6 @@ def createQueueSystemPage(configPanel, parent): configPanel.startPage("Queue System") r = configPanel.addRow(ComboChoice(parent, ["LSF", "RSH", "LOCAL"], "Queue system", "config/queue_system/queue_system")) - r.initialize = lambda ert : [ert.prototype("char* site_config_get_queue_name(long)"), - ert.prototype("void site_config_set_job_queue(long, char*)")] r.getter = lambda ert : ert.enkf.site_config_get_queue_name(ert.site_config) r.setter = lambda ert, value : ert.enkf.site_config_set_job_queue(ert.site_config, str(value)) @@ -40,20 +37,14 @@ def createQueueSystemPage(configPanel, parent): internalPanel.startPage("LSF") r = internalPanel.addRow(StringBox(parent, "LSF Queue", "config/queue_system/lsf_queue")) - r.initialize = lambda ert : [ert.prototype("char* site_config_get_lsf_queue(long)"), - ert.prototype("void site_config_set_lsf_queue(long, char*)")] r.getter = lambda ert : ert.enkf.site_config_get_lsf_queue(ert.site_config) r.setter = lambda ert, value : ert.enkf.site_config_set_lsf_queue(ert.site_config, str(value)) r = internalPanel.addRow(IntegerSpinner(parent, "Max running", "config/queue_system/max_running_lsf", 1, 1000)) - r.initialize = lambda ert : [ert.prototype("int site_config_get_max_running_lsf(long)"), - ert.prototype("void site_config_set_max_running_lsf(long, int)")] r.getter = lambda ert : ert.enkf.site_config_get_max_running_lsf(ert.site_config) r.setter = lambda ert, value : ert.enkf.site_config_set_max_running_lsf(ert.site_config, value) r = internalPanel.addRow(StringBox(parent, "Resources", "config/queue_system/lsf_resources")) - r.initialize = lambda ert : [ert.prototype("char* site_config_get_lsf_request(long)"), - ert.prototype("void site_config_set_lsf_request(long, char*)")] r.getter = lambda ert : ert.enkf.site_config_get_lsf_request(ert.site_config) r.setter = lambda ert, value : ert.enkf.site_config_set_lsf_request(ert.site_config, str(value)) @@ -63,22 +54,15 @@ def createQueueSystemPage(configPanel, parent): internalPanel.startPage("RSH") r = internalPanel.addRow(PathChooser(parent, "Command", "config/queue_system/rsh_command", show_files=True, must_exist=True, is_executable_file=True)) - r.initialize = lambda ert : [ert.prototype("char* site_config_get_rsh_command(long)"), - ert.prototype("void site_config_set_rsh_command(long, char*)")] r.getter = lambda ert : ert.enkf.site_config_get_rsh_command(ert.site_config) r.setter = lambda ert, value : ert.enkf.site_config_set_rsh_command(ert.site_config, str(value)) r = internalPanel.addRow(IntegerSpinner(parent, "Max running", "config/queue_system/max_running_rsh", 1, 1000)) - r.initialize = lambda ert : [ert.prototype("int site_config_get_max_running_rsh(long)"), - ert.prototype("void site_config_set_max_running_rsh(long, int)")] r.getter = lambda ert : ert.enkf.site_config_get_max_running_rsh(ert.site_config) r.setter = lambda ert, value : ert.enkf.site_config_set_max_running_rsh(ert.site_config, value) r = internalPanel.addRow(KeywordTable(parent, "Host List", "config/queue_system/rsh_host_list", "Host", "Number of jobs")) - r.initialize = lambda ert : [ert.prototype("long site_config_get_rsh_host_list(long)"), - ert.prototype("void site_config_clear_rsh_host_list(long)"), - ert.prototype("void site_config_add_rsh_host(long, char*, int)")] r.getter = lambda ert : ert.getHash(ert.enkf.site_config_get_rsh_host_list(ert.site_config), True) def add_rsh_host(ert, listOfKeywords): @@ -100,8 +84,6 @@ def createQueueSystemPage(configPanel, parent): internalPanel.startPage("LOCAL") r = internalPanel.addRow(IntegerSpinner(parent, "Max running", "config/queue_system/max_running_local", 1, 1000)) - r.initialize = lambda ert : [ert.prototype("int site_config_get_max_running_local(long)"), - ert.prototype("void site_config_set_max_running_local(long, int)")] r.getter = lambda ert : ert.enkf.site_config_get_max_running_local(ert.site_config) r.setter = lambda ert, value : ert.enkf.site_config_set_max_running_local(ert.site_config, value) diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/simulation.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/simulation.py index 8013e26d55..db12479cca 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/simulation.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/simulation.py @@ -20,7 +20,6 @@ # ---------------------------------------------------------------------------------------------- from PyQt4 import QtCore from ert_gui.widgets.spinnerwidgets import IntegerSpinner -import ert.ertwrapper as ertwrapper from ert_gui.widgets.tablewidgets import KeywordTable from ert_gui.widgets.pathchooser import PathChooser from ert_gui.widgets.checkbox import CheckBox @@ -28,7 +27,7 @@ from ert_gui.widgets.configpanel import ConfigPanel from ert_gui.widgets.stringbox import StringBox from jobs.forwardmodelpanel import ForwardModelPanel from simulations.runpathpanel import RunpathMemberList, RunpathMemberPanel -from ert.enums import keep_runpath_type +from ert.ert.enums import keep_runpath_type from simulations.runtemplatepanel import RunTemplatePanel import ert_gui.widgets.helpedwidget import os @@ -38,29 +37,17 @@ def createSimulationsPage(configPanel, parent): r = configPanel.addRow(IntegerSpinner(parent, "Max submit", "config/simulation/max_submit", 1, 10000)) - r.initialize = lambda ert : [ert.prototype("int site_config_get_max_submit(long)"), - ert.prototype("void site_config_set_max_submit(long, int)")] r.getter = lambda ert : ert.enkf.site_config_get_max_submit(ert.site_config) r.setter = lambda ert, value : ert.enkf.site_config_set_max_submit(ert.site_config, value) r = configPanel.addRow(IntegerSpinner(parent, "Max resample", "config/simulation/max_resample", 1, 10000)) - r.initialize = lambda ert : [ert.prototype("int model_config_get_max_resample(long)"), - ert.prototype("void model_config_set_max_resample(long, int)")] r.getter = lambda ert : ert.enkf.model_config_get_max_resample(ert.model_config) r.setter = lambda ert, value : ert.enkf.model_config_set_max_resample(ert.model_config, value) r = configPanel.addRow(ForwardModelPanel(parent)) - r.initialize = lambda ert: [ert.prototype("long model_config_get_forward_model(long)"), - ert.prototype("long site_config_get_installed_jobs(long)"), - ert.prototype("long ext_joblist_alloc_list(long)", lib=ert.job_queue), - ert.prototype("char* ext_job_get_private_args_as_string(long)", lib=ert.job_queue), - ert.prototype("char* ext_job_get_help_text(long)", lib=ert.job_queue), - ert.prototype("void forward_model_clear(long)", lib=ert.job_queue), - ert.prototype("long forward_model_add_job(long, char*)", lib=ert.job_queue), - ert.prototype("void ext_job_set_private_args_from_string(long, char*)", lib=ert.job_queue), - ert.prototype("long forward_model_alloc_joblist(long)", lib=ert.job_queue),] + def get_forward_model(ert): site_config = ert.site_config @@ -106,8 +93,7 @@ def createSimulationsPage(configPanel, parent): r = configPanel.addRow(PathChooser(parent, "Case table", "config/simulation/case_table")) - r.initialize = lambda ert : [ert.prototype("char* model_config_get_case_table_file(long)"), - ert.prototype("void enkf_main_set_case_table(long, char*)")] + def get_case_table(ert): return ert.enkf.model_config_get_case_table_file(ert.model_config) @@ -120,8 +106,6 @@ def createSimulationsPage(configPanel, parent): r = configPanel.addRow(PathChooser(parent, "License path", "config/simulation/license_path")) - r.initialize = lambda ert : [ert.prototype("char* site_config_get_license_root_path(long)"), - ert.prototype("void site_config_set_license_root_path(long, char*)")] r.getter = lambda ert : ert.enkf.site_config_get_license_root_path(ert.site_config) def ls(string): @@ -139,8 +123,6 @@ def createSimulationsPage(configPanel, parent): internalPanel.startPage("Runpath") r = internalPanel.addRow(PathChooser(parent, "Runpath", "config/simulation/runpath", path_format=True)) - r.initialize = lambda ert : [ert.prototype("char* model_config_get_runpath_as_char(long)"), - ert.prototype("void model_config_set_runpath_fmt(long, char*)")] r.getter = lambda ert : ert.enkf.model_config_get_runpath_as_char(ert.model_config) r.setter = lambda ert, value : ert.enkf.model_config_set_runpath_fmt(ert.model_config, str(value)) @@ -148,17 +130,12 @@ def createSimulationsPage(configPanel, parent): r = internalPanel.addRow(CheckBox(parent, "Pre clear", "config/simulation/pre_clear_runpath", "Perform pre clear")) - r.initialize = lambda ert : [ert.prototype("bool enkf_main_get_pre_clear_runpath(long)"), - ert.prototype("void enkf_main_set_pre_clear_runpath(long, bool)")] r.getter = lambda ert : ert.enkf.enkf_main_get_pre_clear_runpath(ert.main) r.setter = lambda ert, value : ert.enkf.enkf_main_set_pre_clear_runpath(ert.main, value) r = internalPanel.addRow(RunpathMemberPanel(widgetLabel="Retain runpath", helpLabel="config/simulation/runpath_retain")) - r.initialize = lambda ert : [ert.prototype("int enkf_main_get_ensemble_size(long)"), - ert.prototype("int enkf_main_iget_keep_runpath(long, int)"), - ert.prototype("void enkf_main_iset_keep_runpath(long, int, long)"),] def get_runpath_retain_state(ert): ensemble_size = ert.enkf.enkf_main_get_ensemble_size(ert.main) @@ -183,23 +160,15 @@ def createSimulationsPage(configPanel, parent): internalPanel.startPage("Run Template") r = internalPanel.addRow(RunTemplatePanel(parent)) - r.initialize = lambda ert : [ert.prototype("long enkf_main_get_templates(long)"), - ert.prototype("long ert_templates_alloc_list(long)"), - ert.prototype("long ert_templates_get_template(long, char*)"), - ert.prototype("char* ert_template_get_template_file(long)"), - ert.prototype("char* ert_template_get_target_file(long)"), - ert.prototype("char* ert_template_get_args_as_string(long)"), - ert.prototype("void ert_templates_clear(long)"), - ert.prototype("void ert_templates_add_template(long, char*, char*, char*, char*)"),] def get_run_templates(ert): templates = ert.enkf.enkf_main_get_templates(ert.main) - template_list = ert.enkf.ert_templates_alloc_list(templates) + template_list = ert.enkf.ert_template_alloc_list(templates) template_names = ert.getStringList(template_list, free_after_use=True) result = [] for name in template_names: - template = ert.enkf.ert_templates_get_template(templates, name) + template = ert.enkf.ert_template_get_template(templates, name) template_file = ert.enkf.ert_template_get_template_file(template) target_file = ert.enkf.ert_template_get_target_file(template) arguments = ert.enkf.ert_template_get_args_as_string(template) @@ -210,10 +179,10 @@ def createSimulationsPage(configPanel, parent): def set_run_templates(ert, template_list): templates_pointer = ert.enkf.enkf_main_get_templates(ert.main) - ert.enkf.ert_templates_clear(templates_pointer) + ert.enkf.ert_template_clear(templates_pointer) for template in template_list: - ert.enkf.ert_templates_add_template(templates_pointer, template[0], template[1], template[2], template[3]) + ert.enkf.ert_template_add_template(templates_pointer, template[0], template[1], template[2], template[3]) r.setter = set_run_templates diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/simulations/runpathpanel.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/simulations/runpathpanel.py index 0aba75f1db..63b8a99a16 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/simulations/runpathpanel.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/simulations/runpathpanel.py @@ -16,7 +16,7 @@ from PyQt4 import QtGui, QtCore -from ert.enums import keep_runpath_type +from ert.ert.enums import keep_runpath_type from ert_gui.widgets.helpedwidget import HelpedWidget from ert_gui.pages.run.legend import Legend diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/systemenv.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/systemenv.py index 2a31ab8a06..e9c4f663d6 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/systemenv.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/config/systemenv.py @@ -21,7 +21,6 @@ from ert_gui.widgets.pathchooser import PathChooser from ert_gui.widgets.configpanel import ConfigPanel from ert_gui.widgets.tablewidgets import KeywordTable, KeywordList -import ert.ertwrapper as ertwrapper from PyQt4 import QtGui, QtCore from jobs.jobspanel import JobsPanel, Job import os @@ -35,15 +34,12 @@ def createSystemPage(configPanel, parent): # the site configuration file; this should only be a label - not # user editable. r = configPanel.addRow(ActiveLabel(None, "Site Config", "", "Not specified.")) - r.initialize = lambda ert: [ert.prototype("char* enkf_main_get_site_config_file(long)")] r.getter = lambda ert : ert.enkf.enkf_main_get_site_config_file(ert.main) r.modelConnect("casesUpdated()", r.fetchContent) r = configPanel.addRow(PathChooser(parent, "Job script", "config/systemenv/job_script", True)) - r.initialize = lambda ert : [ert.prototype("char* site_config_get_job_script(long)"), - ert.prototype("void site_config_set_job_script(long, char*)")] r.getter = lambda ert : ert.enkf.site_config_get_job_script(ert.site_config) r.setter = lambda ert, value : ert.enkf.site_config_set_job_script(ert.site_config, str(value)) @@ -51,9 +47,6 @@ def createSystemPage(configPanel, parent): internalPanel.startPage("setenv") r = internalPanel.addRow(KeywordTable(parent, "", "config/systemenv/setenv")) - r.initialize = lambda ert : [ert.prototype("long site_config_get_env_hash(long)"), - ert.prototype("void site_config_clear_env(long)"), - ert.prototype("void site_config_setenv(long, char*, char*)")] r.getter = lambda ert : ert.getHash(ert.enkf.site_config_get_env_hash(ert.site_config)) def setenv(ert, value): @@ -68,10 +61,6 @@ def createSystemPage(configPanel, parent): internalPanel.startPage("Update path") r = internalPanel.addRow(KeywordTable(parent, "", "config/systemenv/update_path")) - r.initialize = lambda ert : [ert.prototype("long site_config_get_path_variables(long)"), - ert.prototype("long site_config_get_path_values(long)"), - ert.prototype("void site_config_clear_pathvar(long)"), - ert.prototype("void site_config_update_pathvar(long, char*, char*)")] def get_update_path(ert): paths = ert.getStringList(ert.enkf.site_config_get_path_variables(ert.site_config)) values = ert.getStringList(ert.enkf.site_config_get_path_values(ert.site_config)) @@ -94,18 +83,6 @@ def createSystemPage(configPanel, parent): internalPanel.startPage("Jobs") r = internalPanel.addRow(JobsPanel(parent)) - r.initialize = lambda ert : [ert.prototype("long site_config_get_installed_jobs(long)"), - ert.prototype("char* site_config_get_license_root_path(long)"), - ert.prototype("int ext_job_is_private(long)", lib=ert.job_queue), - ert.prototype("char* ext_job_get_config_file(long)", lib=ert.job_queue), - ert.prototype("void ext_job_set_config_file(long, char*)", lib=ert.job_queue), - ert.prototype("long ext_job_alloc(char*, char*, int)", lib=ert.job_queue), - ert.prototype("long ext_job_fscanf_alloc(char*, char*, int, char*)", lib=ert.job_queue), - ert.prototype("long ext_joblist_get_job(long, char*)", lib=ert.job_queue), - ert.prototype("int ext_joblist_del_job(long, char*)", lib=ert.job_queue), - ert.prototype("int ext_joblist_has_job(long, char*)", lib=ert.job_queue), - ert.prototype("void ext_joblist_add_job(long, char*, long)", lib=ert.job_queue), - ert.prototype("long ext_joblist_get_jobs(long)", lib=ert.job_queue)] def get_jobs(ert): jl = ert.enkf.site_config_get_installed_jobs(ert.site_config) h = ert.job_queue.ext_joblist_get_jobs(jl) @@ -169,14 +146,10 @@ def createSystemPage(configPanel, parent): configPanel.addRow(internalPanel) r = configPanel.addRow(PathChooser(parent, "Log file", "config/systemenv/log_file", True)) - r.initialize = lambda ert : [ert.prototype("char* log_get_filename(long)", lib=ert.util), - ert.prototype("void log_reset_filename(long, char*)", lib=ert.util)] r.getter = lambda ert : ert.util.log_get_filename(ert.logh) r.setter = lambda ert, value : ert.util.log_reset_filename(ert.logh, value) r = configPanel.addRow(ert_gui.widgets.spinnerwidgets.IntegerSpinner(parent, "Log level", "config/systemenv/log_level", 0, 1000)) - r.initialize = lambda ert : [ert.prototype("int log_get_level(long)", lib=ert.util), - ert.prototype("void log_set_level(long, int)", lib=ert.util)] r.getter = lambda ert : ert.util.log_get_level(ert.logh) r.setter = lambda ert, value : ert.util.log_set_level(ert.logh, value) diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/init/initandcopy.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/init/initandcopy.py index 2c1272a85a..092c4bd9f0 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/init/initandcopy.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/init/initandcopy.py @@ -16,10 +16,9 @@ from ert_gui.widgets.helpedwidget import HelpedWidget -from ert import ertwrapper from PyQt4 import QtGui, QtCore from ert_gui.widgets.util import resourceIcon, ListCheckPanel, ValidatedTimestepCombo, getItemsFromList -from ert.enums import ert_state_enum +from ert.ert.enums import ert_state_enum class ParametersAndMembers(HelpedWidget): @@ -218,15 +217,6 @@ class ParametersAndMembers(HelpedWidget): def initialize(self, ert): - ert.prototype("long ensemble_config_alloc_keylist_from_var_type(long, int)") - ert.prototype("int enkf_main_initialize_from_scratch(long, long, int, int)") - ert.prototype("int enkf_main_get_ensemble_size(long)") - ert.prototype("long enkf_main_get_fs(long)") - ert.prototype("char* enkf_fs_get_read_dir(long)") - ert.prototype("long enkf_fs_alloc_dirlist(long)") - ert.prototype("int enkf_main_get_history_length(long)") - ert.prototype("void enkf_main_initialize_from_existing__(long, char*, int, int, long, char*, long)") - ert.prototype("void enkf_main_copy_ensemble(long, char*, int, int, char*, int, int, long, char*, long)") self.initialized = True @@ -249,12 +239,12 @@ class ParametersAndMembers(HelpedWidget): members = ert.enkf.enkf_main_get_ensemble_size(ert.main) fs = ert.enkf.enkf_main_get_fs(ert.main) - currentCase = ert.enkf.enkf_fs_get_read_dir(fs) - - caseList = ert.enkf.enkf_fs_alloc_dirlist(fs) - list = ert.getStringList(caseList) - ert.freeStringList(caseList) + currentCase = "default" #ert.enkf.enkf_fs_get_read_dir(fs) + #caseList = ert.enkf.enkf_fs_alloc_dirlist(fs) + #list = ert.getStringList(caseList) + #ert.freeStringList(caseList) + list = ["default"] historyLength = ert.enkf.enkf_main_get_history_length(ert.main) return {"parameters" : parameters, diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/init/initpanel.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/init/initpanel.py index ed8382f392..67289b9da6 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/init/initpanel.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/init/initpanel.py @@ -18,7 +18,7 @@ from PyQt4 import QtGui, QtCore from ert_gui.widgets.tablewidgets import KeywordList from ert_gui.widgets.validateddialog import ValidatedDialog -import ert.ertwrapper as ertwrapper +import ert.ert.ertwrapper as ertwrapper from ert_gui.widgets.combochoice import ComboChoice @@ -43,10 +43,10 @@ class InitPanel(QtGui.QFrame): def get_case_list(ert): fs = ert.enkf.enkf_main_get_fs(ert.main) - caseList = ert.enkf.enkf_fs_alloc_dirlist(fs) + caseList = ["default"] #ert.enkf.enkf_fs_alloc_dirlist(fs) - list = ert.getStringList(caseList) - ert.freeStringList(caseList) + list = caseList #ert.getStringList(caseList) + #ert.freeStringList(caseList) return list self.get_case_list = get_case_list # convenience: used by several functions @@ -104,9 +104,6 @@ class InitPanel(QtGui.QFrame): def initialize_cases(ert): ert.prototype("long enkf_main_get_fs(long)") - ert.prototype("char* enkf_fs_get_read_dir(long)") - ert.prototype("void enkf_fs_select_read_dir(long, char*)") - ert.prototype("void enkf_fs_select_write_dir(long, char*, bool)") self.currentCase.updateList(self.get_case_list(ert)) @@ -114,7 +111,8 @@ class InitPanel(QtGui.QFrame): def get_current_case(ert): fs = ert.enkf.enkf_main_get_fs(ert.main) - currentCase = ert.enkf.enkf_fs_get_read_dir(fs) + tmp = self.get_case_list(ert) + currentCase = tmp[0] #ert.enkf.enkf_fs_get_read_dir(fs) #print "The selected case is: " + currentCase return currentCase diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/ensemblefetcher.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/ensemblefetcher.py index 49d5ccb6a4..5e366ad39d 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/ensemblefetcher.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/ensemblefetcher.py @@ -18,11 +18,11 @@ from fetcher import PlotDataFetcherHandler from ert_gui.pages.config.parameters.parametermodels import FieldModel, SummaryModel, KeywordModel, DataModel -import ert.ertwrapper as ertwrapper -import ert.enums as enums +import ert.ert.ertwrapper as ertwrapper +import ert.ert.enums as enums from PyQt4.QtGui import QWidget, QFormLayout, QSpinBox, QComboBox from PyQt4.QtCore import SIGNAL -from ert.erttypes import time_t +from ert.ert.erttypes import time_t import numpy class EnsembleFetcher(PlotDataFetcherHandler): @@ -45,8 +45,7 @@ class EnsembleFetcher(PlotDataFetcherHandler): self.connect(self.data_configuration, SIGNAL('configurationChanged()'), emitter) def initialize(self, ert): - ert.prototype("long ensemble_config_get_node(long, char*)") - ert.prototype("bool ensemble_config_has_key(long, char*)") + ert.prototype("long enkf_main_get_fs(long)") ert.prototype("int enkf_main_get_ensemble_size(long)") diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotdata.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotdata.py index 4b9c2cc6b4..d5c9670b3a 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotdata.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotdata.py @@ -15,15 +15,14 @@ # for more details. -from ert.erttypes import time_t +from ert.ert.erttypes import time_t from ert_gui.widgets.helpedwidget import ContentModel from ert_gui.widgets.util import print_timing, resourceIcon from ert_gui.pages.config.parameters.parametermodels import DataModel, KeywordModel, FieldModel, SummaryModel from ert_gui.pages.config.parameters.parameterpanel import Parameter -import ert.ertwrapper as ertwrapper -import ert.enums as enums +import ert.ert.enums as enums import sys -from ert.enums import obs_impl_type +from ert.ert.enums import obs_impl_type from ensemblefetcher import EnsembleFetcher from rftfetcher import RFTFetcher @@ -232,8 +231,6 @@ class PlotContextDataFetcher(ContentModel): ContentModel.__init__(self) def initialize(self, ert): - ert.prototype("long ensemble_config_alloc_keylist(long)") - ert.prototype("long ensemble_config_get_node(long, char*)") ert.prototype("long enkf_config_node_get_impl_type(long)") ert.prototype("long enkf_config_node_get_ref(long)") @@ -299,11 +296,12 @@ class PlotContextDataFetcher(ContentModel): data.errorbar_max = ert.enkf.plot_config_get_errorbar_max(ert.plot_config) fs = ert.enkf.enkf_main_get_fs(ert.main) - current_case = ert.enkf.enkf_fs_get_read_dir(fs) + current_case = "default" #ert.enkf.enkf_fs_get_read_dir(fs) data.plot_config_path = ert.enkf.plot_config_get_path(ert.plot_config) - data.plot_path = ert.enkf.plot_config_get_path(ert.plot_config) + "/" + current_case - + #data.plot_path = ert.enkf.plot_config_get_path(ert.plot_config) + "/" + current_case + data.plot_path = "PLOTXXX" + enkf_obs = ert.enkf.enkf_main_get_obs(ert.main) key_list = ert.enkf.enkf_obs_alloc_typed_keylist(enkf_obs, obs_impl_type.FIELD_OBS.value()) field_obs = ert.getStringList(key_list, free_after_use=True) @@ -313,10 +311,11 @@ class PlotContextDataFetcher(ContentModel): data.parameters.append(p) - case_list_pointer = ert.enkf.enkf_fs_alloc_dirlist(fs) - case_list = ert.getStringList(case_list_pointer) + #case_list_pointer = ert.enkf.enkf_fs_alloc_dirlist(fs) + #case_list = ert.getStringList(case_list_pointer) + case_list = ["default"] data.current_case = current_case - ert.freeStringList(case_list_pointer) + #ert.freeStringList(case_list_pointer) for case in case_list: data.case_list.append(case) diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotfigure.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotfigure.py index 189d7b4de1..9221f08117 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotfigure.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotfigure.py @@ -20,7 +20,7 @@ import matplotlib.lines import matplotlib.text import numpy -import ert.erttypes as erttypes +import ert.ert.erttypes as erttypes import plotsettings from plotrenderer import DefaultPlotRenderer diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotgenerator.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotgenerator.py index 1387a6440d..8c6e7d0aab 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotgenerator.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotgenerator.py @@ -26,7 +26,7 @@ from plotsettingsxml import PlotSettingsLoader from plotsettings import PlotSettings from plotdata import PlotContextDataFetcher, PlotDataFetcher from ert_gui.pages.config.parameters.parametermodels import SummaryModel, KeywordModel -import ert.enums as enums +import ert.ert.enums as enums class PlotGenerator(QFrame): diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotpanel.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotpanel.py index a98922b91f..c2b23c770b 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotpanel.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotpanel.py @@ -18,7 +18,6 @@ from PyQt4 import QtGui, QtCore from ert_gui.pages.config.parameters.parameterpanel import Parameter from ert_gui.pages.plot.plotview import PlotView -import ert.ertwrapper as ertwrapper import ert_gui.pages.config.parameters.parameterpanel import ert_gui.widgets.helpedwidget from ert_gui.widgets.helpedwidget import ContentModel @@ -36,7 +35,7 @@ from plotconfig import PlotConfigPanel from PyQt4.QtGui import QTabWidget, QFormLayout, QFrame, QVBoxLayout, QHBoxLayout, QCheckBox, QPushButton, QToolButton, QMainWindow from PyQt4.QtGui import QCalendarWidget import plotsettings -import ert.erttypes as erttypes +import ert.ert.erttypes as erttypes class PlotPanel(QtGui.QWidget): def __init__(self): diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotrenderer.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotrenderer.py index c307baacf3..41f43338fd 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotrenderer.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotrenderer.py @@ -16,7 +16,7 @@ from matplotlib.dates import AutoDateLocator, datetime, matplotlib -import ert.erttypes as erttypes +import ert.ert.erttypes as erttypes class PlotRenderer: """An abstract plotter that plots data""" diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotsettings.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotsettings.py index 2f51b61fce..4b58fb0587 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotsettings.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotsettings.py @@ -17,7 +17,7 @@ from plotconfig import PlotConfig import matplotlib -from ert.erttypes import time_t +from ert.ert.erttypes import time_t import datetime from PyQt4.QtCore import QObject, SIGNAL diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotview.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotview.py index a21b30f730..5f74965471 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotview.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/plotview.py @@ -19,7 +19,7 @@ from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas import datetime import time -from ert.erttypes import time_t +from ert.ert.erttypes import time_t from ert_gui.widgets.util import print_timing from plotdata import PlotData diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/rftfetcher.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/rftfetcher.py index d9983491e8..08d1da4521 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/rftfetcher.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/plot/rftfetcher.py @@ -16,10 +16,10 @@ from fetcher import PlotDataFetcherHandler -import ert.ertwrapper as ertwrapper -import ert.enums as enums +import ert.ert.ertwrapper as ertwrapper +import ert.ert.enums as enums import plotdata -from ert.enums import ert_state_enum, obs_impl_type +from ert.ert.enums import ert_state_enum, obs_impl_type import numpy class RFTFetcher(PlotDataFetcherHandler): @@ -45,7 +45,6 @@ class RFTFetcher(PlotDataFetcherHandler): ert.prototype("int obs_vector_get_num_active(long)") ert.prototype("bool obs_vector_iget_active(long, int)") - ert.prototype("long ensemble_config_get_node(long, char*)") ert.prototype("long enkf_config_node_get_ref(long)") ert.prototype("int* field_obs_get_i(long)") diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/run/runpanel.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/run/runpanel.py index d2b8a9adde..dfc44d7eb0 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/run/runpanel.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/run/runpanel.py @@ -16,7 +16,6 @@ from PyQt4 import QtGui, QtCore -from ert import ertwrapper from ert_gui.widgets.helpedwidget import HelpedWidget, ContentModel from ert_gui.widgets.util import resourceIcon, ListCheckPanel, ValidatedTimestepCombo, createSpace, getItemsFromList, frange diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/run/simulation.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/run/simulation.py index 332f9b56df..25b3b57d70 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/run/simulation.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/run/simulation.py @@ -19,8 +19,7 @@ from __future__ import division from PyQt4 import QtGui, QtCore from ert_gui.widgets.util import resourceIcon, resourceStateIcon, shortTime import time -import ert.ertwrapper as ertwrapper -from ert.enums import ert_job_status_type +from ert.ert.enums import ert_job_status_type class SimulationList(QtGui.QListWidget): diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/run/simulationsdialog.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/run/simulationsdialog.py index 6095c91c91..9f41bd57b6 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/run/simulationsdialog.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/pages/run/simulationsdialog.py @@ -22,9 +22,8 @@ from simulation import SimulationItemDelegate, SimulationList, SimulationItem, S import threading import time -import ert.ertwrapper as ertwrapper from ert_gui.widgets.util import getItemsFromList -from ert.enums import ert_job_status_type +from ert.ert.enums import ert_job_status_type from PyQt4.QtGui import QApplication class SimulationsDialog(QtGui.QDialog): diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/widgets/helpedwidget.py b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/widgets/helpedwidget.py index e0b6f082b5..ce46086536 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/widgets/helpedwidget.py +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert_gui/widgets/helpedwidget.py @@ -20,7 +20,7 @@ import help import sys from util import resourceIcon, resourceImage import inspect -import ert.enums as enums +import ert.ert.enums as enums def abstract(): """Abstract keyword that indicate an abstract function""" diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/CMakeLists.txt b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/CMakeLists.txt index 3525d95cf8..c6391119d3 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/CMakeLists.txt @@ -4,7 +4,7 @@ include_directories( ${PLPLOT_HEADER} ) set( SITE_CONFIG_FILE /project/res/etc/ERT/site-config CACHE FILEPATH "Path to global ERT Configuration file") set( src_list main.c enkf_tui_main.c enkf_tui_fs.c enkf_tui_ranking.c enkf_tui_misc.c enkf_tui_table.c enkf_tui_plot.c enkf_tui_plot_rft.c enkf_tui_plot_util.c - enkf_tui_run.c enkf_tui_util.c enkf_tui_init.c enkf_tui_export.c enkf_tui_analysis.c enkf_tui_QC.c enkf_tui_help.c enkf_tui_simple.c ert_tui_jobs.c) + enkf_tui_run.c enkf_tui_util.c enkf_tui_init.c enkf_tui_export.c enkf_tui_analysis.c enkf_tui_QC.c enkf_tui_help.c enkf_tui_simple.c ert_tui_jobs.c enkf_tui_workflow.c) #exec_program( svnversion ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE SVN_VERSION) #exec_program( date OUTPUT_VARIABLE COMPILE_TIME_STAMP) @@ -38,8 +38,11 @@ else() set (destination ${CMAKE_INSTALL_PREFIX}/bin) endif() -install(TARGETS ert DESTINATION ${destination}) -if (INSTALL_GROUP) - install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/ert)") - install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/ert)") + +if (INSTALL_ERT) + install(TARGETS ert DESTINATION ${destination}) + if (INSTALL_GROUP) + install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/ert)") + install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/ert)") + endif() endif() diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_QC.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_QC.c index 4430ae126f..a0eaab0505 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_QC.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_QC.c @@ -56,6 +56,7 @@ #include #include + void enkf_tui_QC_plot_get_PC( enkf_main_type * enkf_main , int step1 , int step2 , state_enum state , const local_obsset_type * obsset , double truncation , int ncomp , matrix_type * PC , matrix_type * PC_obs) { @@ -109,6 +110,7 @@ void enkf_tui_QC_plot_get_PC( enkf_main_type * enkf_main , int step1 , int step2 } + void enkf_tui_QC_plot_PC( void * arg ) { enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); local_config_type * local_config = enkf_main_get_local_config( enkf_main ); @@ -189,6 +191,14 @@ void enkf_tui_QC_plot_PC( void * arg ) { } +void enkf_tui_QC_run_workflow( void * arg ) { + enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); + qc_module_type * qc_module = enkf_main_get_qc_module( enkf_main ); + + qc_module_run_workflow( qc_module , enkf_main ); +} + + void enkf_tui_QC_menu(void * arg) { @@ -201,7 +211,15 @@ void enkf_tui_QC_menu(void * arg) { { menu_type * menu = menu_alloc("Quality check of prior" , "Back" , "bB"); - menu_add_item(menu , "Plot of prior principal components" , "pP" , enkf_tui_QC_plot_PC , enkf_main , NULL); + menu_item_type * plot_PC_item = menu_add_item( menu , "Plot of prior principal components" , "pP" , enkf_tui_QC_plot_PC , enkf_main , NULL); + menu_item_type * run_QC_workflow_item = menu_add_item( menu , "Run QC workflow" , "rR" , enkf_tui_QC_run_workflow , enkf_main , NULL); + + if (!enkf_main_have_obs( enkf_main )) + menu_item_disable( plot_PC_item ); + + if (!enkf_main_has_QC_workflow( enkf_main )) + menu_item_disable( run_QC_workflow_item ); + menu_run(menu); menu_free(menu); } diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_export.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_export.c index 3434eb8b59..17d88f2a8f 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_export.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_export.c @@ -417,79 +417,6 @@ void enkf_tui_export_time(void * enkf_main) { } -void enkf_tui_export_python_module(void * arg ) { - enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); - const ensemble_config_type * ensemble_config = enkf_main_get_ensemble_config(enkf_main); - const int ens_size = enkf_main_get_ensemble_size( enkf_main ); - enkf_fs_type * fs = enkf_main_get_fs(enkf_main); - char ** kw_list; - char * keyword_string; - char * step_string; - char * module_name; - char * module_file; - int * step_list; - int num_step , num_kw; - - util_printf_prompt("Keywords to export" , PROMPT_LEN , '=' , "=> "); - keyword_string = util_alloc_stdin_line(); - util_printf_prompt("Timesteps to export" , PROMPT_LEN , '=' , "=> "); - step_string = util_alloc_stdin_line(); - util_printf_prompt("Name of python module" , PROMPT_LEN , '=' , "=> "); - module_name = util_alloc_stdin_line(); - module_file = util_alloc_sprintf("%s.py" , module_name ); - step_list = util_sscanf_alloc_active_list( step_string , &num_step ); - util_split_string( keyword_string , " " , &num_kw , &kw_list); - { - FILE * stream = util_fopen(module_file , "w"); - int ikw; - fprintf(stream , "data = ["); - for (ikw = 0; ikw < num_kw; ikw++) { - char * index_key; - const enkf_config_node_type * config_node = ensemble_config_user_get_node( ensemble_config , kw_list[ikw] , &index_key); - if (config_node == NULL) - fprintf(stderr,"Warning: could not locate node: %s \n", kw_list[ikw]); - else { - enkf_node_type * node = enkf_node_alloc( config_node ); - node_id_type node_id; - - node_id.state = FORECAST; - for (int istep = 0; istep < num_step; istep++) { - node_id.report_step = istep; - int step = step_list[istep]; - fprintf(stream , "(\"%s\" , %d , [" , kw_list[ikw] , step); - for (int iens = 0; iens < ens_size; iens++) { - double value; - node_id.iens = iens; - enkf_node_user_get( node , fs , index_key , node_id , &value); - - fprintf(stream , "%g " , value); - if (iens < (ens_size -1 )) - fprintf(stream , ","); - else - fprintf(stream , "]"); - - } - if ((istep == (num_step - 1)) && (ikw == (num_kw - 1))) - fprintf(stream , ")]"); - else - fprintf(stream , "),\n"); - } - free(index_key); - enkf_node_free( node ); - } - } - fclose(stream); - } - - - util_free_stringlist( kw_list , num_kw ); - free(module_name); - free(module_file); - free( step_list ); - free( step_string ); - free( keyword_string ); -} - /*****************************************************************/ void enkf_tui_export_fieldP(void * arg) { @@ -773,8 +700,6 @@ void enkf_tui_export_menu(void * arg) { menu_add_separator(menu); menu_add_item(menu , "Export P( a =< x < b )" , "sS" , enkf_tui_export_fieldP , enkf_main , NULL); menu_add_separator(menu); - menu_add_item(menu , "Export Python module of" , "yY" , enkf_tui_export_python_module , enkf_main , NULL); - menu_add_separator(menu); menu_add_item(menu , "Export cell values to text file(s)" , "cC" , enkf_tui_export_cell , enkf_main , NULL); menu_add_item(menu , "Export line profile of a field to text file(s)" , "pP" , enkf_tui_export_profile , enkf_main , NULL); menu_add_item(menu , "Export time development in one cell to text file(s)" , "tT" , enkf_tui_export_time , enkf_main , NULL); diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_init.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_init.c index 4f4eb68df8..3e936e9be5 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_init.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_init.c @@ -45,6 +45,7 @@ void enkf_tui_init(enkf_main_type * enkf_main, bool all_members , bool all_param const ensemble_config_type * ensemble_config = enkf_main_get_ensemble_config(enkf_main); int ens_size = enkf_main_get_ensemble_size( enkf_main ); int iens1, iens2; + bool force_init = true; bool iens_valid = false; /* iens2 should be interpreted as __inclusive__ */ @@ -89,7 +90,7 @@ void enkf_tui_init(enkf_main_type * enkf_main, bool all_members , bool all_param } if (param_list != NULL) { - enkf_main_initialize_from_scratch(enkf_main , param_list , iens1 , iens2); + enkf_main_initialize_from_scratch(enkf_main , param_list , iens1 , iens2 , force_init); stringlist_free( param_list ); } } diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_main.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_main.c index 335777710a..3743bbe61f 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_main.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_main.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -57,12 +58,13 @@ void enkf_tui_main_menu(enkf_main_type * enkf_main) { menu_add_item(menu , "Manage cases" , "cC" , enkf_tui_fs_menu , enkf_main , NULL); menu_add_item(menu , "Run, restart or analyse experiment" , "rR" , enkf_tui_run_menu , enkf_main , NULL); - menu_add_item(menu , "Prior quality check" , "uU" , enkf_tui_QC_menu , enkf_main , NULL); + menu_add_item(menu , "Quality check" , "uU" , enkf_tui_QC_menu , enkf_main , NULL); menu_add_item(menu , "Plot results" , "pP" , enkf_tui_plot_menu , enkf_main , NULL); menu_add_item(menu , "Rank results" , "aA" , enkf_tui_ranking_menu , enkf_main , NULL); menu_add_item(menu , "Export data to other formats" , "eE" , enkf_tui_export_menu , enkf_main , NULL); menu_add_item(menu , "Table of results" , "tT" , enkf_tui_table_menu , enkf_main , NULL); menu_add_item(menu , "Miscellanous" , "mM" , enkf_tui_misc_menu , enkf_main , NULL); + menu_add_item(menu , "Workflows" , "wW" , enkf_tui_workflow_menu , enkf_main , NULL); menu_add_item(menu , "Help" , "hH" , enkf_tui_help_menu_main , enkf_main , NULL); menu_add_item(menu , "Simple menu" , "sS" , enkf_tui_simple_menu , enkf_main , NULL); menu_run(menu); diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_misc.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_misc.c index d03a71af36..790cbe26da 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_misc.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_misc.c @@ -15,13 +15,12 @@ See the GNU General Public License at for more details. */ +#include +#include #include #include -#include -#include - #include #include #include diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_plot.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_plot.c index 74886e4ff7..46bd5acdd7 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_plot.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_plot.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -74,6 +75,7 @@ base_name: The filename of the current plot. */ +#define NUM_REFCASE_POINTS 75 static void __plot_add_data(plot_type * plot , const char * label , int N , const double * x , const double *y) { @@ -122,14 +124,14 @@ void enkf_tui_plot_PC( enkf_main_type * enkf_main , const char * plot_name , con -static void enkf_tui_plot_ensemble__(enkf_main_type * enkf_main , - const enkf_config_node_type * config_node , - const char * user_key , - const char * key_index , - int step1 , int step2 , - bool prediction_mode , - int iens1 , int iens2 , - state_enum plot_state) { +void enkf_tui_plot_ensemble__(enkf_main_type * enkf_main , + const enkf_config_node_type * config_node , + const char * user_key , + const char * key_index , + int step1 , int step2 , + bool prediction_mode , + int iens1 , int iens2 , + state_enum plot_state) { enkf_fs_type * fs = enkf_main_get_fs(enkf_main); enkf_obs_type * enkf_obs = enkf_main_get_obs( enkf_main ); @@ -137,10 +139,10 @@ static void enkf_tui_plot_ensemble__(enkf_main_type * enkf_main , bool plot_dates = true; const int errorbar_max_obsnr = plot_config_get_errorbar_max( plot_config ); - const char * data_file = plot_config_get_plot_refcase( plot_config ); const bool plot_errorbars = plot_config_get_plot_errorbar( plot_config ); const bool add_observations = true; const bool logy = plot_config_get_logy( plot_config ); + const bool plot_refcase = plot_config_get_plot_refcase( plot_config ); bool show_plot = false; char * plot_file = enkf_tui_plot_alloc_plot_file( plot_config , enkf_main_get_current_fs( enkf_main ), user_key ); time_map_type * time_map = enkf_fs_get_time_map( fs ); @@ -149,8 +151,7 @@ static void enkf_tui_plot_ensemble__(enkf_main_type * enkf_main , msg_type * msg; bool_vector_type * has_data = bool_vector_alloc( 0 , false ); int iens , step; - bool plot_refcase = true; - + /* { enkf_plot_data_type * plot_data = enkf_main_alloc_plot_data( enkf_main ); @@ -164,10 +165,8 @@ static void enkf_tui_plot_ensemble__(enkf_main_type * enkf_main , enkf_plot_data_free( plot_data ); } */ - - if ( strcmp( data_file , "" ) == 0) - plot_refcase = false; + if (plot_dates) plot = enkf_tui_plot_alloc(plot_config , "" , /* y akse */ "" ,user_key,plot_file); else @@ -423,46 +422,41 @@ static void enkf_tui_plot_ensemble__(enkf_main_type * enkf_main , double_vector_free( obs_value ); } } - /*REFCASE PLOTTING*/ - if(plot_refcase){ - if( util_file_exists( data_file )){ - double_vector_type * refcase_value = double_vector_alloc( 0 , 0 ); - double_vector_type * refcase_time = double_vector_alloc( 0 , 0 ); - plot_dataset_type * d = plot_alloc_new_dataset( plot ,"refcase" , PLOT_XY ); - plot_dataset_set_style( d , LINE ); - plot_dataset_set_line_color( d , RED); - char *base; - char *header_file; - stringlist_type * summary_file_list = stringlist_alloc_new(); - char *path; - ecl_sum_type *ecl_sum; - util_alloc_file_components( data_file , &path , &base , NULL ); - ecl_util_alloc_summary_files( path , base , NULL , &header_file , summary_file_list); - ecl_sum = ecl_sum_fread_alloc( header_file , summary_file_list , ":" ); - for ( int i = 0; i < double_vector_size(x); i++ ){ - time_t sim_time = ( time_t ) double_vector_iget( x , i ); - if( ecl_sum_has_general_var( ecl_sum , user_key ) && ecl_sum_check_sim_time( ecl_sum , sim_time)){ - double_vector_append( refcase_value , ecl_sum_get_general_var_from_sim_time( ecl_sum, sim_time , user_key)); - double_vector_append( refcase_time , sim_time ); + /*REFCASE PLOTTING*/ + + if (plot_refcase && time_map_get_size( time_map) ) { + ecl_config_type * ecl_config = enkf_main_get_ecl_config( enkf_main ); + ecl_refcase_list_type * refcase_list = ecl_config_get_refcase_list( ecl_config ); + int num_refcase = ecl_refcase_list_get_size( refcase_list ); + + for( int iref=0; iref < num_refcase; iref++) { + ecl_sum_type * refcase = ecl_refcase_list_iget_case( refcase_list , iref ); + if ( ecl_sum_has_general_var( refcase , user_key)) { + char * refcase_label = util_alloc_sprintf("Refcase%d" , iref); + plot_dataset_type * d = plot_alloc_new_dataset( plot , refcase_label , PLOT_XY ); + int color_nr = iref % (PLOT_NUM_COLORS - 1) + 1; // Color_nr == 0 is white; we skip that. + + plot_dataset_set_style( d , LINE ); + plot_dataset_set_line_color( d , color_nr ); + plot_dataset_set_line_width(d , 2.0 ); + + for ( int i = 0; i < time_map_get_size( time_map ); i++ ){ + time_t sim_time = ( time_t ) time_map_iget( time_map , i ); + if (ecl_sum_check_sim_time( refcase , sim_time)) { + double days = ecl_sum_time2days( refcase , sim_time ); + double value = ecl_sum_get_general_var_from_sim_time( refcase , sim_time , user_key); + + if (plot_dates) + plot_dataset_append_point_xy( d , sim_time , value); + else + plot_dataset_append_point_xy( d , days , value); + } } + + free( refcase_label ); } - - util_safe_free(header_file); - util_safe_free(base); - util_safe_free(path); - ecl_sum_free(ecl_sum); - - for (int i = 0; i < double_vector_size( refcase_time ); i++) { - double days = double_vector_iget( refcase_time , i); - double value = double_vector_iget( refcase_value , i); - plot_dataset_append_point_xy( d , days , value); - } - double_vector_free( refcase_value ); - double_vector_free( refcase_time ); } - else - printf("\nCannot find refcase data file: \n%s\n", data_file); } double_vector_free( x ); @@ -479,7 +473,6 @@ static void enkf_tui_plot_ensemble__(enkf_main_type * enkf_main , printf( "No data to plot for:%s \n" , user_key); plot_free( plot ); } - free( plot_file ); bool_vector_free( has_data ); } @@ -753,6 +746,7 @@ static void * enkf_tui_plot_ensemble_mt( void * void_arg ) { } + void enkf_tui_plot_all_summary__( enkf_main_type * enkf_main , int iens1 , int iens2 , int step1 , int step2 , bool prediction_mode) { /* This code is prepared for multithreaded creation of plots; @@ -805,10 +799,9 @@ void enkf_tui_plot_all_summary__( enkf_main_type * enkf_main , int iens1 , int i + void enkf_tui_plot_all_summary(void * arg) { enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); - const ensemble_config_type * ensemble_config = enkf_main_get_ensemble_config(enkf_main); - const plot_config_type * plot_config = enkf_main_get_plot_config( enkf_main ); int iens1 , iens2 , step1 , step2; bool prediction_mode; @@ -822,12 +815,14 @@ void enkf_tui_plot_all_summary(void * arg) { if(step1 != -2) step2 = enkf_tui_util_scanf_int_with_default_return_to_menu( "Stop plotting at report step [Enter: default: everything] (M: return to menu)" , PROMPT_LEN , &prediction_mode); } + if (step1 != -2 && step2 != -2){ enkf_tui_util_scanf_iens_range("Realizations members to plot(0 - %d) [default: all]" , enkf_main_get_ensemble_size( enkf_main ) , PROMPT_LEN , &iens1 , &iens2); - enkf_tui_plot_all_summary__( enkf_main , iens1 , iens2 , step1 , step2 , prediction_mode); + enkf_tui_plot_all_summary__( enkf_main , iens1 , iens2 , step1 , step2 , prediction_mode ); } } - + + diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_plot.h b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_plot.h index dfc4954689..52c5391c33 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_plot.h +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_plot.h @@ -29,4 +29,13 @@ void enkf_tui_plot_menu(void * ); void enkf_tui_plot_PC( enkf_main_type * enkf_main , const char * plot_name , const matrix_type * PC , const matrix_type * PC_obs); void enkf_tui_plot_reports(void *); void enkf_tui_plot_all_summary__( enkf_main_type * enkf_main , int iens1 , int iens2 , int step1 , int step2 , bool prediction_mode); + +void enkf_tui_plot_ensemble__(enkf_main_type * enkf_main , + const enkf_config_node_type * config_node , + const char * user_key , + const char * key_index , + int step1 , int step2 , + bool prediction_mode , + int iens1 , int iens2 , + state_enum plot_state); #endif diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_plot_rft.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_plot_rft.c index 20cd1ffe19..9b4940b319 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_plot_rft.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_plot_rft.c @@ -215,166 +215,173 @@ void enkf_tui_plot_RFTS__(enkf_main_type * enkf_main , void enkf_tui_plot_RFT_simIn(enkf_main_type * enkf_main, path_fmt_type * runpathformat, const path_fmt_type * caseformat, char * wellname , time_t recording_time, bool isMD){ - const int ens_size = enkf_main_get_ensemble_size( enkf_main ); - const plot_config_type * plot_config = enkf_main_get_plot_config( enkf_main ); - const char * data_file = plot_config_get_plot_refcase( plot_config ); - bool plot_refcase = true; - if ( strcmp( data_file , "" ) == 0) - plot_refcase = false; - /* - Start by reading RFT measurment - */ - double_vector_type * UTM_x = double_vector_alloc( 0 , 0); - double_vector_type * UTM_y = double_vector_alloc( 0 , 0); - double_vector_type * MD = double_vector_alloc( 0 , 0); - double_vector_type * TVD_z = double_vector_alloc( 0 , 0); - double_vector_type * RFT_obs = double_vector_alloc( 0 , 0); - int lines = enkf_tui_plot_read_rft_obs(enkf_main, wellname, UTM_x, UTM_y, MD, TVD_z, RFT_obs); - /* - Find ijk-list - */ - char * caseending = path_fmt_alloc_path(caseformat, false, 0); //Use the grid in ensmember 0 - char * casename = path_fmt_alloc_file(runpathformat , false, 0, caseending); - ecl_grid_type * grid = ecl_grid_load_case( casename ); - int_vector_type * i_values = int_vector_alloc( lines , 0 ); - int_vector_type * j_values = int_vector_alloc( lines , 0 ); - int_vector_type * k_values = int_vector_alloc( lines , 0 ); - int_vector_type * active = int_vector_alloc( lines , 0 ); - for (int nobs =0; nobs -1){ - int cell_index = ecl_rft_node_lookup_ijk( rft_refcase_node , int_vector_iget(i_values,nobs), int_vector_iget(j_values,nobs),int_vector_iget(k_values,nobs) ); //lookup cell - if(cell_index > -1){ - double pressure_value = ecl_rft_node_iget_pressure( rft_refcase_node , cell_index); // Pressure - double_vector_append(RFT_refcase, pressure_value); - bool_vector_append(refcase_has_data, true); - } - else{ - double_vector_append(RFT_refcase, 0.0); - bool_vector_append(refcase_has_data, false); - } - } - else { + ecl_grid_free(grid); + + /* + Find refcase rfts + */ + double_vector_type * RFT_refcase = double_vector_alloc( 0 , 0); + bool_vector_type * refcase_has_data = bool_vector_alloc(0, false); + const char * refcase_file_name = ecl_rft_file_alloc_case_filename( ecl_sum_get_case( refcase )); + + if (refcase_file_name == NULL){ + if( plot_refcase ) + util_abort("%s: Cannot find eclipse RFT file",__func__ , refcase_file_name); + + } + ecl_rft_file_type * rft_refcase_file = ecl_rft_file_alloc( refcase_file_name ); + if (refcase_file_name == NULL){ + if( plot_refcase ) + util_abort("%s: Cannot find eclipse RFT file",__func__ , refcase_file_name); + + } + const ecl_rft_node_type * rft_refcase_node = ecl_rft_file_get_well_time_rft( rft_refcase_file , wellname , recording_time); + if(rft_refcase_node == NULL){ + if( plot_refcase ) + printf("No RFT information exists for %s in refcase.\n", wellname); + + for( int nobs = 0; nobs < lines; nobs++){ double_vector_append(RFT_refcase, 0.0); bool_vector_append(refcase_has_data, false); } } - } - ecl_rft_file_free(rft_refcase_file); - /* - Get the simulated RFTs - */ - vector_type * pressure_container = vector_alloc_new(); - vector_type * has_data_container = vector_alloc_new(); - char * caseending1 = path_fmt_alloc_path(caseformat, false, 0); - char * casename1 = path_fmt_alloc_file(runpathformat , false, 0, caseending1); - const char * case_file_name1 = ecl_rft_file_alloc_case_filename(casename1 ); - bool eclipse_rft_exists = false; - if (case_file_name1 == NULL){ - util_abort("%s: Cannot find eclipse RFT file",__func__ , case_file_name1); - } - else{ - eclipse_rft_exists = true; - for (int iens = 0; iens -1){ - int cell_index = ecl_rft_node_lookup_ijk( rftnode , int_vector_iget(i_values,nobs), int_vector_iget(j_values,nobs),int_vector_iget(k_values,nobs) ); //lookup cell - double pressure_value = ecl_rft_node_iget_pressure( rftnode , cell_index); // Pressure - double_vector_iset(simulated_pressures,nobs , pressure_value); - if(cell_index > -1) - bool_vector_iset(has_data, nobs, true); - else - bool_vector_iset(has_data, nobs, false); + else{ + for( int nobs = 0; nobs < lines; nobs++){ + if( int_vector_iget(active,nobs) > -1){ + int cell_index = ecl_rft_node_lookup_ijk( rft_refcase_node , + int_vector_iget(i_values,nobs) , + int_vector_iget(j_values,nobs) , + int_vector_iget(k_values,nobs) ); //lookup cell + + if(cell_index > -1){ + double pressure_value = ecl_rft_node_iget_pressure( rft_refcase_node , cell_index); // Pressure + double_vector_append(RFT_refcase, pressure_value); + bool_vector_append(refcase_has_data, true); } - else { - double_vector_iset(simulated_pressures,nobs ,0.0); - bool_vector_iset(has_data, nobs, false); + else{ + double_vector_append(RFT_refcase, 0.0); + bool_vector_append(refcase_has_data, false); } } + else { + double_vector_append(RFT_refcase, 0.0); + bool_vector_append(refcase_has_data, false); + } } - ecl_rft_file_free(rftfile); - vector_append_owned_ref( pressure_container , simulated_pressures , double_vector_free__ ); - vector_append_owned_ref( has_data_container , has_data , bool_vector_free__ ); } + ecl_rft_file_free(rft_refcase_file); + /* + Get the simulated RFTs + */ + vector_type * pressure_container = vector_alloc_new(); + vector_type * has_data_container = vector_alloc_new(); + char * caseending1 = path_fmt_alloc_path(caseformat, false, 0); + char * casename1 = path_fmt_alloc_file(runpathformat , false, 0, caseending1); + const char * case_file_name1 = ecl_rft_file_alloc_case_filename(casename1 ); + bool eclipse_rft_exists = false; + if (case_file_name1 == NULL){ + util_abort("%s: Cannot find eclipse RFT file",__func__ , case_file_name1); + } + else{ + eclipse_rft_exists = true; + for (int iens = 0; iens -1){ + int cell_index = ecl_rft_node_lookup_ijk( rftnode , int_vector_iget(i_values,nobs), int_vector_iget(j_values,nobs),int_vector_iget(k_values,nobs) ); //lookup cell + double pressure_value = ecl_rft_node_iget_pressure( rftnode , cell_index); // Pressure + double_vector_iset(simulated_pressures,nobs , pressure_value); + if(cell_index > -1) + bool_vector_iset(has_data, nobs, true); + else + bool_vector_iset(has_data, nobs, false); + } + else { + double_vector_iset(simulated_pressures,nobs ,0.0); + bool_vector_iset(has_data, nobs, false); + } + } + } + ecl_rft_file_free(rftfile); + vector_append_owned_ref( pressure_container , simulated_pressures , double_vector_free__ ); + vector_append_owned_ref( has_data_container , has_data , bool_vector_free__ ); + } + } + /* + Do the actual plotting + */ + if(isMD) + enkf_tui_plot_RFTS__( enkf_main , wellname , MD, RFT_obs, RFT_refcase, refcase_has_data, pressure_container, active, eclipse_rft_exists, has_data_container, isMD); + else + enkf_tui_plot_RFTS__( enkf_main , wellname , TVD_z, RFT_obs, RFT_refcase, refcase_has_data, pressure_container, active, eclipse_rft_exists, has_data_container, isMD); + double_vector_free( UTM_x ); + double_vector_free( UTM_y ); + double_vector_free( MD ); + double_vector_free( TVD_z ); + double_vector_free( RFT_obs ); + double_vector_free( RFT_refcase ); + bool_vector_free( refcase_has_data ); + vector_free( pressure_container ); + vector_free( has_data_container ); + free( caseending ); + free( caseending1 ); + free( casename ); + free( casename1 ); + int_vector_free( i_values ); + int_vector_free( j_values ); + int_vector_free( k_values ); + int_vector_free( active ); } - /* - Do the actual plotting - */ - if(isMD) - enkf_tui_plot_RFTS__( enkf_main , wellname , MD, RFT_obs, RFT_refcase, refcase_has_data, pressure_container, active, eclipse_rft_exists, has_data_container, isMD); - else - enkf_tui_plot_RFTS__( enkf_main , wellname , TVD_z, RFT_obs, RFT_refcase, refcase_has_data, pressure_container, active, eclipse_rft_exists, has_data_container, isMD); - double_vector_free( UTM_x ); - double_vector_free( UTM_y ); - double_vector_free( MD ); - double_vector_free( TVD_z ); - double_vector_free( RFT_obs ); - double_vector_free( RFT_refcase ); - bool_vector_free( refcase_has_data ); - vector_free( pressure_container ); - vector_free( has_data_container ); - free( caseending ); - free( caseending1 ); - free( casename ); - free( casename1 ); - int_vector_free( i_values ); - int_vector_free( j_values ); - int_vector_free( k_values ); - int_vector_free( active ); -}; +} int enkf_tui_plot_read_rft_config(const char * rft_config_file, stringlist_type * wellnames, time_t_vector_type * dates){ diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_ranking.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_ranking.c index 0c63082b8d..d6d2a36423 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_ranking.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_ranking.c @@ -107,14 +107,13 @@ static void enkf_tui_ranking_create_data__( void * arg , bool sort_increasing) { ranking_table_type * ranking_table = enkf_main_get_ranking_table( enkf_main ); enkf_fs_type * fs = enkf_main_get_fs( enkf_main ); ensemble_config_type * ensemble_config = enkf_main_get_ensemble_config( enkf_main ); - //const int history_length = enkf_main_get_history_length( enkf_main ); + time_map_type * time_map = enkf_fs_get_time_map( fs ); const int prompt_len = 60; const char * prompt1 = "Data key to use for ranking"; - const char * prompt2 = "Report step of data"; + const char * prompt2 = "Report step of data [Blank: last step]"; const char * ranking_name = "Name of new ranking"; const char * store_prompt = "Name of file to store ranking [Blank - no store]"; - int step; state_enum state = FORECAST; char * user_key; @@ -123,26 +122,32 @@ static void enkf_tui_ranking_create_data__( void * arg , bool sort_increasing) { if (user_key != NULL) { util_printf_prompt( prompt2 , prompt_len , '=' , "=> "); { - char * step_char = util_alloc_stdin_line(); - if (step_char == NULL) - step = 0; - else { - if (util_sscanf_int( step_char , &step )) { - const enkf_config_node_type * config_node; - char * key_index; - config_node = ensemble_config_user_get_node( ensemble_config , user_key , &key_index); - if (config_node) { - util_printf_prompt(ranking_name , prompt_len , '=' , "=> "); - char * ranking_key = util_alloc_stdin_line(); - if (ranking_key != NULL) { - ranking_table_add_data_ranking( ranking_table , sort_increasing , ranking_key , user_key , key_index , fs , config_node, step , state ); - ranking_table_display_ranking( ranking_table , ranking_key ); - } - util_safe_free( ranking_key ); - } + int step = -1; + { + char * step_char = util_alloc_stdin_line(); + + if (step_char == NULL) + step = time_map_get_last_step( time_map ); + else { + util_sscanf_int( step_char , &step ); + free( step_char ); + } + } + + if (step >= 0) { + const enkf_config_node_type * config_node; + char * key_index; + config_node = ensemble_config_user_get_node( ensemble_config , user_key , &key_index); + if (config_node) { + util_printf_prompt(ranking_name , prompt_len , '=' , "=> "); + char * ranking_key = util_alloc_stdin_line(); + if (ranking_key != NULL) { + ranking_table_add_data_ranking( ranking_table , sort_increasing , ranking_key , user_key , key_index , fs , config_node, step , state ); + ranking_table_display_ranking( ranking_table , ranking_key ); + } + util_safe_free( ranking_key ); } } - util_safe_free( step_char ); } } util_safe_free( user_key ); diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_run.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_run.c index c3578336e3..13dcaafe40 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_run.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_run.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,8 @@ #include #include #include +#include +#include #include #include @@ -42,7 +45,7 @@ #include /* -Set runpath runtime - disabled. + Set runpath runtime - disabled. static void enkf_tui_run_set_runpath(void * arg) { arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); @@ -112,6 +115,7 @@ void enkf_tui_run_smoother(void * arg) { } + void enkf_tui_run_iterated_ES(void * enkf_main) { const int ens_size = enkf_main_get_ensemble_size( enkf_main ); const int last_report = enkf_main_get_history_length( enkf_main ); @@ -120,13 +124,14 @@ void enkf_tui_run_iterated_ES(void * enkf_main) { model_config_type * model_config = enkf_main_get_model_config( enkf_main ); const ecl_config_type * ecl_config = enkf_main_get_ecl_config( enkf_main ); const analysis_config_type * analysis_config = enkf_main_get_analysis_config( enkf_main ); + analysis_iter_config_type * iter_config = analysis_config_get_iter_config( analysis_config ); analysis_module_type * module = analysis_config_get_active_module( analysis_config ); int step1 = 0; int step2 ; int_vector_type * step_list = int_vector_alloc(0,0); bool_vector_type * iactive = bool_vector_alloc(0 , true); int iter = 0; - int num_iter = 16; + int num_iter = analysis_iter_config_get_num_iterations( iter_config ); stringlist_type * node_list = ensemble_config_alloc_keylist_from_var_type( enkf_main_get_ensemble_config(enkf_main) , PARAMETER ); if (ecl_config_has_schedule( ecl_config )) @@ -141,24 +146,25 @@ void enkf_tui_run_iterated_ES(void * enkf_main) { bool_vector_iset( iactive , ens_size - 1 , true ); while (true) { - /* { - char * user = getenv("USER"); - char * runpath_fmt = util_alloc_sprintf("/scratch/ert/%s/iteratedES/%d/run%%d" , user , iter); - model_config_set_runpath_fmt( model_config , runpath_fmt ); - free( runpath_fmt ); - } - */ - - char * target_fs_name = util_alloc_sprintf("smoother-%d" , iter); - enkf_fs_type * target_fs = enkf_main_get_alt_fs(enkf_main , target_fs_name , false , true ); - enkf_main_run_exp(enkf_main , iactive , step1 , step1 , FORECAST); - enkf_main_smoother_update(enkf_main , step_list , target_fs); { - - + const char * runpath_fmt = analysis_iter_config_iget_runpath_fmt( iter_config , iter); + if (runpath_fmt != NULL) { + char * runpath_key = util_alloc_sprintf( "runpath-%d" , iter); + model_config_add_runpath( model_config , runpath_key , runpath_fmt); + model_config_select_runpath( model_config , runpath_key ); + free( runpath_key ); + } + } + + enkf_main_run_exp(enkf_main , iactive , true , step1 , step1 , FORECAST); + { + char * target_fs_name = analysis_iter_config_iget_case( iter_config , iter ); + enkf_fs_type * target_fs = enkf_main_get_alt_fs(enkf_main , target_fs_name , false , true ); + enkf_main_smoother_update(enkf_main , step_list , target_fs); + enkf_main_copy_ensemble( enkf_main , enkf_main_get_current_fs( enkf_main ), - step2 , + 0 , // Smoother update will write on step 0 ANALYZED , target_fs, step1 , @@ -167,15 +173,17 @@ void enkf_tui_run_iterated_ES(void * enkf_main) { NULL , node_list ); - enkf_main_select_fs(enkf_main , target_fs ); + + enkf_main_set_fs(enkf_main , target_fs , enkf_fs_get_case_name( target_fs )); + free( target_fs_name ); } - - free( target_fs_name ); - iter= analysis_module_get_int(module, "ITER"); + //iter = analysis_module_get_int(module, "ITER"); + iter++; if (iter == num_iter) break; } int_vector_free( step_list ); + bool_vector_free( iactive ); } } @@ -195,26 +203,27 @@ void enkf_tui_run_iterated_ES(void * enkf_main) { void enkf_tui_run_exp(void * enkf_main) { - const int ens_size = enkf_main_get_ensemble_size( enkf_main ); - bool_vector_type * iactive = bool_vector_alloc(0,true); - bool_vector_iset( iactive , ens_size - 1 , true ); + const int ens_size = enkf_main_get_ensemble_size( enkf_main ); + bool_vector_type * iactive = bool_vector_alloc(0,false); state_enum init_state = ANALYZED; int start_report = 0; int init_step_parameters = 0; - char * select_string; { + char * prompt = util_alloc_sprintf("Which realizations to simulate (Ex: 1,3-5) [M to return to menu] : " , ens_size); + char * select_string; + util_printf_prompt(prompt , PROMPT_LEN , '=' , "=> "); select_string = util_alloc_stdin_line(); - if (select_string != NULL) { - util_sscanf_active_range( select_string , ens_size - 1 , bool_vector_get_ptr( iactive) ); - free( select_string ); - } + enkf_tui_util_sscanf_active_list( iactive , select_string , ens_size); + + util_safe_free( select_string ); free( prompt ); } - enkf_main_run_exp(enkf_main , iactive , init_step_parameters , start_report , init_state); + if (bool_vector_count_equal(iactive , true)) + enkf_main_run_exp(enkf_main , iactive , true , init_step_parameters , start_report , init_state); bool_vector_free(iactive); } @@ -223,10 +232,8 @@ void enkf_tui_run_exp(void * enkf_main) { void enkf_tui_run_create_runpath__(void * __enkf_main) { enkf_main_type * enkf_main = enkf_main_safe_cast(__enkf_main); - const int ens_size = enkf_main_get_ensemble_size( enkf_main ); - bool_vector_type * iactive = bool_vector_alloc(0,true); - bool_vector_iset( iactive , ens_size - 1 , true ); - + const int ens_size = enkf_main_get_ensemble_size( enkf_main ); + bool_vector_type * iactive = bool_vector_alloc(0,false); state_enum init_state = ANALYZED; int start_report = 0; @@ -234,14 +241,15 @@ void enkf_tui_run_create_runpath__(void * __enkf_main) { { char * prompt = util_alloc_sprintf("Which realizations to create[ensemble size:%d] : " , ens_size); char * select_string; + util_printf_prompt(prompt , PROMPT_LEN , '=' , "=> "); select_string = util_alloc_stdin_line(); - util_sscanf_active_range( select_string , ens_size - 1 , bool_vector_get_ptr( iactive) ); + enkf_tui_util_sscanf_active_list( iactive , select_string , ens_size ); + + util_safe_free( select_string ); free( prompt ); - free( select_string ); } - - enkf_main_run_exp(enkf_main , iactive , init_step_parameters , start_report , init_state); + enkf_main_run_exp(enkf_main , iactive , false , init_step_parameters , start_report , init_state); bool_vector_free(iactive); } @@ -259,9 +267,9 @@ void enkf_tui_run_manual_load__( void * arg ) { const int last_report = -1; const int ens_size = enkf_main_get_ensemble_size( enkf_main ); int step1,step2; - bool * iactive = util_calloc(ens_size , sizeof * iactive ); + bool_vector_type * iactive = bool_vector_alloc( 0 , false ); run_mode_type run_mode = ENSEMBLE_EXPERIMENT; - + enkf_main_init_run(enkf_main , run_mode); /* This is ugly */ step1 = 0; @@ -271,15 +279,16 @@ void enkf_tui_run_manual_load__( void * arg ) { char * select_string; util_printf_prompt(prompt , PROMPT_LEN , '=' , "=> "); select_string = util_alloc_stdin_line(); - util_sscanf_active_range( select_string , ens_size - 1 , iactive); + + enkf_tui_util_sscanf_active_list( iactive , select_string , ens_size ); + util_safe_free( select_string ); + free( prompt ); - free( select_string ); } - - { + if (bool_vector_count_equal( iactive , true )) { int iens; arg_pack_type ** arg_list = util_calloc( ens_size , sizeof * arg_list ); thread_pool_type * tp = thread_pool_alloc( 4 , true ); /* num_cpu - HARD coded. */ @@ -288,7 +297,7 @@ void enkf_tui_run_manual_load__( void * arg ) { arg_pack_type * arg_pack = arg_pack_alloc(); arg_list[iens] = arg_pack; - if (iactive[iens]) { + if (bool_vector_iget(iactive , iens)) { enkf_state_type * enkf_state = enkf_main_iget_state( enkf_main , iens ); arg_pack_append_ptr( arg_pack , enkf_state); /* 0: */ @@ -299,15 +308,30 @@ void enkf_tui_run_manual_load__( void * arg ) { arg_pack_append_bool( arg_pack , true ); /* 5: Interactive */ arg_pack_append_owned_ptr( arg_pack , stringlist_alloc_new() , stringlist_free__); /* 6: List of interactive mode messages. */ thread_pool_add_job( tp , enkf_state_internalize_results_mt , arg_pack); + } } thread_pool_join( tp ); thread_pool_free( tp ); printf("\n"); - + + { + qc_module_type * qc_module = enkf_main_get_qc_module( enkf_main ); + runpath_list_type * runpath_list = qc_module_get_runpath_list( qc_module ); + + for (iens = 0; iens < ens_size; iens++) { + if (bool_vector_iget(iactive , iens)) { + const enkf_state_type * state = enkf_main_iget_state( enkf_main , iens ); + runpath_list_add( runpath_list , iens , enkf_state_get_run_path( state ) , enkf_state_get_eclbase( state )); + } + } + + qc_module_export_runpath_list( qc_module ); + } + for (iens = 0; iens < ens_size; iens++) { - if (iactive[iens]) { + if (bool_vector_iget(iactive , iens)) { stringlist_type * msg_list = arg_pack_iget_ptr( arg_list[iens] , 6 ); if (stringlist_get_size( msg_list )) enkf_tui_display_load_msg( iens , msg_list ); @@ -319,18 +343,24 @@ void enkf_tui_run_manual_load__( void * arg ) { arg_pack_free( arg_list[iens]); free( arg_list ); } - free( iactive ); + bool_vector_free( iactive ); } + +/*****************************************************************/ + void enkf_tui_run_menu(void * arg) { enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); + model_config_type * model_config = enkf_main_get_model_config( enkf_main ); + path_fmt_type * runpath_fmt = model_config_get_runpath_fmt( model_config ); menu_type * menu; + { - char * title = util_alloc_sprintf("Run menu [case:%s]" , enkf_main_get_current_fs( enkf_main )); + char * title = util_alloc_sprintf("Run menu [case:%s Runpath:%s]" , enkf_main_get_current_fs( enkf_main ) , path_fmt_get_fmt ( runpath_fmt )); menu = menu_alloc(title , "Back" , "bB"); free(title); } @@ -344,7 +374,7 @@ void enkf_tui_run_menu(void * arg) { menu_item_type * restart_enkf_item = menu_add_item(menu , "Restart EnKF run from arbitrary state" , "rR" , enkf_tui_run_restart__ , enkf_main , NULL); menu_item_type * ES_item = menu_add_item(menu , "Integrated smoother update" , "iI" , enkf_tui_run_smoother , enkf_main , NULL); menu_item_type * it_ES_item = menu_add_item(menu , "Iterated smoother [RML-EnKF]" , "tT" , enkf_tui_run_iterated_ES , enkf_main , NULL); - + if (!ecl_config_has_schedule( ecl_config )) { menu_item_disable( enkf_item ); menu_item_disable( restart_enkf_item ); @@ -357,7 +387,7 @@ void enkf_tui_run_menu(void * arg) { } menu_add_separator(menu); menu_add_item(menu , "Create runpath directories - NO simulation" , "cC" , enkf_tui_run_create_runpath__ , enkf_main , NULL ); - menu_add_item(menu , "Load results manually" , "lL" , enkf_tui_run_manual_load__ , enkf_main , NULL); + menu_add_item(menu , "Load results manually" , "lL" , enkf_tui_run_manual_load__ , enkf_main , NULL); menu_add_separator(menu); { menu_item_type * analysis_item = menu_add_item(menu , "Analysis menu" , "aA" , enkf_tui_analysis_menu , enkf_main , NULL); diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_util.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_util.c index 1ab0aa3592..c529d3b580 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_util.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_util.c @@ -417,6 +417,23 @@ int enkf_tui_util_scanf_int_with_default_return_to_menu(const char * prompt , in return value; } +bool enkf_tui_util_sscanf_active_list( bool_vector_type * iactive , const char * select_string , int ens_size ) { + if (select_string == NULL) { + bool_vector_set_default( iactive , true ); + bool_vector_iset( iactive , ens_size - 1 , true ); + return true; + } else { + bool OK; + OK = string_util_init_active_mask( select_string , iactive ); + + if (bool_vector_size( iactive ) < ens_size) + bool_vector_iset( iactive , ens_size - 1 , false ); + + return OK; + } +} + + /*****************************************************************/ diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_util.h b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_util.h index e443467cb4..8ef31492a5 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_util.h +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_util.h @@ -19,6 +19,7 @@ #ifndef __ENKF_TUI_UTIL_H__ #define __ENKF_TUI_UTIL_H__ +#include #include #include @@ -41,4 +42,6 @@ char * enkf_tui_util_scanf_report_step_as_char(int , cons void enkf_tui_util_msg(const char * , ...); int enkf_tui_util_scanf_int_with_default(const char * prompt , int prompt_len , bool * default_used); int enkf_tui_util_scanf_int_with_default_return_to_menu(const char * prompt , int prompt_len , bool * default_used); + +bool enkf_tui_util_sscanf_active_list( bool_vector_type * iactive , const char * select_string , int ens_size ); #endif diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_workflow.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_workflow.c new file mode 100644 index 0000000000..f05870931b --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_workflow.c @@ -0,0 +1,115 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'enkf_tui_workflow.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +void enkf_tui_workflow_run( void * arg ) { + enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); + { + ert_workflow_list_type * workflow_list = enkf_main_get_workflow_list( enkf_main ); + util_printf_prompt("Name of workflow" , PROMPT_LEN , '=' , "=> "); + { + char * workflow_name = util_alloc_stdin_line(); + if (workflow_name != NULL) { + if (ert_workflow_list_has_workflow( workflow_list , workflow_name )) { + if (!ert_workflow_list_run_workflow( workflow_list , workflow_name , enkf_main )) { + printf("Errors in workflow:%s \n", workflow_name ); + printf("-----------------------------------------------------------------\n"); + config_error_fprintf( ert_workflow_list_get_last_error( workflow_list ) , true , stdout); + printf("-----------------------------------------------------------------\n"); + } + } + } + util_safe_free( workflow_name ); + } + } +} + + +void enkf_tui_workflow_load( void * arg ) { + enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); + { + + } +} + + +void enkf_tui_workflow_list( void * arg ) { + enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); + { + ert_workflow_list_type * workflow_list = enkf_main_get_workflow_list( enkf_main ); + stringlist_type * name_list = ert_workflow_list_alloc_namelist( workflow_list ); + + printf("Available workflows: \n"); + { + int i; + for (i=0; i < stringlist_get_size( name_list ); i++) { + if ((i % 5) == 0) + printf("\n "); + else + printf(" "); + + printf( stringlist_iget( name_list , i )); + } + } + stringlist_free( name_list ); + printf("\n\n"); + } +} + + +void enkf_tui_workflow_menu(void * arg) { + enkf_main_type * enkf_main = enkf_main_safe_cast( arg ); + menu_type * menu = menu_alloc("Workflows" , "Back" , "bB"); + + menu_add_item(menu , "Run workflow" , "rR" , enkf_tui_workflow_run , enkf_main , NULL ); + menu_add_item(menu , "Load workflow" , "lL" , enkf_tui_workflow_load , enkf_main , NULL ); + menu_add_item(menu , "List available workflows" , "iI" , enkf_tui_workflow_list , enkf_main , NULL ); + + menu_add_item(menu , "Help" , "hH" , enkf_tui_help_menu_run , enkf_main , NULL); + menu_run(menu); + menu_free(menu); + +} + diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_workflow.h b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_workflow.h new file mode 100644 index 0000000000..d8d588bef1 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/enkf_tui_workflow.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'enkf_tui_workflow.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + +#ifndef __ENKF_TUI_WORKFLOW_H__ +#define __ENKF_TUI_WORKFLOW_H__ + +void enkf_tui_workflow_menu(void *); + +#endif diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/ert_tui_jobs.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/ert_tui_jobs.c index 3fd94f190e..c23f679a1e 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/ert_tui_jobs.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/ert_tui_jobs.c @@ -19,6 +19,9 @@ #include #include +#include +#include +#include #include @@ -34,3 +37,26 @@ void enkf_tui_plot_all_summary_JOB(void * self , const stringlist_type * args ) enkf_tui_plot_all_summary__( enkf_main , iens1 , iens2 , step1 , step2 , prediction_mode ); } + + +void enkf_tui_plot_JOB(void * self , const stringlist_type * args ) { + enkf_main_type * enkf_main = enkf_main_safe_cast( self ); + enkf_fs_type * enkf_fs = enkf_main_get_fs( enkf_main ); + time_map_type * time_map = enkf_fs_get_time_map( enkf_fs ); + ensemble_config_type * ensemble_config = enkf_main_get_ensemble_config( enkf_main ); + const int step2 = time_map_get_last_step( time_map ); + const int step1 = 0; + int i; + + for (i=0; i < stringlist_get_size( args ); i++) { + const char * user_key = stringlist_iget( args , i ); + char * key_index; + enkf_config_node_type * config_node = ensemble_config_user_get_node( ensemble_config , user_key , &key_index); + if (config_node != NULL) + enkf_tui_plot_ensemble__(enkf_main , config_node , user_key , key_index , step1 , step2 , false , 0 , enkf_main_get_ensemble_size( enkf_main ) , BOTH ); + + util_safe_free( key_index ); + } +} + + diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/main.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/main.c index 81d0eb563e..692c19fb07 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/main.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/main.c @@ -32,6 +32,7 @@ #include #include +#define WORKFLOW_OPTION "-wf" void text_splash() { const int usleep_time = 1000; @@ -51,22 +52,6 @@ void text_splash() { } -void devel_warning() { -#ifdef DEVEL_VERSION - printf("\n"); - printf(" ***************************************************************\n"); - printf(" ** You have started a development version of ERT. If you are **\n"); - printf(" ** not an advanced user, it might be better to use a stable **\n"); - printf(" ** version which has been better tested. The stable version **\n"); - printf(" ** should be available with the command: **\n"); - printf(" ** **\n"); - printf(" ** bash%% ert config_file **\n"); - printf(" ** **\n"); - printf(" ***************************************************************\n"); -#endif -} - - /* GIT_COMMIT and COMPILE_TIME_STAMP are env variables set by the makefile. Will exit if the config file does not exist. @@ -108,7 +93,7 @@ void enkf_usage() { -static void init_debug( const char * executable ) { +static void init_debug( const char * argv0) { char * git_commit = util_alloc_sprintf("git commit...........: %s \n",GIT_COMMIT); char * compile_time = util_alloc_sprintf("Compile time.........: %s \n",COMPILE_TIME_STAMP); @@ -119,39 +104,68 @@ static void init_debug( const char * executable ) { free(git_commit); free(compile_time); - if (executable != NULL) - util_abort_set_executable( executable ); + util_abort_set_executable( argv0 ); } +void parse_workflows(int argc , char ** argv , stringlist_type * workflows) { + bool workflow_on = false; + for (int iarg = 2; iarg < argc; iarg++) { + stringlist_append_copy( workflows , argv[iarg]); + + /*if (strcmp( argv[iarg] , WORKFLOW_OPTION) == 0) + workflow_on = true; + else { + if (workflow_on) + stringlist_append_copy( workflows , argv[iarg]); + else + fprintf(stderr,"**Warning - option:\'%s\' ignored\n",argv[iarg]); + } + */ + } +} + + + int main (int argc , char ** argv) { - devel_warning(); text_splash(); - init_debug( NULL ); + init_debug( argv[0] ); printf("\n"); printf("Documentation : %s \n","http://ert.nr.no"); printf("git commit : %s \n",GIT_COMMIT); printf("compile time : %s \n",COMPILE_TIME_STAMP); - printf("site config : %s \n\n",SITE_CONFIG_FILE); + printf("site config : %s \n",SITE_CONFIG_FILE); + enkf_main_install_SIGNALS(); /* Signals common to both tui and gui. */ signal(SIGINT , util_abort_signal); /* Control C - tui only. */ - if (argc != 2) { + if (argc < 2) { enkf_usage(); exit(1); } else { const char * site_config_file = SITE_CONFIG_FILE; /* The variable SITE_CONFIG_FILE should be defined on compilation ... */ const char * model_config_file = argv[1]; + stringlist_type * workflow_list = stringlist_alloc_new(); + parse_workflows( argc , argv , workflow_list ); + if ( !(util_entry_readable(model_config_file) && util_is_file(model_config_file)) ) + util_exit("Can not read file %s - exiting \n", model_config_file); + + { + char * abs_config = util_alloc_realpath( model_config_file ); + printf("model config : %s \n\n", abs_config); + } enkf_welcome( model_config_file ); { enkf_main_type * enkf_main = enkf_main_bootstrap(site_config_file , model_config_file , true , true); + enkf_main_run_workflows( enkf_main , workflow_list ); enkf_tui_main_menu(enkf_main); enkf_main_free(enkf_main); } - + + stringlist_free( workflow_list ); util_abort_free_version_info(); /* No fucking leaks ... */ } - + exit(0); } diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/upgrade_fs104.c b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/upgrade_fs104.c index 08920c4627..0a96b2a825 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_tui/upgrade_fs104.c +++ b/ThirdParty/Ert/devel/libenkf/applications/ert_tui/upgrade_fs104.c @@ -268,7 +268,11 @@ int main (int argc , char ** argv) { ecl_sum_type * refcase; { config_type * config = create_config(); - config_parse( config , model_config_file , "--" , "INCLUDE" , "DEFINE" , false , true ); + if (!config_parse( config , model_config_file , "--" , "INCLUDE" , "DEFINE" , CONFIG_UNRECOGNIZED_IGNORE , true )) { + config_fprintf_erors( config , stderr ); + exit(1); + } + { char * path; util_alloc_file_components(model_config_file , &path , NULL , NULL); diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/analysis_config.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/analysis_config.h index 86ea068d98..1ece2b5665 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/analysis_config.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/analysis_config.h @@ -20,6 +20,10 @@ #ifndef __ANALYSIS_CONFIG_H__ #define __ANALYSIS_CONFIG_H__ +#ifdef __cplusplus +extern "C" { +#endif + #include #include @@ -30,12 +34,14 @@ #include #include - +#include typedef struct analysis_config_struct analysis_config_type; + +analysis_iter_config_type * analysis_config_get_iter_config( const analysis_config_type * config ); analysis_module_type * analysis_config_get_module( analysis_config_type * config , const char * module_name ); void analysis_config_load_internal_modules( analysis_config_type * analysis ); void analysis_config_reload_module( analysis_config_type * config , const char * module_name); @@ -91,6 +97,8 @@ const char * analysis_config_get_PC_filename( const analysis_config_ty void analysis_config_set_PC_path( analysis_config_type * config , const char * path ); const char * analysis_config_get_PC_path( const analysis_config_type * config ); - +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/analysis_iter_config.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/analysis_iter_config.h new file mode 100644 index 0000000000..27541c6b01 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/analysis_iter_config.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'analysis_iter_config.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + +#ifndef __ANALYSIS_ITER_CONFIG_H__ +#define __ANALYSIS_ITER_CONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct analysis_iter_config_struct analysis_iter_config_type; + + void analysis_iter_config_set_num_iterations( analysis_iter_config_type * config , int num_iterations); + int analysis_iter_config_get_num_iterations( const analysis_iter_config_type * config ); + analysis_iter_config_type * analysis_iter_config_alloc(); + void analysis_iter_config_free( analysis_iter_config_type * config ); + const char * analysis_iter_config_iget_case( analysis_iter_config_type * config , int iter); + const char * analysis_iter_config_iget_runpath_fmt( analysis_iter_config_type * config , int iter); + void analysis_iter_config_add_config_items( config_type * config ); + void analysis_iter_config_init(analysis_iter_config_type * iter_config , const config_type * config); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/config_keys.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/config_keys.h index 8d868b5688..c0f1cf57e5 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/config_keys.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/config_keys.h @@ -45,11 +45,13 @@ extern "C" { #define DEFINE_KEY "DEFINE" #define BASE_SURFACE_KEY "BASE_SURFACE" -#define STORE_SEED_KEY "STORE_SEED" -#define LOAD_SEED_KEY "LOAD_SEED" -#define ENKF_BOOTSTRAP_KEY "ENKF_BOOTSTRAP" -#define ENKF_PEN_PRESS_KEY "ENKF_PEN_PRESS" +#define ADD_FIXED_LENGTH_SCHEDULE_KW_KEY "ADD_FIXED_LENGTH_SCHEDULE_KW" +#define ANALYSIS_COPY_KEY "ANALYSIS_COPY" +#define ANALYSIS_LOAD_KEY "ANALYSIS_LOAD" +#define ANALYSIS_SET_VAR_KEY "ANALYSIS_SET_VAR" +#define ANALYSIS_SELECT_KEY "ANALYSIS_SELECT" #define CASE_TABLE_KEY "CASE_TABLE" +#define CONTAINER_KEY "CONTAINER" #define DATA_FILE_KEY "DATA_FILE" #define DATA_KW_KEY "DATA_KW" #define DBASE_TYPE_KEY "DBASE_TYPE" @@ -57,6 +59,8 @@ extern "C" { #define DELETE_RUNPATH_KEY "DELETE_RUNPATH" #define ECLBASE_KEY "ECLBASE" #define END_DATE_KEY "END_DATE" +#define ENKF_BOOTSTRAP_KEY "ENKF_BOOTSTRAP" +#define ENKF_PEN_PRESS_KEY "ENKF_PEN_PRESS" #define ENKF_ALPHA_KEY "ENKF_ALPHA" #define ENKF_CROSS_VALIDATION_KEY "ENKF_CROSS_VALIDATION" #define ENKF_CV_FOLDS_KEY "ENKF_CV_FOLDS" @@ -73,8 +77,9 @@ extern "C" { #define ENKF_SCHED_FILE_KEY "ENKF_SCHED_FILE" #define ENKF_TRUNCATION_KEY "ENKF_TRUNCATION" #define ENSPATH_KEY "ENSPATH" +#define ITER_CASE_KEY "ITER_CASE" +#define ITER_COUNT_KEY "ITER_COUNT" #define FIELD_KEY "FIELD" -#define SURFACE_KEY "SURFACE" #define FORWARD_MODEL_KEY "FORWARD_MODEL" #define GEN_DATA_KEY "GEN_DATA" #define GEN_KW_KEY "GEN_KW" @@ -83,6 +88,7 @@ extern "C" { #define GRID_KEY "GRID" #define HISTORY_SOURCE_KEY "HISTORY_SOURCE" #define HOSY_TYPE_KEY "HOST_TYPE" +#define IGNORE_SCHEDULE_KEY "IGNORE_SCHEDULE" #define IMAGE_TYPE_KEY "IMAGE_TYPE" #define IMAGE_VIEWER_KEY "IMAGE_VIEWER" #define INIT_SECTION_KEY "INIT_SECTION" @@ -91,8 +97,8 @@ extern "C" { #define JOBNAME_KEY "JOBNAME" #define KEEP_RUNPATH_KEY "KEEP_RUNPATH" #define LICENSE_PATH_KEY "LICENSE_PATH" +#define LOAD_SEED_KEY "LOAD_SEED" #define LOCAL_CONFIG_KEY "LOCAL_CONFIG" -#define ADD_FIXED_LENGTH_SCHEDULE_KW_KEY "ADD_FIXED_LENGTH_SCHEDULE_KW" #define LOG_FILE_KEY "LOG_FILE" #define LOG_LEVEL_KEY "LOG_LEVEL" #define LSF_QUEUE_KEY "LSF_QUEUE" @@ -112,27 +118,32 @@ extern "C" { #define PLOT_HEIGHT_KEY "PLOT_HEIGHT" #define PLOT_PATH_KEY "PLOT_PATH" #define PLOT_REFCASE_KEY "PLOT_REFCASE" +#define PLOT_REFCASE_LIST_KEY "PLOT_REFCASE_LIST" #define PLOT_WIDTH_KEY "PLOT_WIDTH" #define PRE_CLEAR_RUNPATH_KEY "PRE_CLEAR_RUNPATH" #define QUEUE_SYSTEM_KEY "QUEUE_SYSTEM" #define QUEUE_OPTION_KEY "QUEUE_OPTION" #define QC_PATH_KEY "QC_PATH" +#define QC_WORKFLOW_KEY "QC_WORKFLOW" #define REFCASE_KEY "REFCASE" +#define REFCASE_LIST_KEY "REFCASE_LIST" #define REPORT_CONTEXT_KEY "REPORT_CONTEXT" #define REPORT_SEARCH_PATH_KEY "REPORT_SEARCH_PATH" +#define REPORT_LARGE_KEY "REPORT_LARGE" #define REPORT_LIST_KEY "REPORT_LIST" #define REPORT_PATH_KEY "REPORT_PATH" #define REPORT_WELL_LIST_KEY "REPORT_WELL_LIST" #define REPORT_GROUP_LIST_KEY "REPORT_GROUP_LIST" +#define REPORT_TIMEOUT_KEY "REPORT_TIMEOUT" #define RERUN_START_KEY "RERUN_START" #define RSH_COMMAND_KEY "RSH_COMMAND" #define RSH_HOST_KEY "RSH_HOST" #define RUNPATH_KEY "RUNPATH" +#define ITER_RUNPATH_KEY "ITER_RUNPATH" #define RERUN_PATH_KEY "RERUN_PATH" #define RUN_TEMPLATE_KEY "RUN_TEMPLATE" #define RFT_CONFIG_KEY "RFT_CONFIG" #define RFTPATH_KEY "RFTPATH" -#define IGNORE_SCHEDULE_KEY "IGNORE_SCHEDULE" #define SCHEDULE_FILE_KEY "SCHEDULE_FILE" #define SCHEDULE_PREDICTION_FILE_KEY "SCHEDULE_PREDICTION_FILE" #define SCHEDULE_PREDICTION_FILE_KEY "SCHEDULE_PREDICTION_FILE" @@ -143,20 +154,16 @@ extern "C" { #define STATIC_KW_KEY "ADD_STATIC_KW" #define STD_CUTOFF_KEY "STD_CUTOFF" #define SUMMARY_KEY "SUMMARY" -#define CONTAINER_KEY "CONTAINER" -#define UMASK_KEY "UMASK" +#define SURFACE_KEY "SURFACE" #define UPDATE_LOG_PATH_KEY "UPDATE_LOG_PATH" #define UPDATE_PATH_KEY "UPDATE_PATH" #define UPDATE_RESULTS_KEY "UPDATE_RESULTS" #define SINGLE_NODE_UPDATE_KEY "SINGLE_NODE_UPDATE" - -#define ANALYSIS_COPY_KEY "ANALYSIS_COPY" -#define ANALYSIS_LOAD_KEY "ANALYSIS_LOAD" -#define ANALYSIS_SET_VAR_KEY "ANALYSIS_SET_VAR" -#define ANALYSIS_SELECT_KEY "ANALYSIS_SELECT" - - - +#define STORE_SEED_KEY "STORE_SEED" +#define UMASK_KEY "UMASK" +#define WORKFLOW_JOB_DIRECTORY_KEY "WORKFLOW_JOB_DIRECTORY" +#define LOAD_WORKFLOW_KEY "LOAD_WORKFLOW" +#define LOAD_WORKFLOW_JOB_KEY "LOAD_WORKFLOW_JOB" #define CONFIG_BOOL_STRING( var ) (var) ? "TRUE" : "FALSE" diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ecl_config.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ecl_config.h index 770f04fb48..de3c1d08bb 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ecl_config.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ecl_config.h @@ -33,8 +33,11 @@ extern "C" { #include +#include + typedef struct ecl_config_struct ecl_config_type; + void ecl_config_static_kw_init( ecl_config_type * ecl_config , const config_type * config ); bool ecl_config_active( const ecl_config_type * config ); time_t ecl_config_get_end_date( const ecl_config_type * ecl_config ); time_t ecl_config_get_start_date( const ecl_config_type * ecl_config ); @@ -60,6 +63,8 @@ extern "C" { const path_fmt_type * ecl_config_get_eclbase_fmt(const ecl_config_type * ); int ecl_config_get_num_restart_files(const ecl_config_type * ); const ecl_sum_type * ecl_config_get_refcase(const ecl_config_type * ecl_config); + bool ecl_config_has_refcase( const ecl_config_type * ecl_config ); + ecl_refcase_list_type * ecl_config_get_refcase_list( const ecl_config_type * ecl_config ); ecl_grid_type * ecl_config_get_grid(const ecl_config_type * ); void ecl_config_set_grid( ecl_config_type * ecl_config , const char * grid_file ); const char * ecl_config_get_gridfile( const ecl_config_type * ecl_config ); @@ -71,7 +76,7 @@ extern "C" { const char * ecl_config_get_eclbase( const ecl_config_type * ecl_config ); const char * ecl_config_get_schedule_file( const ecl_config_type * ecl_config ); void ecl_config_set_schedule_file( ecl_config_type * ecl_config , const char * schedule_file ); - void ecl_config_load_refcase( ecl_config_type * ecl_config , const char * refcase); + bool ecl_config_load_refcase( ecl_config_type * ecl_config , const char * refcase); const char * ecl_config_get_refcase_name( const ecl_config_type * ecl_config); void ecl_config_clear_static_kw( ecl_config_type * ecl_config ); stringlist_type * ecl_config_get_static_kw_list( const ecl_config_type * ecl_config ); diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ecl_refcase_list.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ecl_refcase_list.h new file mode 100644 index 0000000000..35904f0c0e --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ecl_refcase_list.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_refcase_list.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + + +#ifndef __ECL_REFCASE_LIST_H__ +#define __ECL_REFCASE_LIST_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + + typedef struct ecl_refcase_list_struct ecl_refcase_list_type; + + ecl_refcase_list_type * ecl_refcase_list_alloc( ); + void ecl_refcase_list_free( ecl_refcase_list_type * refcase_list ); + + bool ecl_refcase_list_has_default( ecl_refcase_list_type * refcase_list ); + const ecl_sum_type * ecl_refcase_list_get_default( ecl_refcase_list_type * refcase_list ); + bool ecl_refcase_list_set_default( ecl_refcase_list_type * refcase_list , const char * default_case); + int ecl_refcase_list_get_size(ecl_refcase_list_type * refcase_list ); + int ecl_refcase_list_add_matching( ecl_refcase_list_type * refcase_list , const char * glob_string); + int ecl_refcase_list_add_case( ecl_refcase_list_type * refcase_list , const char * case_name); + const char * ecl_refcase_list_iget_pathcase( ecl_refcase_list_type * refcase_list , int index); + const ecl_sum_type * ecl_refcase_list_iget_case( ecl_refcase_list_type * refcase_list , int index); + const ecl_sum_type * ecl_refcase_list_get_case( ecl_refcase_list_type * refcase_list , const char * case_name); + bool ecl_refcase_list_has_case( ecl_refcase_list_type * refcase_list , const char * case_name); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_defaults.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_defaults.h index 57dac03ab9..3b758cbd09 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_defaults.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_defaults.h @@ -79,7 +79,7 @@ model_config_set_history_source() does currently not handle a default value different from SCHEDULE. */ -#define DEFAULT_HISTORY_SOURCE HISTORY_SOURCE_INVALID +#define DEFAULT_HISTORY_SOURCE REFCASE_HISTORY #define DEFAULT_MAX_SUBMIT 2 /* The number of times to resubmit - default value for config item: MAX_SUBMIT */ @@ -95,36 +95,39 @@ Defaults for the EnKF analysis. The analysis_config object is instantiated with these values. */ -#define DEFAULT_ENKF_MODE ENKF_STANDARD -#define DEFAULT_NCOMP 1 -#define DEFAULT_ENKF_TRUNCATION 0.99 -#define DEFAULT_ENKF_ALPHA 1.50 /* Should be raised ?? */ -#define DEFAULT_ENKF_STD_CUTOFF 1e-6 -#define DEFAULT_MERGE_OBSERVATIONS false -#define DEFAULT_RERUN false -#define DEFAULT_RERUN_START 0 -#define DEFAULT_UPDATE_LOG_PATH "update_log" -#define DEFAULT_CV_NFOLDS 10 -#define DEFAULT_ENKF_SCALING true -#define DEFAULT_ENKF_KERNEL_REG false -#define DEFAULT_ENKF_KERNEL_FUNC 1 /*Default is the Gaussian */ -#define DEFAULT_ENKF_KERNEL_PARAM 1 /*Scale by the maximum value in the distance matrix */ -#define DEFAULT_ENKF_CV false -#define DEFAULT_ENKF_BOOTSTRAP false -#define DEFAULT_ENKF_PEN_PRESS false -#define DEFAULT_ENKF_FORCE_NCOMP false -#define DEFAULT_UPDATE_RESULTS false -#define DEFAULT_SINGLE_NODE_UPDATE true -#define DEFAULT_ANALYSIS_MODULE "STD_ENKF" +#define DEFAULT_ENKF_MODE ENKF_STANDARD +#define DEFAULT_NCOMP 1 +#define DEFAULT_ENKF_TRUNCATION 0.99 +#define DEFAULT_ENKF_ALPHA 1.50 /* Should be raised ?? */ +#define DEFAULT_ENKF_STD_CUTOFF 1e-6 +#define DEFAULT_MERGE_OBSERVATIONS false +#define DEFAULT_RERUN false +#define DEFAULT_RERUN_START 0 +#define DEFAULT_UPDATE_LOG_PATH "update_log" +#define DEFAULT_CV_NFOLDS 10 +#define DEFAULT_ENKF_SCALING true +#define DEFAULT_ENKF_KERNEL_REG false +#define DEFAULT_ENKF_KERNEL_FUNC 1 /*Default is the Gaussian */ +#define DEFAULT_ENKF_KERNEL_PARAM 1 /*Scale by the maximum value in the distance matrix */ +#define DEFAULT_ENKF_CV false +#define DEFAULT_ENKF_BOOTSTRAP false +#define DEFAULT_ENKF_PEN_PRESS false +#define DEFAULT_ENKF_FORCE_NCOMP false +#define DEFAULT_UPDATE_RESULTS false +#define DEFAULT_SINGLE_NODE_UPDATE true +#define DEFAULT_ANALYSIS_MODULE "STD_ENKF" +#define DEFAULT_ANALYSIS_NUM_ITERATIONS 1 /* Default directories. */ -#define DEFAULT_QC_PATH "QC" -#define DEFAULT_REPORT_PATH "reports" -#define DEFAULT_PLOT_PATH "plots" -#define DEFAULT_RUNPATH "simulations/realization%d" -#define DEFAULT_ENSPATH "storage" -#define DEFAULT_RFTPATH "rft" -#define DEFAULT_PLOT_REFCASE "" +#define DEFAULT_QC_PATH "QC" +#define DEFAULT_REPORT_PATH "reports" +#define DEFAULT_PLOT_PATH "plots" +#define DEFAULT_RUNPATH "simulations/realization%d" +#define DEFAULT_ENSPATH "storage" +#define DEFAULT_RFTPATH "rft" +#define DEFAULT_PLOT_REFCASE true +#define DEFAULT_REPORT_LARGE false +#define DEFAULT_REPORT_TIMEOUT 120 #define DEFAULT_PRE_CLEAR_RUNPATH false @@ -144,7 +147,7 @@ #define SUMMARY_KEY_JOIN_STRING ":" #define USER_KEY_JOIN_STRING ":" - +#define DEFAULT_WORKFLOW_VERBOSE false /* Some #define symbols used when saving configuration files. diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_fs.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_fs.h index ef3ffc9932..690e15cce9 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_fs.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_fs.h @@ -37,6 +37,8 @@ extern "C" { #include const char * enkf_fs_get_mount_point( const enkf_fs_type * fs ); + const char * enkf_fs_get_root_path( const enkf_fs_type * fs ); + const char * enkf_fs_get_case_name( const enkf_fs_type * fs ); void enkf_fs_fsync( enkf_fs_type * fs ); enkf_fs_type * enkf_fs_mount(const char * , fs_driver_impl , const char * select_case, bool update_map, bool read_only); diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_main.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_main.h index cf6b5a7060..b82d61d3b7 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_main.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_main.h @@ -56,6 +56,8 @@ extern "C" { #include #include #include +#include +#include /*****************************************************************/ @@ -75,7 +77,7 @@ extern "C" { const char * enkf_main_get_rft_config_file( const enkf_main_type * enkf_main ); bool enkf_main_get_pre_clear_runpath( const enkf_main_type * enkf_main ); void enkf_main_set_pre_clear_runpath( enkf_main_type * enkf_main , bool pre_clear_runpath); - void enkf_main_set_refcase( enkf_main_type * enkf_main , const char * refcase_path); + bool enkf_main_set_refcase( enkf_main_type * enkf_main , const char * refcase_path); ert_report_list_type * enkf_main_get_report_list( const enkf_main_type * enkf_main ); ert_templates_type * enkf_main_get_templates( enkf_main_type * enkf_main ); @@ -98,6 +100,7 @@ extern "C" { void enkf_main_add_well(enkf_main_type * , const char * , int , const char ** ); void enkf_main_analysis(enkf_main_type * ); void enkf_main_free(enkf_main_type * ); + void enkf_main_exit(enkf_main_type * enkf_main); void enkf_main_init_eclipse(enkf_main_type * , int , int ); void enkf_main_init_run( enkf_main_type * enkf_main, run_mode_type run_mode); void enkf_main_load_ecl_init_mt(enkf_main_type * enkf_main , int ); @@ -109,6 +112,7 @@ extern "C" { void enkf_main_run_exp(enkf_main_type * enkf_main , const bool_vector_type * iactive , + bool simulate , int init_step_parameters , int start_report , state_enum start_state); @@ -163,7 +167,7 @@ extern "C" { const char * enkf_main_get_image_viewer(const enkf_main_type * ); const char * enkf_main_get_plot_driver(const enkf_main_type * enkf_main ); const char * enkf_main_get_image_type(const enkf_main_type * enkf_main); - void enkf_main_initialize_from_scratch(enkf_main_type * enkf_main , const stringlist_type * param_list , int iens1 , int iens2); + void enkf_main_initialize_from_scratch(enkf_main_type * enkf_main , const stringlist_type * param_list , int iens1 , int iens2, bool force_init); void enkf_main_initialize_from_existing(enkf_main_type * enkf_main , const char * source_case , @@ -215,7 +219,10 @@ extern "C" { void enkf_main_update_node( enkf_main_type * enkf_main , const char * key ); void enkf_main_fprintf_config( const enkf_main_type * enkf_main ); int_vector_type * enkf_main_update_alloc_step_list( const enkf_main_type * enkf_main , int load_start , int step2 , int stride); - + + const qc_module_type * enkf_main_get_qc_module( const enkf_main_type * enkf_main ); + bool enkf_main_has_QC_workflow( const enkf_main_type * enkf_main ); + void enkf_main_get_PC( const enkf_main_type * enkf_main , const matrix_type * S, const matrix_type * dObs, @@ -230,6 +237,14 @@ extern "C" { void enkf_main_set_verbose( enkf_main_type * enkf_main , bool verbose); bool enkf_main_get_verbose( const enkf_main_type * enkf_main ); + ert_workflow_list_type * enkf_main_get_workflow_list( enkf_main_type * enkf_main ); + void enkf_main_run_workflows( enkf_main_type * enkf_main , const stringlist_type * workflows); + bool enkf_main_run_workflow( enkf_main_type * enkf_main , const char * workflow); + + enkf_main_type * enkf_main_alloc_empty( ); + + rng_config_type * enkf_main_get_rng_config( const enkf_main_type * enkf_main ); + UTIL_SAFE_CAST_HEADER(enkf_main); #ifdef __cplusplus diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_obs.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_obs.h index 2b714fa247..02bbbb1ed9 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_obs.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_obs.h @@ -40,19 +40,22 @@ extern "C" { bool enkf_obs_have_obs( const enkf_obs_type * enkf_obs ); const char * enkf_obs_get_config_file( const enkf_obs_type * enkf_obs); - enkf_obs_type * enkf_obs_alloc( const history_type * hist, double std_cutoff ); + enkf_obs_type * enkf_obs_alloc( ); void enkf_obs_free( enkf_obs_type * enkf_obs); obs_vector_type * enkf_obs_get_vector(const enkf_obs_type * , const char * ); void enkf_obs_load(enkf_obs_type * enkf_obs, + const history_type * history , const char * config_file, const ecl_grid_type * grid , const ecl_sum_type * refcase , + double std_cutoff , ensemble_config_type * ensemble_config); - void enkf_obs_reload( enkf_obs_type * enkf_obs , const ecl_grid_type * grid , const ecl_sum_type * refcase , ensemble_config_type * ensemble_config ); + void enkf_obs_reload( enkf_obs_type * enkf_obs , const history_type * history , + const ecl_grid_type * grid , const ecl_sum_type * refcase , double std_cutoff , ensemble_config_type * ensemble_config ); void enkf_obs_get_obs_and_measure( const enkf_obs_type * enkf_obs, diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_state.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_state.h index 2bf0273c3c..db41476993 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_state.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_state.h @@ -67,13 +67,12 @@ typedef struct enkf_state_struct enkf_state_type; bool enkf_state_resubmit_simulation( enkf_state_type * enkf_state , enkf_fs_type * fs , bool resample); bool enkf_state_kill_simulation( const enkf_state_type * enkf_state ); void * enkf_state_internalize_results_mt( void * arg ); - void enkf_state_initialize(enkf_state_type * enkf_state , enkf_fs_type * fs, const stringlist_type * param_list); + void enkf_state_initialize(enkf_state_type * enkf_state , enkf_fs_type * fs, const stringlist_type * param_list , bool force_init); void enkf_state_fread(enkf_state_type * , enkf_fs_type * fs , int , int , state_enum ); bool enkf_state_get_analyzed(const enkf_state_type * ); void enkf_state_set_analyzed(enkf_state_type * , bool ); void enkf_state_swapout_node(const enkf_state_type * , const char *); void enkf_state_swapin_node(const enkf_state_type * , const char *); - enkf_state_type * enkf_state_copyc(const enkf_state_type * ); void enkf_state_iset_eclpath(enkf_state_type * , int , const char *); enkf_node_type * enkf_state_get_node(const enkf_state_type * , const char * ); void enkf_state_del_node(enkf_state_type * , const char * ); @@ -110,8 +109,10 @@ typedef struct enkf_state_struct enkf_state_type; int enkf_state_get_iens(const enkf_state_type * ); member_config_type *enkf_state_get_member_config(const enkf_state_type * enkf_state); const char * enkf_state_get_run_path(const enkf_state_type * ); + const char * enkf_state_get_eclbase( const enkf_state_type * enkf_state ); void enkf_state_printf_subst_list(enkf_state_type * enkf_state , int step1 , int step2); + unsigned int enkf_state_get_random( enkf_state_type * enkf_state ); /*****************************************************************/ void enkf_state_set_inactive(enkf_state_type * state); diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_types.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_types.h index 40500e70bb..28e3000d8d 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_types.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_types.h @@ -168,7 +168,8 @@ typedef enum { TRUNCATE_NONE = 0, typedef enum { ENKF_ASSIMILATION = 1, ENSEMBLE_EXPERIMENT = 2, - SMOOTHER_UPDATE = 4 } run_mode_type; + SMOOTHER_UPDATE = 4 , + INIT_ONLY = 8 } run_mode_type; #define ENKF_RUN_ENUM_DEFS {.value = 1 , .name = "ENKF_ASSIMILATION"}, \ diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ensemble_config.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ensemble_config.h index 0492450ec9..63b6425303 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ensemble_config.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ensemble_config.h @@ -69,6 +69,10 @@ typedef struct ensemble_config_struct ensemble_config_type; void ensemble_config_init_internalization( ensemble_config_type * ); void ensemble_config_del_node(ensemble_config_type * , const char * ); void ensemble_config_add_config_items(config_type * ); + + void ensemble_config_add_GEN_PARAM_config_item( config_type * config ); + void ensemble_config_init_GEN_PARAM( ensemble_config_type * ensemble_config , const config_type * config ); + enkf_config_node_type * ensemble_config_get_node(const ensemble_config_type * , const char * ); stringlist_type * ensemble_config_alloc_keylist(const ensemble_config_type *); stringlist_type * ensemble_config_alloc_keylist_from_var_type(const ensemble_config_type * , int var_mask); diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_report.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_report.h index 1c1eb114ff..8a93390fde 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_report.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_report.h @@ -30,9 +30,10 @@ extern "C" { ert_report_type * ert_report_alloc( const char * source_file , const char * target_file ); void ert_report_free( ert_report_type * ert_report ); void ert_report_free__(void * arg); - bool ert_report_create( ert_report_type * ert_report , const subst_list_type * context , const char * plot_path , const char * target_path ); + bool ert_report_create( ert_report_type * ert_report , int latex_timeout , const subst_list_type * context , const char * plot_path , const char * target_path ); const char * ert_report_get_basename( const ert_report_type * ert_report ); const char * ert_report_get_work_path( const ert_report_type * ert_report ); + void ert_report_set_latex_timeout( ert_report_type * ert_report , int timeout); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_report_list.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_report_list.h index 2988abc73d..679f54263e 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_report_list.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_report_list.h @@ -43,7 +43,11 @@ extern "C" { void ert_report_list_add_global_context( ert_report_list_type * report_list , const char * key , const char * value); void ert_report_list_site_init( ert_report_list_type * report_list , config_type * config ); void ert_report_list_init( ert_report_list_type * report_list , config_type * config , const ecl_sum_type * refcase); - void ert_report_list_create( const ert_report_list_type * report_list , const char * current_case , bool verbose ); + void ert_report_list_create( ert_report_list_type * report_list , const char * current_case , bool verbose ); + void ert_report_list_add_config_items( config_type * config ); + int ert_report_list_get_latex_timeout( const ert_report_list_type * report_list ); + bool ert_report_list_get_init_large_report( const ert_report_list_type * report_list ); + void ert_report_list_set_init_large_report( ert_report_list_type * report_list , bool init_large_report); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_template.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_template.h index 37788ee01e..d6c5c6be91 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_template.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_template.h @@ -26,6 +26,8 @@ extern "C" { #include #include +#include + typedef struct ert_template_struct ert_template_type; typedef struct ert_templates_struct ert_templates_type; @@ -50,6 +52,7 @@ const char * ert_template_get_template_file( const ert_template_type * e const char * ert_template_get_target_file( const ert_template_type * ert_template); const char * ert_template_get_args_as_string( const ert_template_type * ert_template ); void ert_templates_fprintf_config( const ert_templates_type * ert_templates , FILE * stream ); +void ert_templates_init( ert_templates_type * templates , const config_type * config ); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_workflow_list.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_workflow_list.h new file mode 100644 index 0000000000..1f7d6875e8 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/ert_workflow_list.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_workflow_list.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + +#ifndef __ERT_WORKFLOW_LIST_H__ +#define __ERT_WORKFLOW_LIST_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include + +#include + + + typedef struct ert_workflow_list_struct ert_workflow_list_type; + + workflow_type * ert_workflow_list_get_workflow(ert_workflow_list_type * workflow_list , const char * workflow_name ); + workflow_type * ert_workflow_list_add_workflow( ert_workflow_list_type * workflow_list , const char * workflow_file , const char * workflow_name); + void ert_workflow_list_free( ert_workflow_list_type * workflow_list ); + ert_workflow_list_type * ert_workflow_list_alloc( const subst_list_type * subst_list ); + void ert_workflow_list_add_jobs_in_directory( ert_workflow_list_type * workflow_list , const char * path , log_type * logh); + void ert_workflow_list_add_job( ert_workflow_list_type * workflow_list , const char * job_name , const char * config_file ); + void ert_workflow_list_add_alias( ert_workflow_list_type * workflow_list , const char * real_name , const char * alias); + void ert_workflow_list_add_config_items( config_type * config ); + void ert_workflow_list_init( ert_workflow_list_type * workflow_list , config_type * config , log_type * logh); + bool ert_workflow_list_run_workflow(ert_workflow_list_type * workflow_list , const char * workflow_name , void * self); + bool ert_workflow_list_run_workflow__(ert_workflow_list_type * workflow_list , workflow_type * workflow, bool verbose , void * self ); + bool ert_workflow_list_has_workflow(ert_workflow_list_type * workflow_list , const char * workflow_name ); + stringlist_type * ert_workflow_list_alloc_namelist( ert_workflow_list_type * workflow_list ); + const config_error_type * ert_workflow_list_get_last_error( const ert_workflow_list_type * workflow_list); + void ert_workflow_list_set_verbose( ert_workflow_list_type * workflow_list , bool verbose); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_config.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_config.h index 8b26c20d2b..0dc49fb512 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_config.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_config.h @@ -123,7 +123,7 @@ typedef enum { typedef struct local_config_struct local_config_type; -local_config_type * local_config_alloc( int history_length ); +local_config_type * local_config_alloc( ); void local_config_free( local_config_type * local_config ); local_updatestep_type * local_config_alloc_updatestep( local_config_type * local_config , const char * key ); local_ministep_type * local_config_alloc_ministep( local_config_type * local_config , const char * key , const char * obsset_name); diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/plot_config.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/plot_config.h index cad4fa918e..9e275d9e94 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/plot_config.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/plot_config.h @@ -19,13 +19,14 @@ #ifndef __PLOT_CONFIG_H__ #define __PLOT_CONFIG_H__ #include +#include typedef struct plot_config_struct plot_config_type; void plot_config_set_width(plot_config_type * plot_config , int width); void plot_config_set_height(plot_config_type * plot_config , int height); void plot_config_set_path(plot_config_type * plot_config , const char * plot_path); -void plot_config_set_plot_refcase(plot_config_type * plot_config , const char * plot_refcase); + void plot_config_set_image_type(plot_config_type * plot_config , const char * plot_device); void plot_config_set_viewer(plot_config_type * plot_config , const char * plot_viewer); void plot_config_set_driver(plot_config_type * plot_config , const char * plot_driver);; @@ -36,7 +37,8 @@ bool plot_config_get_plot_errorbar(const plot_config_type * plot_c int plot_config_get_width(const plot_config_type * plot_config ); int plot_config_get_height(const plot_config_type * plot_config ); const char * plot_config_get_path(const plot_config_type * plot_config ); -const char * plot_config_get_plot_refcase(const plot_config_type * plot_config); +bool plot_config_get_plot_refcase(const plot_config_type * plot_config); +void plot_config_set_plot_refcase(plot_config_type * plot_config, bool plot_refcase); const char * plot_config_get_image_type(const plot_config_type * plot_config ); const char * plot_config_get_viewer(const plot_config_type * plot_config ); const char * plot_config_get_driver(const plot_config_type * plot_config ); diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/qc_config.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/qc_config.h deleted file mode 100644 index 89fc077d50..0000000000 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/qc_config.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'qc_config.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT 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. - - ERT 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. -*/ -#ifndef __QC_CONFIG_H__ -#define __QC_CONFIG_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - - typedef struct qc_config_struct qc_config_type; - - qc_config_type * qc_config_alloc(const char * qc_path); - void qc_config_free(); - - void qc_config_set_path( qc_config_type * qc_config , const char * qc_path); - const char * qc_config_get_path( const qc_config_type * qc_config ); - void qc_config_init( qc_config_type * qc_config , const config_type * config); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/qc_module.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/qc_module.h new file mode 100644 index 0000000000..d90b4de24f --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/qc_module.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'qc_module.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ +#ifndef __QC_MODULE_H__ +#define __QC_MODULE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include + + typedef struct qc_module_struct qc_module_type; + + bool qc_module_has_workflow( const qc_module_type * qc_module ); + qc_module_type * qc_module_alloc(ert_workflow_list_type * workflow_list , const char * qc_path); + void qc_module_free(); + bool qc_module_run_workflow( qc_module_type * qc_module , void * self); + runpath_list_type * qc_module_get_runpath_list( qc_module_type * qc_module ); + void qc_module_set_path( qc_module_type * qc_module , const char * qc_path); + const char * qc_module_get_path( const qc_module_type * qc_module ); + void qc_module_init( qc_module_type * qc_module , const config_type * config); + void qc_module_export_runpath_list( const qc_module_type * qc_module ); + void qc_module_add_config_items( config_type * config ); + void qc_module_set_runpath_list_file( qc_module_type * qc_module , const char * filename); + const char * qc_module_get_runpath_list_file( qc_module_type * qc_module); + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/rng_config.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/rng_config.h index 7b18f918d1..461e7fcdf6 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/rng_config.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/rng_config.h @@ -29,17 +29,18 @@ extern "C" { typedef struct rng_config_struct rng_config_type; -void rng_config_fprintf_config( rng_config_type * rng_config , FILE * stream ); -void rng_config_init( rng_config_type * rng_config , config_type * config ); -void rng_config_set_type( rng_config_type * rng_config , rng_alg_type type); -rng_alg_type rng_config_get_type(const rng_config_type * rng_config ); -const char * rng_config_get_seed_load_file( const rng_config_type * rng_config ); -void rng_config_set_seed_load_file( rng_config_type * rng_config , const char * seed_load_file); -const char * rng_config_get_seed_store_file( const rng_config_type * rng_config ); -void rng_config_set_seed_store_file( rng_config_type * rng_config , const char * seed_store_file); -rng_config_type * rng_config_alloc( ); -void rng_config_free( rng_config_type * rng); -void rng_config_add_config_items( config_type * config ); + void rng_config_fprintf_config( rng_config_type * rng_config , FILE * stream ); + void rng_config_init( rng_config_type * rng_config , config_type * config ); + void rng_config_set_type( rng_config_type * rng_config , rng_alg_type type); + rng_alg_type rng_config_get_type(const rng_config_type * rng_config ); + const char * rng_config_get_seed_load_file( const rng_config_type * rng_config ); + void rng_config_set_seed_load_file( rng_config_type * rng_config , const char * seed_load_file); + const char * rng_config_get_seed_store_file( const rng_config_type * rng_config ); + void rng_config_set_seed_store_file( rng_config_type * rng_config , const char * seed_store_file); + rng_config_type * rng_config_alloc( ); + void rng_config_free( rng_config_type * rng); + void rng_config_add_config_items( config_type * config ); + rng_type * rng_config_alloc_rng( rng_config_type * rng_config ); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/runpath_list.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/runpath_list.h new file mode 100644 index 0000000000..b921985c96 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/runpath_list.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + The file 'runpath_list.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + +#ifndef __RUNPATH_LIST_H__ +#define __RUNPATH_LIST_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define RUNPATH_LIST_DEFAULT_LINE_FMT "%03d %s %s\n" + + + typedef struct runpath_list_struct runpath_list_type; + + void runpath_list_free( runpath_list_type * list ); + runpath_list_type * runpath_list_alloc(); + int runpath_list_size( const runpath_list_type * list ); + void runpath_list_add( runpath_list_type * list , int iens , const char * runpath , const char * basename); + void runpath_list_clear( runpath_list_type * list ); + void runpath_list_sort( runpath_list_type * list ); + int runpath_list_iget_iens( runpath_list_type * list , int index); + void runpath_list_set_line_fmt( runpath_list_type * list , const char * line_fmt ); + const char * runpath_list_get_line_fmt( const runpath_list_type * list ); + void runpath_list_fprintf( runpath_list_type * list , FILE * stream); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/site_config.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/site_config.h index dd949bcf7a..16714d1535 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/site_config.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/site_config.h @@ -28,6 +28,7 @@ extern "C" { #include +#include #include #include @@ -45,7 +46,7 @@ typedef struct site_config_struct site_config_type; void site_config_set_num_cpu( site_config_type * site_config , int num_cpu ); void site_config_update_lsf_request(site_config_type * , const forward_model_type *); - void site_config_init(site_config_type * site_config , const config_type * config, bool user_config); + bool site_config_init(site_config_type * site_config , const config_type * config); void site_config_free(site_config_type *); ext_joblist_type * site_config_get_installed_jobs( const site_config_type * ); job_queue_type * site_config_get_job_queue( const site_config_type * ); @@ -95,7 +96,7 @@ typedef struct site_config_struct site_config_type; void site_config_fprintf_config( const site_config_type * site_config , FILE * stream ); site_config_type * site_config_alloc_empty(); - void site_config_add_config_items( config_type * config , bool site_only); + void site_config_add_config_items( config_type * config , bool site_mode); #ifdef __cplusplus } #endif diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/time_map.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/time_map.h index 1432aa4dfb..f501215935 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/time_map.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/time_map.h @@ -23,20 +23,31 @@ extern "C" { #include +#include + #include typedef struct time_map_struct time_map_type; - + UTIL_SAFE_CAST_HEADER( time_map ); + void time_map_clear( time_map_type * map ); + bool time_map_equal( const time_map_type * map1 , const time_map_type * map2); time_map_type * time_map_alloc( ); void time_map_free( time_map_type * map ); - void time_map_update( time_map_type * map , int step , time_t time); - void time_map_summary_update( time_map_type * map , const ecl_sum_type * ecl_sum); + bool time_map_update( time_map_type * map , int step , time_t time); + bool time_map_summary_update( time_map_type * map , const ecl_sum_type * ecl_sum); time_t time_map_iget( time_map_type * map , int step ); void time_map_fwrite( time_map_type * map , const char * filename); void time_map_fread( time_map_type * map , const char * filename); double time_map_iget_sim_days( time_map_type * map , int step ); int time_map_get_last_step( time_map_type * map); + int time_map_get_size( time_map_type * map); + void time_map_update_strict( time_map_type * map , int step , time_t time); + void time_map_summary_update_strict( time_map_type * map , const ecl_sum_type * ecl_sum); + time_t time_map_get_start_time( time_map_type * map); + time_t time_map_get_end_time( time_map_type * map); + double time_map_get_end_days( time_map_type * map); + #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libenkf/src/CMakeLists.txt b/ThirdParty/Ert/devel/libenkf/src/CMakeLists.txt index 32d1963c4c..24dcedbcdf 100644 --- a/ThirdParty/Ert/devel/libenkf/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libenkf/src/CMakeLists.txt @@ -1,6 +1,7 @@ -set( source_files ert_report.c time_map.c rng_config.c trans_func.c enkf_types.c enkf_obs.c obs_data.c block_obs.c enkf_config_node.c field_config.c field.c ecl_static_kw.c enkf_state.c enkf_util.c enkf_node.c gen_kw_config.c gen_kw.c enkf_fs.c fs_driver.c meas_data.c summary_obs.c summary.c summary_config.c gen_data_config.c gen_data.c gen_common.c gen_obs.c enkf_sched.c enkf_serialize.c ecl_config.c enkf_defaults.c ensemble_config.c model_config.c site_config.c active_list.c obs_vector.c field_trans.c plain_driver.c local_ministep.c local_updatestep.c container_config.c container.c local_context.c local_config.c analysis_config.c misfit_ensemble.c misfit_member.c misfit_ts.c data_ranking.c misfit_ranking.c ranking_table.c fs_types.c block_fs_driver.c plot_config.c ert_template.c member_config.c enkf_analysis.c enkf_main.c local_dataset.c local_obsset.c surface.c surface_config.c enkf_plot_data.c enkf_plot_member.c qc_config.c ert_report_list.c enkf_plot_arg.c) +set( source_files ert_report.c time_map.c rng_config.c trans_func.c enkf_types.c enkf_obs.c obs_data.c block_obs.c enkf_config_node.c field_config.c field.c ecl_static_kw.c enkf_state.c enkf_util.c enkf_node.c gen_kw_config.c gen_kw.c enkf_fs.c fs_driver.c meas_data.c summary_obs.c summary.c summary_config.c gen_data_config.c gen_data.c gen_common.c gen_obs.c enkf_sched.c enkf_serialize.c ecl_config.c enkf_defaults.c ensemble_config.c model_config.c site_config.c active_list.c obs_vector.c field_trans.c plain_driver.c local_ministep.c local_updatestep.c container_config.c container.c local_context.c local_config.c analysis_config.c misfit_ensemble.c misfit_member.c misfit_ts.c data_ranking.c misfit_ranking.c ranking_table.c fs_types.c block_fs_driver.c plot_config.c ert_template.c member_config.c enkf_analysis.c enkf_main.c local_dataset.c local_obsset.c surface.c surface_config.c enkf_plot_data.c enkf_plot_member.c qc_module.c ert_report_list.c enkf_plot_arg.c runpath_list.c ert_workflow_list.c analysis_iter_config.c enkf_main_jobs.c ecl_refcase_list.c) + +set( header_files ert_report.h time_map.h rng_config.h enkf_analysis.h enkf_fs_type.h trans_func.h enkf_obs.h obs_data.h enkf_config_node.h block_obs.h field_config.h field.h enkf_macros.h ecl_static_kw.h enkf_state.h enkf_util.h enkf_main.h enkf_node.h enkf_fs.h gen_kw_config.h gen_kw.h enkf_types.h fs_driver.h meas_data.h summary_obs.h summary_config.h summary_config.h gen_data_config.h gen_data.h gen_common.h gen_obs.h enkf_sched.h fs_types.h enkf_serialize.h plain_driver.h ecl_config.h ensemble_config.h model_config.h site_config.h active_list.h obs_vector.h field_trans.h plain_driver.h local_ministep.h container.h local_updatestep.h local_config.h analysis_config.h misfit_ensemble.h misfit_ensemble_typedef.h misfit_ts.h misfit_member.h data_ranking.h ranking_table.h ranking_common.h misfit_ranking.h block_fs_driver.h field_common.h gen_kw_common.h gen_data_common.h plot_config.h ert_template.h member_config.h enkf_defaults.h container_config.h local_dataset.h local_obsset.h surface.h surface_config.h local_context.h enkf_plot_data.h enkf_plot_member.h qc_module.h ert_report_list.h enkf_plot_arg.h runpath_list.h ert_workflow_list.h analysis_iter_config.h ecl_refcase_list.h) -set( header_files ert_report.h time_map.h rng_config.h enkf_analysis.h enkf_fs_type.h trans_func.h enkf_obs.h obs_data.h enkf_config_node.h block_obs.h field_config.h field.h enkf_macros.h ecl_static_kw.h enkf_state.h enkf_util.h enkf_main.h enkf_node.h enkf_fs.h gen_kw_config.h gen_kw.h enkf_types.h fs_driver.h meas_data.h summary_obs.h summary_config.h summary_config.h gen_data_config.h gen_data.h gen_common.h gen_obs.h enkf_sched.h fs_types.h enkf_serialize.h plain_driver.h ecl_config.h ensemble_config.h model_config.h site_config.h active_list.h obs_vector.h field_trans.h plain_driver.h local_ministep.h container.h local_updatestep.h local_config.h analysis_config.h misfit_ensemble.h misfit_ensemble_typedef.h misfit_ts.h misfit_member.h data_ranking.h ranking_table.h ranking_common.h misfit_ranking.h block_fs_driver.h field_common.h gen_kw_common.h gen_data_common.h plot_config.h ert_template.h member_config.h enkf_defaults.h container_config.h local_dataset.h local_obsset.h surface.h surface_config.h local_context.h enkf_plot_data.h enkf_plot_member.h qc_config.h ert_report_list.h enkf_plot_arg.h) add_library( enkf ${LIBRARY_TYPE} ${source_files} ) set_target_properties( enkf PROPERTIES VERSION 1.0 SOVERSION 1.0 ) @@ -12,10 +13,11 @@ set_target_properties( enkf PROPERTIES VERSION 1.0 SOVERSION 1.0 ) target_link_libraries( enkf ecl sched analysis rms plot config job_queue ) #----------------------------------------------------------------- -install(TARGETS enkf DESTINATION ${CMAKE_INSTALL_LIBDIR}) -foreach(header ${header_files}) - install(FILES ../include/ert/enkf/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/enkf) -endforeach() - +if (INSTALL_ERT) + install(TARGETS enkf DESTINATION ${CMAKE_INSTALL_LIBDIR}) + foreach(header ${header_files}) + install(FILES ../include/ert/enkf/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/enkf) + endforeach() +endif() diff --git a/ThirdParty/Ert/devel/libenkf/src/analysis_config.c b/ThirdParty/Ert/devel/libenkf/src/analysis_config.c index 357b304ace..3e5fef6893 100644 --- a/ThirdParty/Ert/devel/libenkf/src/analysis_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/analysis_config.c @@ -33,28 +33,34 @@ #include #include #include +#include struct analysis_config_struct { - hash_type * analysis_modules; - analysis_module_type * analysis_module; - char * log_path; /* Points to directory with update logs. */ - bool merge_observations; /* When observing from time1 to time2 - should ALL observations in between be used? */ - bool rerun; /* Should we rerun the simulator when the parameters have been updated? */ - int rerun_start; /* When rerunning - from where should we start? */ + hash_type * analysis_modules; + analysis_module_type * analysis_module; + char * log_path; /* Points to directory with update logs. */ + bool merge_observations; /* When observing from time1 to time2 - should ALL observations in between be used? */ + bool rerun; /* Should we rerun the simulator when the parameters have been updated? */ + int rerun_start; /* When rerunning - from where should we start? */ - double overlap_alpha; - double std_cutoff; + double overlap_alpha; + double std_cutoff; - char * PC_filename; - char * PC_path; - bool store_PC; - bool update_results; /* Should result values like e.g. WWCT be updated? */ - bool single_node_update; /* When creating the default ALL_ACTIVE local configuration. */ - rng_type * rng; + char * PC_filename; + char * PC_path; + bool store_PC; + bool update_results; /* Should result values like e.g. WWCT be updated? */ + bool single_node_update; /* When creating the default ALL_ACTIVE local configuration. */ + rng_type * rng; + analysis_iter_config_type * iter_config; }; + + + + /*****************************************************************/ /* @@ -107,8 +113,8 @@ ANALYSIS_SELECT ModuleName */ - - + +/*****************************************************************/ @@ -368,44 +374,67 @@ void analysis_config_init( analysis_config_type * analysis , const config_type * /* Loading external modules */ { - for (int i=0; i < config_get_occurences( config , ANALYSIS_LOAD_KEY ); i++) { - const stringlist_type * tokens = config_iget_stringlist_ref( config , ANALYSIS_LOAD_KEY , i); - const char * user_name = stringlist_iget( tokens , 0 ); - const char * lib_name = stringlist_iget( tokens , 1 ); - - analysis_config_load_external_module( analysis , user_name , lib_name); + const config_content_item_type * load_item = config_get_content_item( config , ANALYSIS_LOAD_KEY ); + if (load_item != NULL) { + for (int i=0; i < config_content_item_get_size( load_item ); i++) { + const config_content_node_type * load_node = config_content_item_iget_node( load_item , i ); + const char * user_name = config_content_node_iget( load_node , 0 ); + const char * lib_name = config_content_node_iget( load_node , 1 ); + + analysis_config_load_external_module( analysis , user_name , lib_name); + } } } /* Reload/copy modules. */ { - for (int i=0; i < config_get_occurences( config , ANALYSIS_COPY_KEY ); i++) { - const stringlist_type * tokens = config_iget_stringlist_ref( config , ANALYSIS_COPY_KEY , i); - const char * src_name = stringlist_iget( tokens , 0 ); - const char * target_name = stringlist_iget( tokens , 1 ); - - analysis_config_add_module_copy( analysis , src_name , target_name); + const config_content_item_type * copy_item = config_get_content_item( config , ANALYSIS_COPY_KEY ); + if (copy_item != NULL) { + for (int i=0; i < config_content_item_get_size( copy_item ); i++) { + const config_content_node_type * copy_node = config_content_item_iget_node( copy_item , i ); + const char * src_name = config_content_node_iget( copy_node , 0 ); + const char * target_name = config_content_node_iget( copy_node , 1 ); + + analysis_config_add_module_copy( analysis , src_name , target_name); + } } } /* Setting variables for analysis modules */ { - for (int i=0; i < config_get_occurences( config , ANALYSIS_SET_VAR_KEY ); i++) { - const stringlist_type * tokens = config_iget_stringlist_ref( config , ANALYSIS_SET_VAR_KEY , i); - const char * module_name = stringlist_iget( tokens , 0 ); - const char * var_name = stringlist_iget( tokens , 1 ); - char * value = stringlist_alloc_joined_substring( tokens , 2 , stringlist_get_size( tokens ) , " " ); - analysis_module_type * module = analysis_config_get_module( analysis , module_name ); - - analysis_module_set_var( module , var_name , value ); - free( value ); + const config_content_item_type * assign_item = config_get_content_item( config , ANALYSIS_SET_VAR_KEY ); + if (assign_item != NULL) { + for (int i=0; i < config_content_item_get_size( assign_item ); i++) { + const config_content_node_type * assign_node = config_content_item_iget_node( assign_item , i ); + + const char * module_name = config_content_node_iget( assign_node , 0 ); + const char * var_name = config_content_node_iget( assign_node , 1 ); + analysis_module_type * module = analysis_config_get_module( analysis , module_name ); + { + char * value = NULL; + + for (int j=2; j < config_content_node_get_size( assign_node ); j++) { + const char * config_value = config_content_node_iget( assign_node , j ); + if (value == NULL) + value = util_alloc_string_copy( config_value ); + else { + value = util_strcat_realloc( value , " " ); + value = util_strcat_realloc( value , config_value ); + } + } + + analysis_module_set_var( module , var_name , value ); + free( value ); + } + } } } if (config_item_set( config, ANALYSIS_SELECT_KEY )) analysis_config_select_module( analysis , config_get_value( config , ANALYSIS_SELECT_KEY )); - + + analysis_iter_config_init( analysis->iter_config , config ); } @@ -415,12 +444,13 @@ bool analysis_config_get_merge_observations(const analysis_config_type * config) } - - - +analysis_iter_config_type * analysis_config_get_iter_config( const analysis_config_type * config ) { + return config->iter_config; +} void analysis_config_free(analysis_config_type * config) { + analysis_iter_config_free( config->iter_config ); hash_free( config->analysis_modules ); free(config->log_path); free(config); @@ -451,6 +481,7 @@ analysis_config_type * analysis_config_alloc_default( rng_type * rng ) { config->analysis_module = NULL; config->analysis_modules = hash_alloc(); config->rng = rng; + config->iter_config = analysis_iter_config_alloc(); return config; } @@ -467,33 +498,35 @@ void analysis_config_add_config_items( config_type * config ) { config_add_key_value( config , ENKF_ALPHA_KEY , false , CONFIG_FLOAT); config_add_key_value( config , STD_CUTOFF_KEY , false , CONFIG_FLOAT); - config_add_key_value( config , ENKF_MERGE_OBSERVATIONS_KEY , false , CONFIG_BOOLEAN); - config_add_key_value( config , UPDATE_RESULTS_KEY , false , CONFIG_BOOLEAN); - config_add_key_value( config , SINGLE_NODE_UPDATE_KEY , false , CONFIG_BOOLEAN); - config_add_key_value( config , ENKF_CROSS_VALIDATION_KEY , false , CONFIG_BOOLEAN); - config_add_key_value( config , ENKF_LOCAL_CV_KEY , false , CONFIG_BOOLEAN); - config_add_key_value( config , ENKF_PEN_PRESS_KEY , false , CONFIG_BOOLEAN); - config_add_key_value( config , ENKF_SCALING_KEY , false , CONFIG_BOOLEAN); - config_add_key_value( config , ENKF_KERNEL_REG_KEY , false , CONFIG_BOOLEAN); + config_add_key_value( config , ENKF_MERGE_OBSERVATIONS_KEY , false , CONFIG_BOOL); + config_add_key_value( config , UPDATE_RESULTS_KEY , false , CONFIG_BOOL); + config_add_key_value( config , SINGLE_NODE_UPDATE_KEY , false , CONFIG_BOOL); + config_add_key_value( config , ENKF_CROSS_VALIDATION_KEY , false , CONFIG_BOOL); + config_add_key_value( config , ENKF_LOCAL_CV_KEY , false , CONFIG_BOOL); + config_add_key_value( config , ENKF_PEN_PRESS_KEY , false , CONFIG_BOOL); + config_add_key_value( config , ENKF_SCALING_KEY , false , CONFIG_BOOL); + config_add_key_value( config , ENKF_KERNEL_REG_KEY , false , CONFIG_BOOL); config_add_key_value( config , ENKF_KERNEL_FUNC_KEY , false , CONFIG_INT); config_add_key_value( config , ENKF_KERNEL_PARAM_KEY , false , CONFIG_INT); - config_add_key_value( config , ENKF_FORCE_NCOMP_KEY , false , CONFIG_BOOLEAN); + config_add_key_value( config , ENKF_FORCE_NCOMP_KEY , false , CONFIG_BOOL); config_add_key_value( config , ENKF_NCOMP_KEY , false , CONFIG_INT); config_add_key_value( config , ENKF_CV_FOLDS_KEY , false , CONFIG_INT); - config_add_key_value( config , ENKF_RERUN_KEY , false , CONFIG_BOOLEAN); + config_add_key_value( config , ENKF_RERUN_KEY , false , CONFIG_BOOL); config_add_key_value( config , RERUN_START_KEY , false , CONFIG_INT); config_add_key_value( config , UPDATE_LOG_PATH_KEY , false , CONFIG_STRING); config_add_key_value( config , ANALYSIS_SELECT_KEY , false , CONFIG_STRING); - item = config_add_schema_item( config , ANALYSIS_LOAD_KEY , false , true ); - config_schema_item_set_argc_minmax( item , 2 , 2 , 0 , NULL ); + item = config_add_schema_item( config , ANALYSIS_LOAD_KEY , false ); + config_schema_item_set_argc_minmax( item , 2 , 2); - item = config_add_schema_item( config , ANALYSIS_COPY_KEY , false , true ); - config_schema_item_set_argc_minmax( item , 2 , 2 , 0 , NULL ); + item = config_add_schema_item( config , ANALYSIS_COPY_KEY , false ); + config_schema_item_set_argc_minmax( item , 2 , 2); - item = config_add_schema_item( config , ANALYSIS_SET_VAR_KEY , false , true ); - config_schema_item_set_argc_minmax( item , 3 , -1 , 0 , NULL ); + + item = config_add_schema_item( config , ANALYSIS_SET_VAR_KEY , false ); + config_schema_item_set_argc_minmax( item , 3 , CONFIG_DEFAULT_ARG_MAX); + analysis_iter_config_add_config_items( config ); } diff --git a/ThirdParty/Ert/devel/libenkf/src/analysis_iter_config.c b/ThirdParty/Ert/devel/libenkf/src/analysis_iter_config.c new file mode 100644 index 0000000000..c0bd8debe7 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/src/analysis_iter_config.c @@ -0,0 +1,130 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'analysis_iter_config.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include + +#include + +#include +#include +#include + + +struct analysis_iter_config_struct { + char * runpath_fmt; + char * case_fmt; + stringlist_type * storage; + int num_iterations; +}; + + +void analysis_iter_config_set_num_iterations( analysis_iter_config_type * config , int num_iterations) { + config->num_iterations = num_iterations; +} + +int analysis_iter_config_get_num_iterations( const analysis_iter_config_type * config ) { + return config->num_iterations; +} + + + +analysis_iter_config_type * analysis_iter_config_alloc() { + analysis_iter_config_type * config = util_malloc( sizeof * config ); + config->runpath_fmt = NULL; + config->case_fmt = NULL; + config->storage = stringlist_alloc_new(); + analysis_iter_config_set_num_iterations( config , DEFAULT_ANALYSIS_NUM_ITERATIONS ); + return config; +} + +void analysis_iter_config_free( analysis_iter_config_type * config ) { + util_safe_free( config->runpath_fmt ); + util_safe_free( config->case_fmt ); + stringlist_free( config->storage ); +} + + +/** + This should contain a format string with two %d modifiers, the + first will be replaced with the iteration number, and the second + with the realization number. The actual instantiation will happen + in a two step process, hence the last '%d' must be protected with + an extra '%'. +*/ + +static void analysis_iter_config_set_runpath_fmt( analysis_iter_config_type * config , const char * runpath_fmt) { + util_safe_free( config->runpath_fmt ); + if (runpath_fmt != NULL) { + config->runpath_fmt = util_calloc( strlen(runpath_fmt ) + 2 , sizeof * config->runpath_fmt); + strcpy(config->runpath_fmt , runpath_fmt); + { + char * perc_ptr = strrchr( config->runpath_fmt , '%'); + memmove(&perc_ptr[1] , &perc_ptr[0] , strlen(perc_ptr) + 1); + perc_ptr[0] = '%'; + } + } +} + +static void analysis_iter_config_set_case_fmt( analysis_iter_config_type * config , const char * case_fmt) { + config->case_fmt = util_realloc_string_copy( config->case_fmt , case_fmt ); +} + +const char * analysis_iter_config_iget_runpath_fmt( analysis_iter_config_type * config , int iter) { + if (config->runpath_fmt != NULL) { + char * runpath_fmt = util_alloc_sprintf( config->runpath_fmt , iter ); + stringlist_append_owned_ref( config->storage , runpath_fmt ); + return runpath_fmt; + } else + return NULL; +} + +const char * analysis_iter_config_iget_case( analysis_iter_config_type * config , int iter) { + if (config->case_fmt != NULL) { + char * fs_case = util_alloc_sprintf( config->case_fmt , iter ); + stringlist_append_owned_ref( config->storage , fs_case); + return fs_case; + } else + return NULL; +} + + +void analysis_iter_config_add_config_items( config_type * config ) { + config_add_key_value( config , ITER_CASE_KEY , false , CONFIG_STRING); + config_add_key_value( config , ITER_RUNPATH_KEY , false , CONFIG_STRING); + config_add_key_value( config , ITER_COUNT_KEY , false , CONFIG_INT); +} + + +void analysis_iter_config_init(analysis_iter_config_type * iter_config , const config_type * config) { + if (config_item_set( config , ITER_CASE_KEY )) + analysis_iter_config_set_case_fmt( iter_config , config_get_value( config , ITER_CASE_KEY )); + + if (config_item_set( config , ITER_RUNPATH_KEY )) + analysis_iter_config_set_runpath_fmt( iter_config , config_get_value( config , ITER_RUNPATH_KEY )); + + if (config_item_set( config , ITER_COUNT_KEY )) + analysis_iter_config_set_num_iterations( iter_config , config_get_value_as_int( config , ITER_COUNT_KEY )); +} + + diff --git a/ThirdParty/Ert/devel/libenkf/src/ecl_config.c b/ThirdParty/Ert/devel/libenkf/src/ecl_config.c index 68f2ace152..258dbc9efe 100644 --- a/ThirdParty/Ert/devel/libenkf/src/ecl_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/ecl_config.c @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -37,6 +38,7 @@ #include #include #include +#include #include /** @@ -64,7 +66,7 @@ struct ecl_config_struct { char * data_file; /* Eclipse data file. */ time_t start_date; /* The start date of the ECLIPSE simulation - parsed from the data_file. */ time_t end_date; /* An optional date value which can be used to check if the ECLIPSE simulation has been 'long enough'. */ - ecl_sum_type * refcase; /* Refcase - can be NULL. */ + ecl_refcase_list_type * refcase_list; ecl_grid_type * grid; /* The grid which is active for this model. */ char * schedule_prediction_file; /* Name of schedule prediction file - observe that this is internally handled as a gen_kw node. */ char * schedule_target_file; /* File name to write schedule info to */ @@ -264,20 +266,8 @@ const char * ecl_config_get_eclbase( const ecl_config_type * ecl_config ) { Can be called with @refcase == NULL - which amounts to clearing the current refcase. */ -void ecl_config_load_refcase( ecl_config_type * ecl_config , const char * refcase ){ - if (ecl_config->refcase != NULL) { - if (refcase == NULL) { /* Clear the refcase */ - ecl_sum_free( ecl_config->refcase ); - ecl_config->refcase = NULL; - } else { /* Check if the currently loaded case is the same as refcase */ - if (!ecl_sum_same_case( ecl_config->refcase , refcase )) { - ecl_sum_free( ecl_config->refcase ); - ecl_config->refcase = ecl_sum_fread_alloc_case( refcase , SUMMARY_KEY_JOIN_STRING ); - } - } - } else - if (refcase != NULL) - ecl_config->refcase = ecl_sum_fread_alloc_case( refcase , SUMMARY_KEY_JOIN_STRING ); +bool ecl_config_load_refcase( ecl_config_type * ecl_config , const char * refcase ){ + return ecl_refcase_list_set_default( ecl_config->refcase_list , refcase ); } @@ -285,11 +275,11 @@ void ecl_config_load_refcase( ecl_config_type * ecl_config , const char * refcas Will return NULL if no refcase is set. */ const char * ecl_config_get_refcase_name( const ecl_config_type * ecl_config) { - - if (ecl_config->refcase == NULL) + const ecl_sum_type * refcase = ecl_refcase_list_get_default( ecl_config->refcase_list ); + if (refcase == NULL) return NULL; else - return ecl_sum_get_case( ecl_config->refcase ); + return ecl_sum_get_case( refcase ); } @@ -405,7 +395,6 @@ ecl_config_type * ecl_config_alloc_empty( ) { ecl_config->data_file = NULL; ecl_config->input_init_section = NULL; ecl_config->init_section = NULL; - ecl_config->refcase = NULL; ecl_config->grid = NULL; ecl_config->can_restart = false; ecl_config->start_date = -1; @@ -413,6 +402,7 @@ ecl_config_type * ecl_config_alloc_empty( ) { ecl_config->sched_file = NULL; ecl_config->schedule_prediction_file = NULL; ecl_config->schedule_target_file = NULL; + ecl_config->refcase_list = ecl_refcase_list_alloc(); ecl_config_init_static_kw( ecl_config ); @@ -442,10 +432,43 @@ void ecl_config_init( ecl_config_type * ecl_config , const config_type * config config_iget_as_int(config , ADD_FIXED_LENGTH_SCHEDULE_KW_KEY , iocc , 1)); } + + if (config_item_set( config , REFCASE_KEY)) { + const char * refcase_path = config_get_value_as_path( config , REFCASE_KEY ); + if (!ecl_config_load_refcase( ecl_config , refcase_path)) + fprintf(stderr,"** Warning: loading refcase:%s failed \n", refcase_path); + } + - if (config_item_set( config , REFCASE_KEY)) - ecl_config_load_refcase( ecl_config , config_get_value( config , REFCASE_KEY )); - + if (config_item_set( config , REFCASE_LIST_KEY)) { + config_content_item_type * item = config_get_content_item( config , REFCASE_LIST_KEY); + int i; + for (i=0; i < config_content_item_get_size( item ); i++) { + config_content_node_type * node = config_content_item_iget_node( item , i ); + int j; + for (j=0; j < config_content_node_get_size( node ); j++) { + const char * case_glob = config_content_node_iget_as_path( node , j ); + ecl_refcase_list_add_matching( ecl_config->refcase_list , case_glob ); + } + } + } + + /* Deprecated */ + if (config_item_set( config , PLOT_REFCASE_LIST_KEY)) { + char * case_list_file = config_get_value( config , PLOT_REFCASE_LIST_KEY); + FILE * stream = util_fopen(case_list_file , "r"); + bool at_eof; + do { + char * case_name = util_fscanf_alloc_line(stream , &at_eof); + if (case_name) { + ecl_refcase_list_add_case( ecl_config->refcase_list , case_name); + free( case_name ); + } + } while (!at_eof); + + fclose( stream ); + } + if (config_item_set(config , INIT_SECTION_KEY)) ecl_config_set_init_section( ecl_config , config_get_value( config , INIT_SECTION_KEY )); else @@ -509,8 +532,7 @@ void ecl_config_free(ecl_config_type * ecl_config) { if (ecl_config->grid != NULL) ecl_grid_free( ecl_config->grid ); - if (ecl_config->refcase != NULL) - ecl_sum_free( ecl_config->refcase ); + ecl_refcase_list_free( ecl_config->refcase_list ); free(ecl_config); } @@ -592,8 +614,21 @@ void ecl_config_set_grid( ecl_config_type * ecl_config , const char * grid_file } +ecl_refcase_list_type * ecl_config_get_refcase_list( const ecl_config_type * ecl_config ) { + return ecl_config->refcase_list; +} + const ecl_sum_type * ecl_config_get_refcase(const ecl_config_type * ecl_config) { - return ecl_config->refcase; + return ecl_refcase_list_get_default( ecl_config->refcase_list ); +} + +bool ecl_config_has_refcase( const ecl_config_type * ecl_config ) { + const ecl_sum_type * refcase = ecl_config_get_refcase( ecl_config ); + printf("refcase:%p \n",refcase); + if (refcase) + return true; + else + return false; } @@ -640,44 +675,81 @@ bool ecl_config_get_unified_restart(const ecl_config_type * ecl_config) { retur bool ecl_config_get_unified_summary(const ecl_config_type * ecl_config) { return ecl_io_config_get_unified_summary( ecl_config->io_config ); } +void ecl_config_static_kw_init( ecl_config_type * ecl_config , const config_type * config ) { + const config_content_item_type * content_item = config_get_content_item( config , STATIC_KW_KEY ); + if (content_item != NULL) { + int j; + for (j=0; j < config_content_item_get_size( content_item ); j++) { + const config_content_node_type * content_node = config_content_item_iget_node( content_item , j); + int k; + for (k = 0; k < config_content_node_get_size( content_node ); k++) + ecl_config_add_static_kw(ecl_config , config_content_node_iget( content_node , k )); + } + } +} + void ecl_config_add_config_items( config_type * config ) { config_schema_item_type * item; - item = config_add_schema_item(config , SCHEDULE_FILE_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_EXISTING_FILE}); + item = config_add_schema_item(config , SCHEDULE_FILE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); /* Observe that SCHEDULE_PREDICTION_FILE - which is implemented as a GEN_KW is added in ensemble_config.c */ - item = config_add_schema_item( config , IGNORE_SCHEDULE_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) { CONFIG_BOOLEAN }); + item = config_add_schema_item( config , IGNORE_SCHEDULE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_BOOL); - item = config_add_schema_item(config , ECLBASE_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); - - item = config_add_schema_item(config , DATA_FILE_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_EXISTING_FILE}); - - item = config_add_schema_item(config , STATIC_KW_KEY , false , true); - config_schema_item_set_argc_minmax(item , 1 , -1 , 0 , NULL); - - item = config_add_schema_item(config , ADD_FIXED_LENGTH_SCHEDULE_KW_KEY , false , true); - config_schema_item_set_argc_minmax(item , 2 , 2 , 2 , (const config_item_types [2]) { CONFIG_STRING , CONFIG_INT}); - - item = config_add_schema_item(config , REFCASE_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , NULL ); - item = config_add_schema_item(config , GRID_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_EXISTING_FILE}); + item = config_add_schema_item(config , ECLBASE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1); + + + item = config_add_schema_item(config , DATA_FILE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); + + + item = config_add_schema_item(config , STATIC_KW_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , CONFIG_DEFAULT_ARG_MAX ); - item = config_add_schema_item(config , INIT_SECTION_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_FILE}); + + item = config_add_schema_item(config , ADD_FIXED_LENGTH_SCHEDULE_KW_KEY , false ); + config_schema_item_set_argc_minmax(item , 2 , 2 ); + config_schema_item_iset_type( item , 1 , CONFIG_INT ); + + + item = config_add_schema_item(config , REFCASE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_PATH ); + + item = config_add_schema_item(config , REFCASE_LIST_KEY , false ); + config_schema_item_set_default_type( item , CONFIG_PATH ); + + item = config_add_key_value(config , PLOT_REFCASE_LIST_KEY , false , CONFIG_STRING); + { + char * message = util_alloc_sprintf("Warning: the key:%s is depreceated - use %s instead" , PLOT_REFCASE_LIST_KEY , REFCASE_LIST_KEY); + config_install_message( config , PLOT_REFCASE_LIST_KEY , message ); + free( message ); + } + + item = config_add_schema_item(config , GRID_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); + + + item = config_add_schema_item(config , INIT_SECTION_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_PATH ); config_add_alias(config , INIT_SECTION_KEY , "EQUIL_INIT_FILE"); - item = config_add_schema_item(config , END_DATE_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL ); + + item = config_add_schema_item(config , END_DATE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); } @@ -713,10 +785,12 @@ void ecl_config_fprintf_config( const ecl_config_type * ecl_config , FILE * stre } } - if (ecl_config->refcase != NULL) { + /* + if (ecl_config->refcase != NULL) { fprintf( stream , CONFIG_KEY_FORMAT , REFCASE_KEY ); fprintf( stream , CONFIG_ENDVALUE_FORMAT , ecl_config_get_refcase_name( ecl_config )); - } + } + */ if (ecl_config->grid != NULL) { fprintf( stream , CONFIG_KEY_FORMAT , GRID_KEY ); @@ -752,5 +826,4 @@ void ecl_config_fprintf_config( const ecl_config_type * ecl_config , FILE * stre fprintf(stream , "\n\n"); - } diff --git a/ThirdParty/Ert/devel/libenkf/src/ecl_refcase_list.c b/ThirdParty/Ert/devel/libenkf/src/ecl_refcase_list.c new file mode 100644 index 0000000000..756ca37641 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/src/ecl_refcase_list.c @@ -0,0 +1,397 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_refcase_list.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include +#include + +#include + +#include + + +/* + This file implements a quite simple collection of ecl_sum instances, + with the following twists: + + o The default case is special in several ways: + + - It is added with the ecl_refcase_list_set_default() function. + + - The default case is always the first case, i.e. iget(0) will + return the default case. + + - When setting the default we verify that it can be loaded, and + the thing fails if not. That is in contrast to the other cases + where the actual summary loading is lazy and on demand. + + o The collection has an internal dictionary which ensures that the + same case is not added twice. + + o When calling iget( ) the default case will come as index 0, and + the remaining cases will come in util_strcmp_int() ordering. + + o Observe that the functions in this module return NULL quite + liberally: + + - If you have added a case which does not exist you will get + NULL when you (at a later stage) try to access the ecl_sum + instance. + + - If you ask for the default case before one has been set you + will get NULL. + */ + + +#define SUM_PAIR_TYPE_ID 665109971 + +typedef struct sum_pair_struct { + UTIL_TYPE_ID_DECLARATION; + char * case_name; // This should be (path)/basename - no extension + ecl_sum_type * ecl_sum; +} sum_pair_type; + + + +struct ecl_refcase_list_struct { + sum_pair_type * default_case; + hash_type * case_dict; + vector_type * case_list; /* This is created, and sorted, on demand when we do indexed lookup of cases. */ + bool sorted; +}; + +/*****************************************************************/ + + + +static sum_pair_type * sum_pair_alloc( const char * case_name , bool strict_load) { + ecl_sum_type * ecl_sum = NULL; + char * path = NULL; + char * basename = NULL; + + util_alloc_file_components( case_name , &path , &basename , NULL); + if (basename != NULL) { + char * use_case = util_alloc_filename( path , basename , NULL); + if (strict_load) + ecl_sum = ecl_sum_fread_alloc_case( use_case , ":"); + + util_safe_free( path ); + free( basename ); + if (strict_load && (ecl_sum == NULL)) { + free( use_case ); + return NULL; + } + + + { + sum_pair_type * pair = util_malloc( sizeof * pair ); + UTIL_TYPE_ID_INIT( pair , SUM_PAIR_TYPE_ID ); + pair->case_name = use_case; + pair->ecl_sum = ecl_sum; + return pair; + } + } else { + util_safe_free( path ); + util_safe_free( basename ); + return NULL; + } +} + + +static UTIL_SAFE_CAST_FUNCTION( sum_pair , SUM_PAIR_TYPE_ID ); +static UTIL_SAFE_CAST_FUNCTION_CONST( sum_pair , SUM_PAIR_TYPE_ID ); +static UTIL_IS_INSTANCE_FUNCTION( sum_pair , SUM_PAIR_TYPE_ID); + +const ecl_sum_type * sum_pair_get_ecl_sum( sum_pair_type * sum_pair ) { + if (sum_pair->ecl_sum == NULL) + sum_pair->ecl_sum = ecl_sum_fread_alloc_case( sum_pair->case_name , ":"); + return sum_pair->ecl_sum; +} + + +static void sum_pair_free( sum_pair_type * sum_pair ) { + free( sum_pair->case_name ); + if (sum_pair->ecl_sum != NULL) + ecl_sum_free( sum_pair->ecl_sum ); + free( sum_pair ); +} + + +static void sum_pair_free__( void * arg ) { + sum_pair_type * pair = sum_pair_safe_cast( arg ); + sum_pair_free( pair ); +} + + + + +static int sum_pair_cmp( const void * arg1 , const void * arg2) { + const sum_pair_type * pair1 = sum_pair_safe_cast_const( arg1 ); + const sum_pair_type * pair2 = sum_pair_safe_cast_const( arg2 ); + + return util_strcmp_int( pair1->case_name , pair2->case_name ); +} + +/*****************************************************************/ + + +ecl_refcase_list_type * ecl_refcase_list_alloc( ) { + ecl_refcase_list_type * refcase_list = util_malloc( sizeof * refcase_list ); + refcase_list->default_case = NULL; + refcase_list->case_list = vector_alloc_new(); + refcase_list->case_dict = hash_alloc(); + refcase_list->sorted = false; + return refcase_list; +} + + + +void ecl_refcase_list_free( ecl_refcase_list_type * refcase_list ) { + vector_free( refcase_list->case_list ); + hash_free( refcase_list->case_dict ); + free( refcase_list ); +} + + + +const ecl_sum_type * ecl_refcase_list_get_default( ecl_refcase_list_type * refcase_list ) { + if (refcase_list->default_case) + return sum_pair_get_ecl_sum( refcase_list->default_case ); + else + return NULL; +} + + +bool ecl_refcase_list_has_default( ecl_refcase_list_type * refcase_list ) { + if (refcase_list->default_case) + return true; + else + return false; +} + + +static void ecl_refcase_list_del_default( ecl_refcase_list_type * refcase_list ) { + sum_pair_type * default_pair = refcase_list->default_case; + if (default_pair) { + hash_del( refcase_list->case_dict , default_pair->case_name ); + refcase_list->default_case = NULL; + } +} + + +/* + If a valid refcase has been set already, and this fails, nothing happens. +*/ + +bool ecl_refcase_list_set_default( ecl_refcase_list_type * refcase_list , const char * default_case) { + + if (default_case) { + sum_pair_type * default_pair = sum_pair_alloc( default_case , true ); + if (default_pair) { + ecl_refcase_list_del_default( refcase_list ); + refcase_list->default_case = default_pair; + + hash_insert_hash_owned_ref( refcase_list->case_dict , default_pair->case_name , default_pair , sum_pair_free__); + refcase_list->sorted = false; + return true; + } else + return false; + } else { + ecl_refcase_list_del_default( refcase_list ); + return true; + } +} + + + + +/** + Will sort the list and remove all elements which can not be loaded. +*/ + +static void ecl_refcase_list_assert_clean( ecl_refcase_list_type * refcase_list ) { + if (!refcase_list->sorted) { + vector_free( refcase_list->case_list ); + refcase_list->case_list = vector_alloc_new(); + + { + stringlist_type * tmp_list = hash_alloc_stringlist( refcase_list->case_dict ); + sum_pair_type * default_case = refcase_list->default_case; + int i; + + for (i =0; i < stringlist_get_size( tmp_list ); i++) { + const char * casename = stringlist_iget( tmp_list , i ); + bool normal_case = true; + + if (default_case && util_string_equal( casename , default_case->case_name)) + normal_case = false; + + if (normal_case) { + sum_pair_type * pair = hash_get( refcase_list->case_dict , casename); + const ecl_sum_type * ecl_sum = sum_pair_get_ecl_sum( pair ); + + if (ecl_sum) + vector_append_ref( refcase_list->case_list , pair); + else + hash_del( refcase_list->case_dict , casename ); + + } + } + stringlist_free( tmp_list ); + } + + vector_sort( refcase_list->case_list , sum_pair_cmp ); + refcase_list->sorted = true; + } +} + + +static sum_pair_type * ecl_refcase_list_get_pair( ecl_refcase_list_type * refcase_list , const char * case_name) { + ecl_refcase_list_assert_clean( refcase_list ); + { + if (hash_has_key( refcase_list->case_dict , case_name)) + return hash_get( refcase_list->case_dict , case_name ); + else + return NULL; + } +} + + +static sum_pair_type * ecl_refcase_list_iget_pair( ecl_refcase_list_type * refcase_list , int index) { + ecl_refcase_list_assert_clean( refcase_list ); + { + int index_offset = refcase_list->default_case ? 1 : 0; + index -= index_offset; + + if (index < 0) + return refcase_list->default_case; + else + return vector_safe_iget( refcase_list->case_list , index); + } +} + + +int ecl_refcase_list_get_size(ecl_refcase_list_type * refcase_list ) { + ecl_refcase_list_assert_clean( refcase_list ); + { + int size = hash_get_size( refcase_list->case_dict ); + return size; + } +} + + + +const ecl_sum_type * ecl_refcase_list_iget_case( ecl_refcase_list_type * refcase_list , int index) { + sum_pair_type * pair = ecl_refcase_list_iget_pair( refcase_list , index ); + if (pair) + return sum_pair_get_ecl_sum( pair ); + else + return NULL; +} + + +const ecl_sum_type * ecl_refcase_list_get_case( ecl_refcase_list_type * refcase_list , const char * case_name) { + sum_pair_type * pair = ecl_refcase_list_get_pair( refcase_list , case_name ); + if (pair) + return sum_pair_get_ecl_sum( pair ); + else + return NULL; +} + + +bool ecl_refcase_list_has_case( ecl_refcase_list_type * refcase_list , const char * case_name) { + const sum_pair_type * pair = ecl_refcase_list_get_pair( refcase_list , case_name ); + if (pair) + return true; + else + return false; +} + + + +const char * ecl_refcase_list_iget_pathcase( ecl_refcase_list_type * refcase_list , int index) { + const ecl_sum_type * ecl_sum = ecl_refcase_list_iget_case( refcase_list , index ); + if (ecl_sum) + return ecl_sum_get_case( ecl_sum ); + else + return NULL; +} + + + +int ecl_refcase_list_add_case( ecl_refcase_list_type * refcase_list , const char * case_name) { + sum_pair_type * pair = sum_pair_alloc( case_name , false ); + if (pair) { + if (hash_has_key( refcase_list->case_dict , pair->case_name)) { + sum_pair_free( pair ); + return 0; + } else { + hash_insert_hash_owned_ref( refcase_list->case_dict , pair->case_name , pair , sum_pair_free__); + refcase_list->sorted = false; + return 1; + } + } else + return 0; +} + +/* + The glob_string pattern must (for all practical purposes) end in an + explicit extension: + + - If it ends without an extension there will be zero mathces. It + - it ends with a '*' there will be a hell-of-a-lot of duplicate + matches. + + If the input glob string does not have an explicit extension we add + .*SMSPEC for the matching purpose. +*/ + + +int ecl_refcase_list_add_matching( ecl_refcase_list_type * refcase_list , const char * __glob_string) { + int count = 0; + char * glob_string; + + { + char * glob_ext; + util_alloc_file_components( __glob_string , NULL , NULL , &glob_ext); + if (glob_ext == NULL) + glob_string = util_alloc_filename(NULL , __glob_string , "*SMSPEC"); + else { + glob_string = util_alloc_string_copy( __glob_string ); + free( glob_ext ); + } + } + + { + stringlist_type * case_list = stringlist_alloc_new(); + int i; + stringlist_select_matching( case_list , glob_string ); + for (i=0; i < stringlist_get_size( case_list ); i++) { + count += ecl_refcase_list_add_case( refcase_list , stringlist_iget( case_list , i ) ); + } + stringlist_free( case_list ); + } + + free( glob_string ); + return count; +} + diff --git a/ThirdParty/Ert/devel/libenkf/src/enkf_fs.c b/ThirdParty/Ert/devel/libenkf/src/enkf_fs.c index 5a6d210ae9..4bdfecd968 100644 --- a/ThirdParty/Ert/devel/libenkf/src/enkf_fs.c +++ b/ThirdParty/Ert/devel/libenkf/src/enkf_fs.c @@ -208,8 +208,11 @@ struct enkf_fs_struct { UTIL_TYPE_ID_DECLARATION; - char * mount_point; - + char * case_name; + char * root_path; + char * mount_point; // mount_point = root_path / case_name; the mount_point is the fundamental INPUT. + + fs_driver_type * dynamic_forecast; fs_driver_type * dynamic_analyzed; fs_driver_type * parameter; @@ -249,6 +252,16 @@ static enkf_fs_type * enkf_fs_alloc_empty( const char * mount_point , bool read_ fs->mount_point = util_alloc_string_copy( mount_point ); if (mount_point == NULL) util_abort("%s: fatal internal error: mount_point == NULL \n",__func__); + { + char ** path_tmp; + int path_len; + + util_path_split( fs->mount_point , &path_len , &path_tmp); + fs->case_name = util_alloc_string_copy( path_tmp[path_len - 1]); + fs->root_path = util_alloc_joined_string( path_tmp , path_len , UTIL_PATH_SEP_STRING); + + util_free_stringlist( path_tmp , path_len ); + } return fs; } @@ -507,6 +520,8 @@ void enkf_fs_close( enkf_fs_type * fs ) { enkf_fs_free_driver( fs->eclipse_static ); enkf_fs_free_driver( fs->index ); + util_safe_free( fs->case_name ); + util_safe_free( fs->root_path ); util_safe_free( fs->mount_point ); path_fmt_free( fs->case_fmt ); path_fmt_free( fs->case_member_fmt ); @@ -696,6 +711,14 @@ const char * enkf_fs_get_mount_point( const enkf_fs_type * fs ) { return fs->mount_point; } +const char * enkf_fs_get_root_path( const enkf_fs_type * fs ) { + return fs->root_path; +} + +const char * enkf_fs_get_case_name( const enkf_fs_type * fs ) { + return fs->case_name; +} + void enkf_fs_debug_fprintf( const enkf_fs_type * fs) { printf("-----------------------------------------------------------------\n"); printf("fs...................: %p \n",fs ); diff --git a/ThirdParty/Ert/devel/libenkf/src/enkf_main.c b/ThirdParty/Ert/devel/libenkf/src/enkf_main.c index 2f374dbd38..6b6188d454 100644 --- a/ThirdParty/Ert/devel/libenkf/src/enkf_main.c +++ b/ThirdParty/Ert/devel/libenkf/src/enkf_main.c @@ -80,7 +80,7 @@ #include #include #include -#include +#include #include #include #include @@ -96,6 +96,7 @@ #include #include #include +#include /**/ @@ -135,7 +136,7 @@ struct enkf_main_struct { char * current_fs_case; enkf_fs_type * dbase; /* The internalized information. */ ensemble_config_type * ensemble_config; /* The config objects for the various enkf nodes.*/ - qc_config_type * qc_config; + qc_module_type * qc_module; model_config_type * model_config; ecl_config_type * ecl_config; site_config_type * site_config; @@ -147,6 +148,7 @@ struct enkf_main_struct { rng_config_type * rng_config; rng_type * rng; ert_report_list_type * report_list; + ert_workflow_list_type * workflow_list; ranking_table_type * ranking_table; /*---------------------------*/ /* Variables related to substitution. */ @@ -214,11 +216,12 @@ void enkf_main_set_jobname( enkf_main_type * enkf_main , const char * jobname_fm } - -void enkf_main_set_refcase( enkf_main_type * enkf_main , const char * refcase_path) { - ecl_config_load_refcase( enkf_main->ecl_config , refcase_path ); +bool enkf_main_set_refcase( enkf_main_type * enkf_main , const char * refcase_path) { + bool set_refcase = ecl_config_load_refcase( enkf_main->ecl_config , refcase_path ); model_config_set_refcase( enkf_main->model_config , ecl_config_get_refcase( enkf_main->ecl_config )); ensemble_config_set_refcase( enkf_main->ensemble_config , ecl_config_get_refcase( enkf_main->ecl_config )); + + return set_refcase; } @@ -298,11 +301,21 @@ enkf_obs_type * enkf_main_get_obs(const enkf_main_type * enkf_main) { return enkf_main->obs; } + bool enkf_main_have_obs( const enkf_main_type * enkf_main ) { return enkf_obs_have_obs( enkf_main->obs ); } +bool enkf_main_has_QC_workflow( const enkf_main_type * enkf_main ) { + return qc_module_has_workflow( enkf_main->qc_module ); +} + +const qc_module_type * enkf_main_get_qc_module( const enkf_main_type * enkf_main ) { + return enkf_main->qc_module; +} + + /** Will do a forced reload of the observtaions; if the user has edited the content of the observation file while the ERT instance is @@ -311,8 +324,10 @@ bool enkf_main_have_obs( const enkf_main_type * enkf_main ) { void enkf_main_reload_obs( enkf_main_type * enkf_main) { enkf_obs_reload(enkf_main->obs , + model_config_get_history(enkf_main->model_config), ecl_config_get_grid( enkf_main->ecl_config ), ecl_config_get_refcase( enkf_main->ecl_config ) , + analysis_config_get_std_cutoff(enkf_main->analysis_config), enkf_main->ensemble_config ); } @@ -327,9 +342,11 @@ void enkf_main_reload_obs( enkf_main_type * enkf_main) { void enkf_main_load_obs( enkf_main_type * enkf_main , const char * obs_config_file ) { if (!util_string_equal( obs_config_file , enkf_obs_get_config_file( enkf_main->obs ))) { enkf_obs_load(enkf_main->obs , + model_config_get_history(enkf_main->model_config), obs_config_file , ecl_config_get_grid( enkf_main->ecl_config ), ecl_config_get_refcase( enkf_main->ecl_config ) , + analysis_config_get_std_cutoff(enkf_main->analysis_config), enkf_main->ensemble_config ); } } @@ -375,27 +392,36 @@ static void enkf_main_free_ensemble( enkf_main_type * enkf_main ) { } -void enkf_main_free(enkf_main_type * enkf_main) { - rng_free( enkf_main->rng ); +void enkf_main_free(enkf_main_type * enkf_main){ + if (enkf_main->rng != NULL) + rng_free( enkf_main->rng ); rng_config_free( enkf_main->rng_config ); + enkf_obs_free(enkf_main->obs); ranking_table_free( enkf_main->ranking_table ); enkf_main_free_ensemble( enkf_main ); if (enkf_main->dbase != NULL) enkf_fs_close( enkf_main->dbase ); util_safe_free( enkf_main->current_fs_case ); - log_add_message( enkf_main->logh , false , NULL , "Exiting ert application normally - all is fine(?)" , false); + if (log_is_open( enkf_main->logh )) + log_add_message( enkf_main->logh , false , NULL , "Exiting ert application normally - all is fine(?)" , false); log_close( enkf_main->logh ); + analysis_config_free(enkf_main->analysis_config); ecl_config_free(enkf_main->ecl_config); model_config_free( enkf_main->model_config); - qc_config_free( enkf_main->qc_config ); + + + qc_module_free( enkf_main->qc_module ); site_config_free( enkf_main->site_config); ensemble_config_free( enkf_main->ensemble_config ); if (enkf_main->local_config != NULL) local_config_free( enkf_main->local_config ); + ert_report_list_free( enkf_main->report_list ); + ert_workflow_list_free( enkf_main->workflow_list ); + int_vector_free( enkf_main->keep_runpath ); plot_config_free( enkf_main->plot_config ); @@ -411,6 +437,12 @@ void enkf_main_free(enkf_main_type * enkf_main) { +void enkf_main_exit(enkf_main_type * enkf_main) { + enkf_main_free( enkf_main ); + exit(0); +} + + /*****************************************************************/ @@ -1278,7 +1310,7 @@ static bool enkf_main_run_step(enkf_main_type * enkf_main , if (step1 > 0) ecl_config_assert_restart( enkf_main_get_ecl_config( enkf_main ) ); - + { bool verbose_queue = enkf_main->verbose; int max_internal_submit = model_config_get_max_internal_submit(enkf_main->model_config); @@ -1290,36 +1322,42 @@ static bool enkf_main_run_step(enkf_main_type * enkf_main , if (run_mode == ENKF_ASSIMILATION) printf("Starting forward step: %d -> %d\n",step1 , step2); } - + log_add_message(enkf_main->logh , 1 , NULL , "===================================================================", false); if (run_mode == ENKF_ASSIMILATION) log_add_fmt_message(enkf_main->logh , 1 , NULL , "Forward model: %d -> %d ",step1,step2); else log_add_fmt_message(enkf_main->logh , 1 , NULL , "Forward model: %d -> ??? ",step1); - bool_vector_safe_cast( iactive ); job_size = bool_vector_count_equal( iactive , true ); { pthread_t queue_thread; job_queue_type * job_queue = site_config_get_job_queue(enkf_main->site_config); - arg_pack_type * queue_args = arg_pack_alloc(); /* This arg_pack will be freed() in the job_que_run_jobs__() */ - arg_pack_append_ptr(queue_args , job_queue); - arg_pack_append_int(queue_args , job_size); - arg_pack_append_bool(queue_args , verbose_queue); - pthread_create( &queue_thread , NULL , job_queue_run_jobs__ , queue_args); + /* Start the queue */ + if (run_mode != INIT_ONLY) { + arg_pack_type * queue_args = arg_pack_alloc(); /* This arg_pack will be freed() in the job_que_run_jobs__() */ + arg_pack_append_ptr(queue_args , job_queue); + arg_pack_append_int(queue_args , job_size); + arg_pack_append_bool(queue_args , verbose_queue); + pthread_create( &queue_thread , NULL , job_queue_run_jobs__ , queue_args); + } + { thread_pool_type * submit_threads = thread_pool_alloc( 4 , true ); enkf_fs_type * fs = enkf_main_get_fs( enkf_main ); + runpath_list_type * runpath_list = qc_module_get_runpath_list( enkf_main->qc_module ); + runpath_list_clear( runpath_list ); for (iens = 0; iens < ens_size; iens++) { - if (bool_vector_iget(iactive , iens)) { + enkf_state_type * enkf_state = enkf_main->ensemble[iens]; + if (bool_vector_safe_iget(iactive , iens)) { int load_start = step1; if (step1 > 0) load_start++; - enkf_state_init_run(enkf_main->ensemble[iens] , + enkf_state_init_run(enkf_state , run_mode , true , max_internal_submit , @@ -1329,34 +1367,42 @@ static bool enkf_main_run_step(enkf_main_type * enkf_main , load_start , step1 , step2 ); + + runpath_list_add( runpath_list , + iens , + enkf_state_get_run_path( enkf_state ) , + enkf_state_get_eclbase( enkf_state )); { arg_pack_type * arg_pack = arg_pack_alloc( ); // This is discarded by the enkf_state_start_forward_model__() function. */ - arg_pack_append_ptr( arg_pack , enkf_main->ensemble[iens] ); + arg_pack_append_ptr( arg_pack , enkf_state ); arg_pack_append_ptr( arg_pack , fs ); thread_pool_add_job(submit_threads , enkf_state_start_forward_model__ , arg_pack); } } else - enkf_state_set_inactive( enkf_main->ensemble[iens] ); + enkf_state_set_inactive( enkf_state ); } /* After this join all directories/files for the simulations have been set up correctly, and all the jobs have been added to the job_queue manager. */ + qc_module_export_runpath_list( enkf_main->qc_module ); thread_pool_join(submit_threads); thread_pool_free(submit_threads); } - job_queue_submit_complete( job_queue ); - log_add_message(enkf_main->logh , 1 , NULL , "All jobs submitted to internal queue - waiting for completion" , false); - pthread_join( queue_thread , NULL ); /* Wait for the job_queue_run_jobs() function to complete. */ + if (run_mode != INIT_ONLY) { + job_queue_submit_complete( job_queue ); + log_add_message(enkf_main->logh , 1 , NULL , "All jobs submitted to internal queue - waiting for completion" , false); + pthread_join( queue_thread , NULL ); /* Wait for the job_queue_run_jobs() function to complete. */ + } } - + /* This should be carefully checked for the situation where only a subset (with offset > 0) of realisations are simulated. */ - { + if (run_mode != INIT_ONLY) { bool totalOK = true; for (iens = 0; iens < ens_size; iens++) { if (bool_vector_iget(iactive , iens)) { @@ -1378,12 +1424,15 @@ static bool enkf_main_run_step(enkf_main_type * enkf_main , } } - if (totalOK) - log_add_fmt_message(enkf_main->logh , 1 , NULL , "All jobs complete and data loaded."); - enkf_fs_fsync( enkf_main->dbase ); + if (totalOK) { + log_add_fmt_message(enkf_main->logh , 1 , NULL , "All jobs complete and data loaded."); + if (run_mode != ENKF_ASSIMILATION) + qc_module_run_workflow( enkf_main->qc_module , enkf_main ); + } return totalOK; - } + } else + return true; } } @@ -1444,52 +1493,31 @@ void enkf_main_init_run( enkf_main_type * enkf_main, run_mode_type run_mode) { } -/* -This function checks if no parameters have been initialized. If as much as one parameter -has been initialized the function will return false. -*/ - - -bool enkf_main_is_not_initialized_at_all( const enkf_main_type * enkf_main ) { - stringlist_type * parameter_keys = ensemble_config_alloc_keylist_from_var_type( enkf_main->ensemble_config , PARAMETER ); - bool initialized; - bool not_initialized_at_all = true; - int ikey, iens; - for (ikey = 0 ; ikey < stringlist_get_size( parameter_keys ) ; ikey++){ - const enkf_config_node_type * config_node = ensemble_config_get_node( enkf_main->ensemble_config , stringlist_iget( parameter_keys , ikey) ); - for ( iens = 0 ; iens < enkf_main->ens_size ; iens++ ){ - node_id_type node_id = {.report_step = 0 , .iens = iens , .state = ANALYZED }; - initialized = enkf_config_node_has_node( config_node , enkf_main->dbase , node_id); - if (initialized) - not_initialized_at_all = false; - } - - } - return not_initialized_at_all; -} - void enkf_main_run_exp(enkf_main_type * enkf_main , const bool_vector_type * iactive , + bool simulate , int init_step_parameters , int start_report , state_enum start_state) { - bool initialize = enkf_main_is_not_initialized_at_all( enkf_main ); - int ens_size = enkf_main_get_ensemble_size( enkf_main ); - if (initialize) { + + bool force_init = false; + int ens_size = enkf_main_get_ensemble_size( enkf_main ); + run_mode_type run_mode = simulate ? ENSEMBLE_EXPERIMENT : INIT_ONLY; + { stringlist_type * param_list = ensemble_config_alloc_keylist_from_var_type( enkf_main->ensemble_config , PARAMETER ); - enkf_main_initialize_from_scratch( enkf_main , param_list , 0 , ens_size - 1); + enkf_main_initialize_from_scratch( enkf_main , param_list , 0 , ens_size - 1, force_init); stringlist_free( param_list ); } - enkf_main_init_run( enkf_main , ENSEMBLE_EXPERIMENT ); + enkf_main_init_run( enkf_main , run_mode ); { const enkf_sched_type * enkf_sched = model_config_get_enkf_sched(enkf_main->model_config); const int last_report = -1; // Should be fully ignored. int load_start = start_report; state_enum init_state_parameter = start_state; state_enum init_state_dynamic = start_state; - enkf_main_run_step(enkf_main , ENSEMBLE_EXPERIMENT , iactive , load_start , init_step_parameters , init_state_parameter , init_state_dynamic , start_report , -1); + enkf_main_run_step(enkf_main , run_mode , iactive , load_start , init_step_parameters , init_state_parameter , init_state_dynamic , start_report , -1); } } @@ -1500,11 +1528,11 @@ void enkf_main_run_assimilation(enkf_main_type * enkf_main , int init_step_parameters , int start_report , state_enum start_state) { - bool initialize = enkf_main_is_not_initialized_at_all( enkf_main ); + bool force_init = false; int ens_size = enkf_main_get_ensemble_size( enkf_main ); - if (initialize) { + { stringlist_type * param_list = ensemble_config_alloc_keylist_from_var_type( enkf_main->ensemble_config , PARAMETER ); - enkf_main_initialize_from_scratch( enkf_main , param_list , 0 , ens_size - 1); + enkf_main_initialize_from_scratch( enkf_main , param_list , 0 , ens_size - 1 , force_init ); stringlist_free( param_list ); } bool rerun = analysis_config_get_rerun( enkf_main->analysis_config ); @@ -1597,11 +1625,11 @@ void enkf_main_run_assimilation(enkf_main_type * enkf_main , void enkf_main_run_smoother(enkf_main_type * enkf_main , const char * target_fs_name , bool rerun) { - bool initialize = enkf_main_is_not_initialized_at_all( enkf_main ); + bool force_init = false; int ens_size = enkf_main_get_ensemble_size( enkf_main ); - if (initialize) { + { stringlist_type * param_list = ensemble_config_alloc_keylist_from_var_type( enkf_main->ensemble_config , PARAMETER ); - enkf_main_initialize_from_scratch( enkf_main , param_list , 0 , ens_size - 1); + enkf_main_initialize_from_scratch( enkf_main , param_list , 0 , ens_size - 1 , force_init); stringlist_free( param_list ); } @@ -1765,18 +1793,19 @@ static void * enkf_main_initialize_from_scratch_mt(void * void_arg) { stringlist_type * param_list = arg_pack_iget_ptr( arg_pack , 1 ); int iens1 = arg_pack_iget_int( arg_pack , 2 ); int iens2 = arg_pack_iget_int( arg_pack , 3 ); + bool force_init = arg_pack_iget_bool( arg_pack , 4 ); int iens; for (iens = iens1; iens < iens2; iens++) { enkf_state_type * state = enkf_main_iget_state( enkf_main , iens); - enkf_state_initialize( state , enkf_main_get_fs( enkf_main ) , param_list ); + enkf_state_initialize( state , enkf_main_get_fs( enkf_main ) , param_list , force_init); } return NULL; } -void enkf_main_initialize_from_scratch(enkf_main_type * enkf_main , const stringlist_type * param_list , int iens1 , int iens2) { +void enkf_main_initialize_from_scratch(enkf_main_type * enkf_main , const stringlist_type * param_list , int iens1 , int iens2, bool force_init) { int num_cpu = 4; thread_pool_type * tp = thread_pool_alloc( num_cpu , true ); int ens_sub_size = (iens2 - iens1 + 1) / num_cpu; @@ -1800,6 +1829,7 @@ void enkf_main_initialize_from_scratch(enkf_main_type * enkf_main , const string arg_pack_append_int( arg_list[i] , start_iens ); arg_pack_append_int( arg_list[i] , end_iens ); } + arg_pack_append_bool( arg_list[i] , force_init ); thread_pool_add_job( tp , enkf_main_initialize_from_scratch_mt , arg_list[i]); } thread_pool_join( tp ); @@ -1811,6 +1841,9 @@ void enkf_main_initialize_from_scratch(enkf_main_type * enkf_main , const string } + + + /** This function creates a local_config file corresponding to the default 'ALL_ACTIVE' configuration. We eat our own dogshit around @@ -1892,34 +1925,28 @@ void enkf_main_create_all_active_config( const enkf_main_type * enkf_main , -static config_type * enkf_main_alloc_config( bool site_only , bool strict ) { - config_type * config = config_alloc(); +static void enkf_main_init_user_config( const enkf_main_type * enkf_main , config_type * config ) { config_schema_item_type * item; /*****************************************************************/ - /* config_add_schema_item(): */ + /* config_add_schema_item(): */ /* */ /* 1. boolean - required? */ - /* 2. boolean - append? */ /*****************************************************************/ - site_config_add_config_items( config , site_only ); - if (site_only) - return config; /* <---------------- return statement here! */ - - - + ert_workflow_list_add_config_items( config ); plot_config_add_config_items( config ); analysis_config_add_config_items( config ); - ensemble_config_add_config_items(config); + ensemble_config_add_config_items( config ); ecl_config_add_config_items( config ); rng_config_add_config_items( config ); /*****************************************************************/ /* Required keywords from the ordinary model_config file */ - item = config_add_schema_item(config , CASE_TABLE_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1, (const config_item_types [1]) {CONFIG_EXISTING_FILE}); + item = config_add_schema_item(config , CASE_TABLE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); config_add_key_value( config , LOG_LEVEL_KEY , false , CONFIG_INT); config_add_key_value( config , LOG_FILE_KEY , false , CONFIG_STRING); @@ -1927,8 +1954,9 @@ static config_type * enkf_main_alloc_config( bool site_only , bool strict ) { config_add_key_value(config , MAX_RESAMPLE_KEY , false , CONFIG_INT); - item = config_add_schema_item(config , NUM_REALIZATIONS_KEY , true , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1, (const config_item_types [1]) {CONFIG_INT}); + item = config_add_schema_item(config , NUM_REALIZATIONS_KEY , true ); + config_schema_item_set_argc_minmax(item , 1 , 1); + config_schema_item_iset_type( item , 0 , CONFIG_INT ); config_add_alias(config , NUM_REALIZATIONS_KEY , "SIZE"); config_add_alias(config , NUM_REALIZATIONS_KEY , "NUM_REALISATIONS"); config_install_message(config , "SIZE" , "** Warning: \'SIZE\' is depreceated - use \'NUM_REALIZATIONS\' instead."); @@ -1937,56 +1965,61 @@ static config_type * enkf_main_alloc_config( bool site_only , bool strict ) { /*****************************************************************/ /* Optional keywords from the model config file */ - item = config_add_schema_item( config , RUN_TEMPLATE_KEY , false , true ); - config_schema_item_set_argc_minmax(item , 2 , -1 , 2 , (const config_item_types [2]) { CONFIG_EXISTING_FILE , CONFIG_STRING }); /* Force the template to exist at boot time. */ + item = config_add_schema_item( config , RUN_TEMPLATE_KEY , false ); + config_schema_item_set_argc_minmax(item , 2 , CONFIG_DEFAULT_ARG_MAX ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); config_add_key_value(config , RUNPATH_KEY , false , CONFIG_STRING); config_add_key_value(config , RERUN_PATH_KEY , false , CONFIG_STRING); - item = config_add_schema_item(config , ENSPATH_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); + item = config_add_schema_item(config , ENSPATH_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); - item = config_add_schema_item( config , JOBNAME_KEY , false , false ); - config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); + item = config_add_schema_item( config , JOBNAME_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); - item = config_add_schema_item(config , SELECT_CASE_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); + item = config_add_schema_item(config , SELECT_CASE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); - item = config_add_schema_item(config , DBASE_TYPE_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1, 1 , 0 , NULL); - config_schema_item_set_common_selection_set(item , 3 , (const char *[3]) {"PLAIN" , "SQLITE" , "BLOCK_FS"}); + item = config_add_schema_item(config , DBASE_TYPE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1, 1 ); + config_schema_item_set_common_selection_set(item , 2 , (const char *[2]) {"PLAIN" , "BLOCK_FS"}); - item = config_add_schema_item(config , FORWARD_MODEL_KEY , false , true); - config_schema_item_set_argc_minmax(item , 1 , -1 , 0 , NULL); + item = config_add_schema_item(config , FORWARD_MODEL_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , CONFIG_DEFAULT_ARG_MAX); - item = config_add_schema_item(config , DATA_KW_KEY , false , true); - config_schema_item_set_argc_minmax(item , 2 , 2 , 0 , NULL); + item = config_add_schema_item(config , DATA_KW_KEY , false ); + config_schema_item_set_argc_minmax(item , 2 , 2); - item = config_add_schema_item(config , KEEP_RUNPATH_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , -1 , 0 , NULL); + item = config_add_schema_item(config , KEEP_RUNPATH_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , CONFIG_DEFAULT_ARG_MAX); - config_add_key_value(config , PRE_CLEAR_RUNPATH_KEY , false , CONFIG_BOOLEAN); + config_add_key_value(config , PRE_CLEAR_RUNPATH_KEY , false , CONFIG_BOOL); - item = config_add_schema_item(config , DELETE_RUNPATH_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , -1 , 0 , NULL); + item = config_add_schema_item(config , DELETE_RUNPATH_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , CONFIG_DEFAULT_ARG_MAX); - item = config_add_schema_item(config , OBS_CONFIG_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) { CONFIG_EXISTING_FILE}); + item = config_add_schema_item(config , OBS_CONFIG_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); - item = config_add_schema_item(config , RFT_CONFIG_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) { CONFIG_EXISTING_FILE}); + item = config_add_schema_item(config , RFT_CONFIG_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); - item = config_add_schema_item(config , RFTPATH_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); + item = config_add_schema_item(config , RFTPATH_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); - item = config_add_schema_item(config , LOCAL_CONFIG_KEY , false , true); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) { CONFIG_EXISTING_FILE}); + item = config_add_schema_item(config , LOCAL_CONFIG_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); - item = config_add_schema_item(config , ENKF_SCHED_FILE_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) { CONFIG_EXISTING_FILE}); + item = config_add_schema_item(config , ENKF_SCHED_FILE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); - item = config_add_schema_item(config , HISTORY_SOURCE_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); + item = config_add_schema_item(config , HISTORY_SOURCE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1); { stringlist_type * refcase_dep = stringlist_alloc_argv_ref( (const char *[1]) { REFCASE_KEY } , 1); @@ -1996,28 +2029,9 @@ static config_type * enkf_main_alloc_config( bool site_only , bool strict ) { stringlist_free(refcase_dep); } - /*****************************************************************/ - /* Report */ - item = config_add_schema_item(config , REPORT_LIST_KEY , false , true); - config_schema_item_set_argc_minmax(item , 1 , -1 , 0 , NULL); - - item = config_add_schema_item(config , REPORT_CONTEXT_KEY , false , true); - config_schema_item_set_argc_minmax(item , 2 , 2 , 0 , NULL); - item = config_add_schema_item(config , REPORT_PATH_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); - - item = config_add_schema_item( config , REPORT_WELL_LIST_KEY , false , true ); - config_schema_item_set_argc_minmax(item , 1 , -1 , 0 , NULL); - - item = config_add_schema_item( config , REPORT_GROUP_LIST_KEY , false , true ); - config_schema_item_set_argc_minmax(item , 1 , -1 , 0 , NULL); - /*****************************************************************/ - /* QC */ - item = config_add_schema_item( config , QC_PATH_KEY , false , false ); - config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); - - return config; + ert_report_list_add_config_items( config); + qc_module_add_config_items( config ); } @@ -2052,29 +2066,25 @@ void enkf_main_parse_keep_runpath(enkf_main_type * enkf_main , const char * keep int i; for (i = 0; i < ens_size; i++) int_vector_iset( enkf_main->keep_runpath , i , DEFAULT_KEEP); + { - int * active_list; - int num_items; + int_vector_type * active_list = string_util_alloc_active_list(keep_runpath_string); - active_list = util_sscanf_alloc_active_list(keep_runpath_string , &num_items); - for (i = 0; i < num_items; i++) - int_vector_iset( enkf_main->keep_runpath , i , EXPLICIT_KEEP); + for (i = 0; i < int_vector_size( active_list ); i++) + int_vector_iset( enkf_main->keep_runpath , int_vector_iget( active_list , i ) , EXPLICIT_KEEP); - - free( active_list ); + int_vector_free( active_list ); } { - int * active_list; - int num_items; + int_vector_type * active_list = string_util_alloc_active_list(delete_runpath_string); - active_list = util_sscanf_alloc_active_list(delete_runpath_string , &num_items); - for (i = 0; i < num_items; i++) - int_vector_iset( enkf_main->keep_runpath , i , EXPLICIT_DELETE); + for (i = 0; i < int_vector_size( active_list ); i++) + int_vector_iset( enkf_main->keep_runpath , int_vector_iget( active_list , i ) , EXPLICIT_DELETE); - free( active_list ); + int_vector_free( active_list ); } } @@ -2102,11 +2112,30 @@ void enkf_main_clear_data_kw( enkf_main_type * enkf_main ) { subst_list_clear( enkf_main->subst_list ); } +static void enkf_main_add_subst_kw( enkf_main_type * enkf_main , const char * key , const char * value, const char * help_text , bool insert_copy) { + char * tagged_key = util_alloc_sprintf( INTERNAL_DATA_KW_TAG_FORMAT , key ); + + if (insert_copy) + subst_list_append_owned_ref( enkf_main->subst_list , tagged_key , util_alloc_string_copy( value ), help_text); + else + subst_list_append_ref( enkf_main->subst_list , tagged_key , value , help_text); + + free(tagged_key); +} + +static void enkf_main_init_workflow_list( enkf_main_type * enkf_main , config_type * config ) { + ert_workflow_list_init( enkf_main->workflow_list , config , enkf_main->logh); +} + + +static void enkf_main_init_qc( enkf_main_type * enkf_main , config_type * config ) { + qc_module_init( enkf_main->qc_module , config ); + enkf_main_add_subst_kw( enkf_main , "QC_PATH" , qc_module_get_path( enkf_main->qc_module ) , "QC Root path" , true); +} static void enkf_main_init_subst_list( enkf_main_type * enkf_main ) { /* Here we add the functions which should be available for string substitution operations. */ - enkf_main->subst_func_pool = subst_func_pool_alloc( enkf_main->rng ); subst_func_pool_add_func( enkf_main->subst_func_pool , "EXP" , "exp" , subst_func_exp , false , 1 , 1 , NULL); subst_func_pool_add_func( enkf_main->subst_func_pool , "LOG" , "log" , subst_func_log , false , 1 , 1 , NULL); subst_func_pool_add_func( enkf_main->subst_func_pool , "POW10" , "Calculates 10^x" , subst_func_pow10 , false , 1 , 1 , NULL); @@ -2114,7 +2143,7 @@ static void enkf_main_init_subst_list( enkf_main_type * enkf_main ) { subst_func_pool_add_func( enkf_main->subst_func_pool , "MUL" , "Multiplies arguments" , subst_func_mul , true , 1 , 0 , NULL); subst_func_pool_add_func( enkf_main->subst_func_pool , "RANDINT" , "Returns a random integer - 32 bit" , subst_func_randint , false , 0 , 0 , enkf_main->rng); subst_func_pool_add_func( enkf_main->subst_func_pool , "RANDFLOAT" , "Returns a random float 0-1." , subst_func_randfloat , false , 0 , 0 , enkf_main->rng); - + /** Allocating the parent subst_list instance. This will (should ...) be the top level subst instance for all substitions in the ert @@ -2131,7 +2160,7 @@ static void enkf_main_init_subst_list( enkf_main_type * enkf_main ) { o Constant in time. */ - enkf_main->subst_list = subst_list_alloc( enkf_main->subst_func_pool ); + /* Installing the functions. */ subst_list_insert_func( enkf_main->subst_list , "EXP" , "__EXP__"); subst_list_insert_func( enkf_main->subst_list , "LOG" , "__LOG__"); @@ -2144,7 +2173,7 @@ static void enkf_main_init_subst_list( enkf_main_type * enkf_main ) { -static enkf_main_type * enkf_main_alloc_empty( ) { +enkf_main_type * enkf_main_alloc_empty( ) { enkf_main_type * enkf_main = util_malloc(sizeof * enkf_main); UTIL_TYPE_ID_INIT(enkf_main , ENKF_MAIN_ID); enkf_main->current_fs_case = NULL; @@ -2154,33 +2183,44 @@ static enkf_main_type * enkf_main_alloc_empty( ) { enkf_main->site_config_file = NULL; enkf_main->rft_config_file = NULL; enkf_main->local_config = NULL; + enkf_main->rng = NULL; enkf_main->ens_size = 0; enkf_main->keep_runpath = int_vector_alloc( 0 , DEFAULT_KEEP ); - enkf_main->logh = log_alloc_existing( NULL , DEFAULT_LOG_LEVEL ); + enkf_main->logh = log_open( NULL , DEFAULT_LOG_LEVEL ); enkf_main->rng_config = rng_config_alloc( ); + enkf_main->site_config = site_config_alloc_empty(); + enkf_main->ensemble_config = ensemble_config_alloc_empty(); + enkf_main->ecl_config = ecl_config_alloc_empty(); + enkf_main->plot_config = plot_config_alloc_default(); + enkf_main->ranking_table = ranking_table_alloc( 0 ); + enkf_main->obs = enkf_obs_alloc( ); + enkf_main->model_config = model_config_alloc_empty( ); + + enkf_main_rng_init( enkf_main ); + enkf_main->subst_func_pool = subst_func_pool_alloc( ); + enkf_main->subst_list = subst_list_alloc( enkf_main->subst_func_pool ); + enkf_main->templates = ert_templates_alloc( enkf_main->subst_list ); + enkf_main->workflow_list = ert_workflow_list_alloc( enkf_main->subst_list ); + enkf_main->qc_module = qc_module_alloc( enkf_main->workflow_list , DEFAULT_QC_PATH ); + enkf_main->analysis_config = analysis_config_alloc_default( enkf_main->rng ); + enkf_main->report_list = ert_report_list_alloc( DEFAULT_REPORT_PATH , plot_config_get_path( enkf_main->plot_config ) ); + enkf_main_init_subst_list( enkf_main ); enkf_main_set_verbose( enkf_main , true ); - enkf_main->site_config = site_config_alloc_empty(); - enkf_main->ensemble_config = ensemble_config_alloc_empty(); - enkf_main->ecl_config = ecl_config_alloc_empty(); - enkf_main->qc_config = qc_config_alloc( DEFAULT_QC_PATH ); - enkf_main->model_config = model_config_alloc_empty(); - enkf_main->analysis_config = analysis_config_alloc_default( enkf_main->rng ); /* This is ready for use. */ - enkf_main->plot_config = plot_config_alloc_default(); /* This is ready for use. */ - enkf_main->report_list = ert_report_list_alloc( DEFAULT_REPORT_PATH , plot_config_get_path( enkf_main->plot_config ) ); - enkf_main->ranking_table = ranking_table_alloc( 0 ); + printf("enkf_main->subst_list :%p \n",enkf_main->subst_list); return enkf_main; } + static void enkf_main_install_data_kw( enkf_main_type * enkf_main , hash_type * config_data_kw) { /* Installing the DATA_KW keywords supplied by the user - these are at the very top level, so they can reuse everything defined later. */ - { + if (config_data_kw) { hash_iter_type * iter = hash_iter_alloc(config_data_kw); const char * key = hash_iter_get_next_key(iter); while (key != NULL) { @@ -2197,26 +2237,18 @@ static void enkf_main_install_data_kw( enkf_main_type * enkf_main , hash_type * ensemble members, and independent of time. */ { - char * cwd = util_alloc_cwd(); - char * date_string = util_alloc_date_stamp(); - - char * cwd_key = util_alloc_sprintf( INTERNAL_DATA_KW_TAG_FORMAT , "CWD" ); - char * config_path_key = util_alloc_sprintf( INTERNAL_DATA_KW_TAG_FORMAT , "CONFIG_PATH" ); - char * date_key = util_alloc_sprintf( INTERNAL_DATA_KW_TAG_FORMAT , "DATE" ); - char * num_cpu_key = util_alloc_sprintf( INTERNAL_DATA_KW_TAG_FORMAT , "NUM_CPU" ); - char * num_cpu_string = "1"; + char * cwd = util_alloc_cwd(); + char * date_string = util_alloc_date_stamp(); + const char * num_cpu_string = "1"; + + enkf_main_add_subst_kw( enkf_main , "CWD" , cwd , "The current working directory we are running from - the location of the config file." , true); + enkf_main_add_subst_kw( enkf_main , "CONFIG_PATH" , cwd , "The current working directory we are running from - the location of the config file." , false); + enkf_main_add_subst_kw( enkf_main , "DATE" , date_string , "The current date." , true); + enkf_main_add_subst_kw( enkf_main , "NUM_CPU" , num_cpu_string , "The number of CPU used for one forward model." , true ); + enkf_main_add_subst_kw( enkf_main , "RUNPATH_FILE" , qc_module_get_runpath_list_file( enkf_main->qc_module ) , "The name of a file with a list of run directories." , true); - - subst_list_append_owned_ref( enkf_main->subst_list , cwd_key , cwd , "The current working directory we are running from - the location of the config file."); - subst_list_append_ref( enkf_main->subst_list , config_path_key , cwd , "The current working directory we are running from - the location of the config file."); - subst_list_append_owned_ref( enkf_main->subst_list , date_key , date_string , "The current date"); - subst_list_append_ref( enkf_main->subst_list , num_cpu_key , num_cpu_string , "The number of CPU used for one forward model."); - - - free( num_cpu_key ); - free( cwd_key ); - free( config_path_key ); - free( date_key ); + //free( cwd ); + //free( date_string ); } } @@ -2393,6 +2425,7 @@ char * enkf_main_alloc_mount_point( const enkf_main_type * enkf_main , const cha return mount_point; } + void enkf_main_set_fs( enkf_main_type * enkf_main , enkf_fs_type * fs , const char * case_path ) { if (enkf_main->dbase != fs) { if (enkf_main->dbase != NULL) @@ -2402,6 +2435,7 @@ void enkf_main_set_fs( enkf_main_type * enkf_main , enkf_fs_type * fs , const ch enkf_main_link_current_fs__( enkf_main , case_path); enkf_main->current_fs_case = util_realloc_string_copy( enkf_main->current_fs_case , case_path); enkf_main_gen_data_special( enkf_main ); + enkf_main_add_subst_kw( enkf_main , "CASE" , enkf_main->current_fs_case , "Current case" , true ); } } @@ -2609,7 +2643,7 @@ void enkf_main_update_obs_keys( enkf_main_type * enkf_main ) { void enkf_main_set_log_file( enkf_main_type * enkf_main , const char * log_file ) { - log_reset_filename( enkf_main->logh , log_file); + log_reopen( enkf_main->logh , log_file); } @@ -2646,9 +2680,15 @@ static void enkf_main_init_log( enkf_main_type * enkf_main , const config_type * } static void enkf_main_init_data_kw( enkf_main_type * enkf_main , config_type * config ) { - hash_type * data_kw = config_alloc_hash(config , DATA_KW_KEY); + config_content_item_type * data_item = config_get_content_item( config , DATA_KW_KEY ); + hash_type * data_kw = NULL; + if (data_item) + data_kw = config_content_item_alloc_hash(data_item , true); + enkf_main_install_data_kw( enkf_main , data_kw ); - hash_free( data_kw ); + + if (data_kw) + hash_free( data_kw ); } @@ -2658,24 +2698,54 @@ static void enkf_main_init_data_kw( enkf_main_type * enkf_main , config_type * c /*****************************************************************/ -void enkf_main_rng_init( enkf_main_type * enkf_main) { - const char * seed_load = rng_config_get_seed_load_file( enkf_main->rng_config ); - const char * seed_store = rng_config_get_seed_store_file( enkf_main->rng_config ); - enkf_main->rng = rng_alloc( rng_config_get_type(enkf_main->rng_config) , INIT_DEFAULT); - - if (seed_load != NULL) { - FILE * stream = util_fopen( seed_load , "r"); - rng_fscanf_state( enkf_main->rng , stream ); - fclose( stream ); - } else - rng_init( enkf_main->rng , INIT_DEV_RANDOM ); - +rng_config_type * enkf_main_get_rng_config( const enkf_main_type * enkf_main ) { + return enkf_main->rng_config; +} - if (seed_store != NULL) { - FILE * stream = util_mkdir_fopen( seed_store , "w"); - rng_fprintf_state( enkf_main->rng , stream ); - fclose( stream ); +void enkf_main_rng_init( enkf_main_type * enkf_main) { + if (enkf_main->rng != NULL) { + rng_free( enkf_main->rng ); + enkf_main->rng = NULL; } + enkf_main->rng = rng_config_alloc_rng( enkf_main->rng_config ); +} + + +void enkf_main_init_local_updates( enkf_main_type * enkf_main , const config_type * config ) { + if (model_config_has_history( enkf_main->model_config )) { + enkf_main->local_config = local_config_alloc( ); + + /* First create the default ALL_ACTIVE configuration. */ + { + char * all_active_config_file = util_alloc_tmp_file("/tmp" , "enkf_local_config" , true); + enkf_main_create_all_active_config( enkf_main , + all_active_config_file ); + + /* Install custom local_config - if present.*/ + { + int i; + for (i = 0; i < config_get_occurences( config , LOCAL_CONFIG_KEY); i++) { + const stringlist_type * files = config_iget_stringlist_ref(config , LOCAL_CONFIG_KEY , i); + for (int j=0; j < stringlist_get_size( files ); j++) + local_config_add_config_file( enkf_main->local_config , stringlist_iget( files , j) ); + } + } + + /** + This is where the local configuration files are actually parsed. + */ + local_config_reload( enkf_main->local_config , + ecl_config_get_grid( enkf_main->ecl_config ), + enkf_main->ensemble_config , + enkf_main->obs , + all_active_config_file ); + + unlink( all_active_config_file ); + free(all_active_config_file); + } + } else + if (config_get_occurences( config , LOCAL_CONFIG_KEY) > 0) + fprintf(stderr,"** Warning: Not possible to configure local analysis without SCHEDULE or REFCASE - %s keyword(s) ignored\n", LOCAL_CONFIG_KEY); } @@ -2688,31 +2758,24 @@ void enkf_main_rng_init( enkf_main_type * enkf_main) { */ -static void enkf_main_bootstrap_site(enkf_main_type * enkf_main , const char * site_config_file , bool strict) { - char * cwd = util_alloc_cwd(); - { - +static void enkf_main_bootstrap_site(enkf_main_type * enkf_main , const char * site_config_file) { + if (site_config_file != NULL) { + if (!util_file_exists(site_config_file)) util_exit("%s: can not locate site configuration file:%s \n",__func__ , site_config_file); + config_type * config = config_alloc(); { - char * site_config_path; - util_alloc_file_components( site_config_file , &site_config_path , NULL , NULL ); - if (site_config_path != NULL) { - if (chdir( site_config_path ) != 0) - util_abort("s: holy diver - could not chdir() to directory:%s containing the site configuration. \n",__func__ , site_config_path); + site_config_add_config_items( config , true ); + if (config_parse(config , site_config_file , "--" , INCLUDE_KEY , DEFINE_KEY , CONFIG_UNRECOGNIZED_WARN , false)) { + site_config_init( enkf_main->site_config , config ); + ert_report_list_site_init( enkf_main->report_list , config ); + ert_workflow_list_init( enkf_main->workflow_list , config , enkf_main->logh); + } else { + fprintf(stderr , "** ERROR: Parsing site configuration file:%s failed \n\n" , site_config_file); + config_fprintf_errors( config , true , stderr ); + exit(1); } - util_safe_free( site_config_path ); } - - { - config_type * config = enkf_main_alloc_config( true , strict ); - config_parse(config , site_config_file , "--" , INCLUDE_KEY , DEFINE_KEY , true , false); - site_config_init( enkf_main->site_config , config , false); /* <---- site_config : first pass. */ - ert_report_list_site_init( enkf_main->report_list , config ); - config_free( config ); - } - + config_free( config ); } - chdir( cwd ); - free( cwd ); } @@ -2760,9 +2823,9 @@ enkf_main_type * enkf_main_bootstrap(const char * _site_config, const char * _mo if (site_config == NULL) site_config = _site_config; - + if (site_config == NULL) - util_exit("%s: main enkf_config file is not set. Use environment variable \"ERT_SITE_CONFIG\" - or recompile - aborting.\n",__func__); + fprintf(stderr,"**WARNING** main enkf_config file is not set. Use environment variable \"ERT_SITE_CONFIG\" - or recompile.\n"); { char * path; @@ -2797,23 +2860,28 @@ enkf_main_type * enkf_main_bootstrap(const char * _site_config, const char * _mo } - if (!util_file_exists(site_config)) util_exit("%s: can not locate site configuration file:%s \n",__func__ , site_config); if (!util_file_exists(model_config)) util_exit("%s: can not locate user configuration file:%s \n",__func__ , model_config); { - enkf_main = enkf_main_alloc_empty( ); config_type * config; - /* Parsing the site_config file first */ + enkf_main = enkf_main_alloc_empty( ); enkf_main_set_verbose( enkf_main , verbose ); - enkf_main_bootstrap_site( enkf_main , site_config , strict ); + enkf_main_bootstrap_site( enkf_main , site_config); - - config = enkf_main_alloc_config( false , strict ); + config = config_alloc(); + enkf_main_init_user_config( enkf_main , config ); + site_config_add_config_items( config , false ); site_config_init_user_mode( enkf_main->site_config ); - config_parse(config , model_config , "--" , INCLUDE_KEY , DEFINE_KEY , true , true); - site_config_init( enkf_main->site_config , config , true ); /* <---- model_config : second pass. */ + + if (!config_parse(config , model_config , "--" , INCLUDE_KEY , DEFINE_KEY , CONFIG_UNRECOGNIZED_WARN , true)) { + config_fprintf_errors( config , true , stderr ); + exit(1); + } + + site_config_init( enkf_main->site_config , config ); /* <---- model_config : second pass. */ /*****************************************************************/ - /* OK - now we have parsed everything - and we are ready to start + /* + OK - now we have parsed everything - and we are ready to start populating the enkf_main object. */ @@ -2827,6 +2895,8 @@ enkf_main_type * enkf_main_bootstrap(const char * _site_config, const char * _mo rng_config_init( enkf_main->rng_config , config ); enkf_main_rng_init( enkf_main ); /* Must be called before the ensmeble is created. */ enkf_main_init_subst_list( enkf_main ); + ert_workflow_list_init( enkf_main->workflow_list , config , enkf_main->logh ); + enkf_main_init_qc( enkf_main , config ); enkf_main_init_data_kw( enkf_main , config ); analysis_config_load_internal_modules( enkf_main->analysis_config ); @@ -2834,7 +2904,7 @@ enkf_main_type * enkf_main_bootstrap(const char * _site_config, const char * _mo ecl_config_init( enkf_main->ecl_config , config ); plot_config_init( enkf_main->plot_config , config ); ensemble_config_init( enkf_main->ensemble_config , config , ecl_config_get_grid( enkf_main->ecl_config ) , ecl_config_get_refcase( enkf_main->ecl_config) ); - qc_config_init( enkf_main->qc_config , config ); + model_config_init( enkf_main->model_config , config , enkf_main_get_ensemble_size( enkf_main ), @@ -2844,11 +2914,13 @@ enkf_main_type * enkf_main_bootstrap(const char * _site_config, const char * _mo ecl_config_get_refcase( enkf_main->ecl_config )); enkf_main_update_num_cpu( enkf_main ); { - if (config_item_set( config , SCHEDULE_PREDICTION_FILE_KEY)) { - stringlist_type * tokens = config_iget_stringlist_ref(config , SCHEDULE_PREDICTION_FILE_KEY , 0); - const char * template_file = stringlist_iget(tokens , 0); + const config_content_item_type * pred_item = config_get_content_item( config , SCHEDULE_PREDICTION_FILE_KEY ); + if (pred_item != NULL) { + const config_content_node_type * pred_node = config_content_item_get_last_node( pred_item ); + const char * template_file = config_content_node_iget_as_path( pred_node , 0 ); { - hash_type * opt_hash = hash_alloc_from_options( tokens ); + hash_type * opt_hash = hash_alloc(); + config_content_node_init_opt_hash( pred_node , opt_hash , 1 ); const char * parameters = hash_safe_get( opt_hash , "PARAMETERS" ); const char * min_std = hash_safe_get( opt_hash , "MIN_STD" ); @@ -2884,10 +2956,10 @@ enkf_main_type * enkf_main_bootstrap(const char * _site_config, const char * _mo char * delete_runpath_string = NULL; int ens_size = config_get_value_as_int(config , NUM_REALIZATIONS_KEY); - if (config_has_set_item(config , KEEP_RUNPATH_KEY)) + if (config_item_set(config , KEEP_RUNPATH_KEY)) keep_runpath_string = config_alloc_joined_string(config , KEEP_RUNPATH_KEY , ""); - if (config_has_set_item(config , DELETE_RUNPATH_KEY)) + if (config_item_set(config , DELETE_RUNPATH_KEY)) delete_runpath_string = config_alloc_joined_string(config , DELETE_RUNPATH_KEY , ""); enkf_main_parse_keep_runpath( enkf_main , keep_runpath_string , delete_runpath_string , ens_size ); @@ -2899,43 +2971,16 @@ enkf_main_type * enkf_main_bootstrap(const char * _site_config, const char * _mo /* This is really in the wrong place ... */ { enkf_main->pre_clear_runpath = DEFAULT_PRE_CLEAR_RUNPATH; - if (config_has_set_item(config , PRE_CLEAR_RUNPATH_KEY)) + if (config_item_set(config , PRE_CLEAR_RUNPATH_KEY)) enkf_main->pre_clear_runpath = config_get_value_as_bool( config , PRE_CLEAR_RUNPATH_KEY); } - - - if (config_has_set_item(config , STATIC_KW_KEY)) { - for (int i=0; i < config_get_occurences(config , STATIC_KW_KEY); i++) { - const stringlist_type * static_kw_list = config_iget_stringlist_ref(config , STATIC_KW_KEY , i); - int k; - for (k = 0; k < stringlist_get_size(static_kw_list); k++) - ecl_config_add_static_kw(enkf_main->ecl_config , stringlist_iget( static_kw_list , k)); - } - } - + ecl_config_static_kw_init( enkf_main->ecl_config , config ); + /* Installing templates */ { - enkf_main->templates = ert_templates_alloc( enkf_main->subst_list ); - for (int i=0; i < config_get_occurences( config , RUN_TEMPLATE_KEY); i++) { - const char * template_file = config_iget( config , RUN_TEMPLATE_KEY , i , 0); - const char * target_file = config_iget( config , RUN_TEMPLATE_KEY , i , 1); - ert_template_type * template = ert_templates_add_template( enkf_main->templates , NULL , template_file , target_file , NULL); - - for (int iarg = 2; iarg < config_get_occurence_size( config , RUN_TEMPLATE_KEY , i); iarg++) { - char * key , *value; - util_binary_split_string( config_iget( config , RUN_TEMPLATE_KEY , i , iarg ), "=:" , true , &key , &value); - - if (value != NULL) - ert_template_add_arg( template ,key , value ); - else - fprintf(stderr,"** Warning - failed to parse argument:%s as key:value - ignored \n",config_iget( config , "RUN_TEMPLATE" , i , iarg )); - - free( key ); - util_safe_free( value ); - } - } + ert_templates_init( enkf_main->templates , config ); } /*****************************************************************/ @@ -2943,12 +2988,11 @@ enkf_main_type * enkf_main_bootstrap(const char * _site_config, const char * _mo { const char * obs_config_file; - if (config_has_set_item(config , OBS_CONFIG_KEY)) + if (config_item_set(config , OBS_CONFIG_KEY)) obs_config_file = config_iget(config , OBS_CONFIG_KEY , 0,0); else obs_config_file = NULL; - enkf_main->obs = enkf_obs_alloc( model_config_get_history(enkf_main->model_config), analysis_config_get_std_cutoff(enkf_main->analysis_config) ); enkf_main_load_obs( enkf_main , obs_config_file ); } @@ -2956,7 +3000,7 @@ enkf_main_type * enkf_main_bootstrap(const char * _site_config, const char * _mo { const char * rft_config_file = NULL; - if (config_has_set_item(config , RFT_CONFIG_KEY)) + if (config_item_set(config , RFT_CONFIG_KEY)) rft_config_file = config_iget(config , RFT_CONFIG_KEY , 0,0); enkf_main_set_rft_config_file( enkf_main , rft_config_file ); @@ -2974,7 +3018,7 @@ enkf_main_type * enkf_main_bootstrap(const char * _site_config, const char * _mo /* Adding ensemble members */ enkf_main_resize_ensemble( enkf_main , config_iget_as_int(config , NUM_REALIZATIONS_KEY , 0 , 0) ); - + /*****************************************************************/ /* Installing the local_config object. Observe that the @@ -2982,47 +3026,15 @@ enkf_main_type * enkf_main_bootstrap(const char * _site_config, const char * _mo if you have created a personal local config that will be loaded on top. */ - - if (model_config_has_history( enkf_main->model_config )) { - enkf_main->local_config = local_config_alloc( /*enkf_main->ensemble_config , enkf_main->enkf_obs , */ model_config_get_last_history_restart( enkf_main->model_config )); - - /* First create the default ALL_ACTIVE configuration. */ - { - char * all_active_config_file = util_alloc_tmp_file("/tmp" , "enkf_local_config" , true); - enkf_main_create_all_active_config( enkf_main , - all_active_config_file ); - - /* Install custom local_config - if present.*/ - { - int i; - for (i = 0; i < config_get_occurences( config , LOCAL_CONFIG_KEY); i++) { - const stringlist_type * files = config_iget_stringlist_ref(config , LOCAL_CONFIG_KEY , i); - for (int j=0; j < stringlist_get_size( files ); j++) - local_config_add_config_file( enkf_main->local_config , stringlist_iget( files , j) ); - } - } - - /** - This is where the local configuration files are actually parsed. - */ - local_config_reload( enkf_main->local_config , - ecl_config_get_grid( enkf_main->ecl_config ), - enkf_main->ensemble_config , - enkf_main->obs , - all_active_config_file ); - - unlink( all_active_config_file ); - free(all_active_config_file); - } - } else - if (config_get_occurences( config , LOCAL_CONFIG_KEY) > 0) - fprintf(stderr,"** Warning: Not possible to configure local analysis without SCHEDULE or REFCASE - %s keyword(s) ignored\n", LOCAL_CONFIG_KEY); + enkf_main_init_local_updates(enkf_main , config ); + } config_free(config); } enkf_main_init_jobname( enkf_main ); enkf_main_gen_data_special( enkf_main ); free( model_config ); + return enkf_main; } @@ -3469,8 +3481,31 @@ void enkf_main_fprintf_config( const enkf_main_type * enkf_main ) { enkf_main_log_fprintf_config( enkf_main , stream ); site_config_fprintf_config( enkf_main->site_config , stream ); rng_config_fprintf_config( enkf_main->rng_config , stream ); - ert_report_list_free( enkf_main->report_list ); fclose( stream ); } } + +/*****************************************************************/ + +ert_workflow_list_type * enkf_main_get_workflow_list( enkf_main_type * enkf_main ) { + return enkf_main->workflow_list; +} + + +bool enkf_main_run_workflow( enkf_main_type * enkf_main , const char * workflow) { + ert_workflow_list_type * workflow_list = enkf_main_get_workflow_list( enkf_main ); + if (ert_workflow_list_has_workflow( workflow_list , workflow)) + return ert_workflow_list_run_workflow( workflow_list , workflow , enkf_main ); + else + return false; +} + + +void enkf_main_run_workflows( enkf_main_type * enkf_main , const stringlist_type * workflows) { + int iw; + for (iw = 0; iw < stringlist_get_size( workflows ); iw++) + enkf_main_run_workflow( enkf_main , stringlist_iget( workflows , iw )); +} + + diff --git a/ThirdParty/Ert/devel/libenkf/src/enkf_main_jobs.c b/ThirdParty/Ert/devel/libenkf/src/enkf_main_jobs.c new file mode 100644 index 0000000000..608cef8583 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/src/enkf_main_jobs.c @@ -0,0 +1,63 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'enkf_main_jobs.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 + +#include + + +void enkf_main_exit_JOB(void * self , const stringlist_type * args ) { + enkf_main_type * enkf_main = enkf_main_safe_cast( self ); + enkf_main_exit( enkf_main ); +} + + + +void enkf_main_ensemble_run_JOB( void * self , const stringlist_type * args ) { + enkf_main_type * enkf_main = enkf_main_safe_cast( self ); + int ens_size = enkf_main_get_ensemble_size( enkf_main ); + bool_vector_type * iactive = bool_vector_alloc( 0 , true ); + + // Ignore args until string_utils is in place ..... + // if (stringlist_get_size( args ) + + bool_vector_iset( iactive , ens_size - 1 , true ); + enkf_main_run_exp( enkf_main , iactive , true , 0 , 0 , ANALYZED ); +} + + +void enkf_main_smoother_JOB( void * self , const stringlist_type * args ) { + enkf_main_type * enkf_main = enkf_main_safe_cast( self ); + int ens_size = enkf_main_get_ensemble_size( enkf_main ); + bool_vector_type * iactive = bool_vector_alloc( 0 , true ); + bool rerun = true; + const char * target_case = "AUTO-SMOOTHER"; + + bool_vector_iset( iactive , ens_size - 1 , true ); + enkf_main_run_smoother( enkf_main , target_case , rerun); +} + + + +void enkf_main_create_reports_JOB(void * self , const stringlist_type * args ) { + enkf_main_type * enkf_main = enkf_main_safe_cast( self ); + ert_report_list_type * report_list = enkf_main_get_report_list( enkf_main ); + + ert_report_list_create( report_list , enkf_main_get_current_fs( enkf_main ) , true ); +} + diff --git a/ThirdParty/Ert/devel/libenkf/src/enkf_obs.c b/ThirdParty/Ert/devel/libenkf/src/enkf_obs.c index 5f28267de3..f95cc2340a 100644 --- a/ThirdParty/Ert/devel/libenkf/src/enkf_obs.c +++ b/ThirdParty/Ert/devel/libenkf/src/enkf_obs.c @@ -185,7 +185,6 @@ struct enkf_obs_struct { bool have_obs; char * config_file; /* The name of the config file which has been loaded. */ hash_type * obs_hash; - double std_cutoff; /* (Dimensionfull) Std values below this limit are considered zero. */ time_t_vector_type * obs_time; /* For fast lookup of report_step -> obs_time */ const history_type * history; /* A shared (not owned by enkf_obs) reference to the history object - used when adding HISTORY observations. */ @@ -197,19 +196,20 @@ struct enkf_obs_struct { -enkf_obs_type * enkf_obs_alloc( const history_type * history , double std_cutoff ) +enkf_obs_type * enkf_obs_alloc( ) { enkf_obs_type * enkf_obs = util_malloc(sizeof * enkf_obs); enkf_obs->have_obs = false; enkf_obs->obs_hash = hash_alloc(); - enkf_obs->std_cutoff = std_cutoff; - enkf_obs->history = history; enkf_obs->obs_time = time_t_vector_alloc(0 , -1 ); + + enkf_obs->history = NULL; enkf_obs->config_file = NULL; return enkf_obs; } + bool enkf_obs_have_obs( const enkf_obs_type * enkf_obs ) { return enkf_obs->have_obs; } @@ -440,8 +440,13 @@ void enkf_obs_get_obs_and_measure(const enkf_obs_type * enkf_obs, -void enkf_obs_reload( enkf_obs_type * enkf_obs , const ecl_grid_type * grid , const ecl_sum_type * refcase , ensemble_config_type * ensemble_config ) { - enkf_obs_load( enkf_obs , enkf_obs->config_file , grid , refcase , ensemble_config ); +void enkf_obs_reload( enkf_obs_type * enkf_obs , + const history_type * history , + const ecl_grid_type * grid , + const ecl_sum_type * refcase , + double std_cutoff , + ensemble_config_type * ensemble_config ) { + enkf_obs_load( enkf_obs , history , enkf_obs->config_file , grid , refcase , std_cutoff , ensemble_config ); } @@ -456,11 +461,18 @@ void enkf_obs_reload( enkf_obs_type * enkf_obs , const ecl_grid_type * grid , co -void enkf_obs_load(enkf_obs_type * enkf_obs , const char * config_file, const ecl_grid_type * grid , const ecl_sum_type * refcase , ensemble_config_type * ensemble_config) { +void enkf_obs_load(enkf_obs_type * enkf_obs , + const history_type * history , + const char * config_file, + const ecl_grid_type * grid , + const ecl_sum_type * refcase , + double std_cutoff , ensemble_config_type * ensemble_config) { + if (config_file == NULL) { hash_clear( enkf_obs->obs_hash ); enkf_obs->have_obs = false; } else { + enkf_obs->history = history; if ( enkf_obs->history == NULL) { fprintf(stderr,"** ERROR: When loading obervations you must provide either REFCASE or a SCHEDULE file.\n"); fprintf(stderr,"** The observations in obs file:%s will be ignored \n",config_file); @@ -493,7 +505,7 @@ void enkf_obs_load(enkf_obs_type * enkf_obs , const char * config_file, const e if (config_node != NULL) { obs_vector = obs_vector_alloc( SUMMARY_OBS , obs_key , ensemble_config_get_node( ensemble_config , obs_key ) , enkf_obs->obs_time , last_report); if (obs_vector != NULL) { - if (obs_vector_load_from_HISTORY_OBSERVATION(obs_vector , hist_obs_conf , enkf_obs->history , ensemble_config , enkf_obs->std_cutoff )) + if (obs_vector_load_from_HISTORY_OBSERVATION(obs_vector , hist_obs_conf , enkf_obs->history , ensemble_config , std_cutoff )) enkf_obs_add_obs_vector(enkf_obs, obs_key, obs_vector); else { fprintf(stderr,"** Could not load historical data for observation:%s - ignored\n",obs_key); diff --git a/ThirdParty/Ert/devel/libenkf/src/enkf_state.c b/ThirdParty/Ert/devel/libenkf/src/enkf_state.c index 23cac00826..639524d057 100644 --- a/ThirdParty/Ert/devel/libenkf/src/enkf_state.c +++ b/ThirdParty/Ert/devel/libenkf/src/enkf_state.c @@ -279,14 +279,17 @@ static void shared_info_free(shared_info_type * shared_info) { /** Helper classes complete - starting on the enkf_state proper object. */ /*****************************************************************/ -void enkf_state_initialize(enkf_state_type * enkf_state , enkf_fs_type * fs , const stringlist_type * param_list) { +void enkf_state_initialize(enkf_state_type * enkf_state , enkf_fs_type * fs , const stringlist_type * param_list, bool force_init) { + state_enum init_state = ANALYZED; int ip; for (ip = 0; ip < stringlist_get_size(param_list); ip++) { int iens = enkf_state_get_iens( enkf_state ); enkf_node_type * param_node = enkf_state_get_node( enkf_state , stringlist_iget( param_list , ip)); - if (enkf_node_initialize( param_node , iens , enkf_state->rng)) { - node_id_type node_id = {.report_step = 0, .iens = iens , .state = ANALYZED }; - enkf_node_store( param_node , fs , true , node_id); + node_id_type node_id = {.report_step = 0, .iens = iens , .state = init_state }; + if (force_init || (enkf_node_has_data( param_node , fs , node_id) == false)) { + if (enkf_node_initialize( param_node , iens , enkf_state->rng)) + enkf_node_store( param_node , fs , true , node_id); + } } } @@ -359,7 +362,6 @@ void enkf_state_update_eclbase( enkf_state_type * enkf_state ) { enkf_state_add_subst_kw( enkf_state , "CASE" , eclbase , NULL); /* No CASE_TABLE loaded - using the eclbase as default. */ else enkf_state_add_subst_kw( enkf_state , "CASE" , casename , NULL); - } } @@ -498,7 +500,7 @@ enkf_state_type * enkf_state_alloc(int iens, done in a cascade like fashion). The user defined keywords are added first, so that these can refer to the built in keywords. */ - + enkf_state_add_subst_kw(enkf_state , "RUNPATH" , "---" , "The absolute path of the current forward model instance. "); enkf_state_add_subst_kw(enkf_state , "IENS" , "---" , "The realisation number for this realization."); enkf_state_add_subst_kw(enkf_state , "IENS4" , "---" , "The realization number for this realization - formated with %04d."); @@ -518,23 +520,16 @@ enkf_state_type * enkf_state_alloc(int iens, enkf_state_add_subst_kw(enkf_state , "CASE" , casename , "The casename for this realization - as loaded from the CASE_TABLE file."); else enkf_state_add_subst_kw(enkf_state , "CASE" , "---" , "The casename for this realization - similar to ECLBASE."); - + enkf_state->my_config = member_config_alloc( iens , casename , pre_clear_runpath , keep_runpath , ecl_config , ensemble_config , fs); enkf_state_set_static_subst_kw( enkf_state ); - enkf_state_add_nodes( enkf_state , ensemble_config ); - + return enkf_state; } -enkf_state_type * enkf_state_copyc(const enkf_state_type * src) { - util_abort("%s: not implemented \n",__func__); - return NULL; -} - - static bool enkf_state_has_node(const enkf_state_type * enkf_state , const char * node_key) { bool has_node = hash_has_key(enkf_state->node_hash , node_key); @@ -589,12 +584,17 @@ void enkf_state_update_node( enkf_state_type * enkf_state , const char * node_ke } +const char * enkf_state_get_eclbase( const enkf_state_type * enkf_state ) { + return member_config_get_eclbase( enkf_state->my_config ); +} + + static ecl_sum_type * enkf_state_load_ecl_sum(const enkf_state_type * enkf_state , stringlist_type * messages , bool * loadOK) { member_config_type * my_config = enkf_state->my_config; const run_info_type * run_info = enkf_state->run_info; const ecl_config_type * ecl_config = enkf_state->shared_info->ecl_config; const bool fmt_file = ecl_config_get_formatted(ecl_config); - const char * eclbase = member_config_get_eclbase( my_config ); + const char * eclbase = enkf_state_get_eclbase( enkf_state ); stringlist_type * data_files = stringlist_alloc_new(); @@ -739,7 +739,7 @@ static bool enkf_state_internalize_dynamic_eclipse_results(enkf_state_type * enk } { time_map_type * time_map = enkf_fs_get_time_map( fs ); - time_map_summary_update( time_map , summary ); + time_map_summary_update_strict( time_map , summary ); } ecl_sum_free( summary ); return true; @@ -1661,26 +1661,29 @@ static void enkf_state_start_forward_model(enkf_state_type * enkf_state , enkf_f const shared_info_type * shared_info = enkf_state->shared_info; const member_config_type * my_config = enkf_state->my_config; const site_config_type * site_config = shared_info->site_config; - arg_pack_type * load_arg = arg_pack_alloc(); - - /* - Prepare the job and submit it to the queue - */ enkf_state_init_eclipse( enkf_state , fs ); - arg_pack_append_ptr( load_arg , enkf_state ); - arg_pack_append_ptr( load_arg , fs ); - - run_info->queue_index = job_queue_add_job_mt( shared_info->job_queue , - site_config_get_job_script( site_config ), - enkf_state_complete_forward_modelOK__ , - enkf_state_complete_forward_modelEXIT__ , - load_arg , - ecl_config_get_num_cpu( shared_info->ecl_config ), - run_info->run_path , - member_config_get_jobname(my_config) , - 1, - (const char *[1]) { run_info->run_path } ); - run_info->num_internal_submit++; + + if (run_info->run_mode != INIT_ONLY) { + arg_pack_type * load_arg = arg_pack_alloc(); + + /* + Prepare the job and submit it to the queue + */ + arg_pack_append_ptr( load_arg , enkf_state ); + arg_pack_append_ptr( load_arg , fs ); + + run_info->queue_index = job_queue_add_job_mt( shared_info->job_queue , + site_config_get_job_script( site_config ), + enkf_state_complete_forward_modelOK__ , + enkf_state_complete_forward_modelEXIT__ , + load_arg , + ecl_config_get_num_cpu( shared_info->ecl_config ), + run_info->run_path , + member_config_get_jobname(my_config) , + 1, + (const char *[1]) { run_info->run_path } ); + run_info->num_internal_submit++; + } } } @@ -2034,15 +2037,11 @@ void enkf_state_init_run(enkf_state_type * state , -/*****************************************************************/ -/** - This function will return the true time (i.e. time_t instance) - cooresponding to the report_step 'report_step'. If no data has been - loaded for the input report_step -1 is returned, this must be - checked by the calling scope. -*/ +unsigned int enkf_state_get_random( enkf_state_type * enkf_state ) { + return rng_forward( enkf_state->rng ); +} diff --git a/ThirdParty/Ert/devel/libenkf/src/ensemble_config.c b/ThirdParty/Ert/devel/libenkf/src/ensemble_config.c index da935d4bec..d6567ba483 100644 --- a/ThirdParty/Ert/devel/libenkf/src/ensemble_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/ensemble_config.c @@ -138,6 +138,7 @@ ensemble_config_type * ensemble_config_alloc_empty( ) { ensemble_config_type * ensemble_config = util_malloc(sizeof * ensemble_config ); ensemble_config->config_nodes = hash_alloc(); + ensemble_config->field_trans_table = field_trans_table_alloc(); ensemble_config->refcase = NULL; ensemble_config->gen_kw_format_string = util_alloc_string_copy( DEFAULT_GEN_KW_TAG_FORMAT ); pthread_mutex_init( &ensemble_config->mutex , NULL); @@ -147,6 +148,19 @@ ensemble_config_type * ensemble_config_alloc_empty( ) { +void ensemble_config_free(ensemble_config_type * ensemble_config) { + hash_free( ensemble_config->config_nodes ); + field_trans_table_free( ensemble_config->field_trans_table ); + free( ensemble_config->gen_kw_format_string ); + free( ensemble_config ); +} + + + + + + + ert_impl_type ensemble_config_impl_type(const ensemble_config_type *ensemble_config, const char * ecl_kw_name) { ert_impl_type impl_type = INVALID; @@ -176,16 +190,6 @@ enkf_var_type ensemble_config_var_type(const ensemble_config_type *ensemble_conf -void ensemble_config_free(ensemble_config_type * ensemble_config) { - hash_free( ensemble_config->config_nodes ); - field_trans_table_free( ensemble_config->field_trans_table ); - free( ensemble_config->gen_kw_format_string ); - free( ensemble_config ); -} - - - - bool ensemble_config_has_key(const ensemble_config_type * ensemble_config , const char * key) { @@ -284,6 +288,13 @@ void ensemble_config_clear_obs_keys(ensemble_config_type * ensemble_config) { +void ensemble_config_add_GEN_PARAM_config_item( config_type * config ) { + config_schema_item_type * item; + item = config_add_schema_item(config , GEN_PARAM_KEY , false ); + config_schema_item_set_argc_minmax(item , 5 , CONFIG_DEFAULT_ARG_MAX); +} + + void ensemble_config_add_config_items(config_type * config) { config_schema_item_type * item; @@ -292,174 +303,247 @@ void ensemble_config_add_config_items(config_type * config) { be able to print suitable messages before exiting. */ - item = config_add_schema_item(config , "HAVANA_FAULT" , false , true); - config_schema_item_set_argc_minmax(item , 2 , 2 , 0 , NULL ); + item = config_add_schema_item(config , "HAVANA_FAULT" , false ); + config_schema_item_set_argc_minmax(item , 2 , 2); - item = config_add_schema_item(config , "MULTFLT" , false , true); - config_schema_item_set_argc_minmax(item , 3 , 3 , 3 , (const config_item_types [3]) { CONFIG_STRING , CONFIG_STRING , CONFIG_EXISTING_FILE}); + item = config_add_schema_item(config , "MULTFLT" , false ); + config_schema_item_set_argc_minmax(item , 3 , 3 ); + config_schema_item_iset_type( item , 2 , CONFIG_EXISTING_PATH ); /*****************************************************************/ - item = config_add_schema_item(config , GEN_KW_KEY , false , true); - config_schema_item_set_argc_minmax(item , 4 , 6 , 6 , (const config_item_types [6]) { CONFIG_STRING , CONFIG_EXISTING_FILE , CONFIG_STRING , CONFIG_EXISTING_FILE , CONFIG_STRING , CONFIG_STRING}); + ensemble_config_add_GEN_PARAM_config_item( config ); + item = config_add_schema_item(config , GEN_KW_KEY , false ); + config_schema_item_set_argc_minmax(item , 4 , 6); + config_schema_item_iset_type( item , 1 , CONFIG_EXISTING_PATH ); + config_schema_item_iset_type( item , 3 , CONFIG_EXISTING_PATH ); + + + item = config_add_key_value( config , GEN_KW_TAG_FORMAT_KEY , false , CONFIG_STRING); - - item = config_add_schema_item(config , SCHEDULE_PREDICTION_FILE_KEY , false , false); + item = config_add_schema_item(config , SCHEDULE_PREDICTION_FILE_KEY , false ); /* scedhule_prediction_file filename */ - config_schema_item_set_argc_minmax(item , 1 , 3 , 3 , (const config_item_types [3]) { CONFIG_EXISTING_FILE , CONFIG_STRING , CONFIG_STRING}); - - item = config_add_schema_item(config , GEN_PARAM_KEY , false , true); - config_schema_item_set_argc_minmax(item , 5 , -1 , 0 , NULL); + config_schema_item_set_argc_minmax(item , 1 , 3 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); - item = config_add_schema_item(config , GEN_DATA_KEY , false , true); - config_schema_item_set_argc_minmax(item , 1 , -1 , 0 , NULL); - item = config_add_schema_item(config , SUMMARY_KEY , false , true); /* can have several summary keys on each line. */ - config_schema_item_set_argc_minmax(item , 1 , -1 , 0 , NULL); - item = config_add_schema_item(config , CONTAINER_KEY , false , true); /* can have several summary keys on each line. */ - config_schema_item_set_argc_minmax(item , 2 , -1 , 0 , NULL); - item = config_add_schema_item( config , SURFACE_KEY , false , true ); - config_schema_item_set_argc_minmax(item , 4 , 5 , 0 , NULL); + item = config_add_schema_item(config , GEN_DATA_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , CONFIG_DEFAULT_ARG_MAX); + + item = config_add_schema_item(config , SUMMARY_KEY , false ); /* can have several summary keys on each line. */ + config_schema_item_set_argc_minmax(item , 1 , CONFIG_DEFAULT_ARG_MAX); + + item = config_add_schema_item(config , CONTAINER_KEY , false ); /* can have several summary keys on each line. */ + config_schema_item_set_argc_minmax(item , 2 , CONFIG_DEFAULT_ARG_MAX); + + item = config_add_schema_item( config , SURFACE_KEY , false ); + config_schema_item_set_argc_minmax(item , 4 , 5 ); /* the way config info is entered for fields is unfortunate because it is difficult/impossible to let the config system handle run time validation of the input. */ - item = config_add_schema_item(config , FIELD_KEY , false , true); - config_schema_item_set_argc_minmax(item , 2 , -1 , 0 , NULL); + item = config_add_schema_item(config , FIELD_KEY , false ); + config_schema_item_set_argc_minmax(item , 2 , CONFIG_DEFAULT_ARG_MAX); config_schema_item_add_required_children(item , GRID_KEY); /* if you are using a field - you must have a grid. */ } -/** - observe that if the user has not given a refcase with the refcase - key the refcase pointer will be NULL. in that case it will be - impossible to use wildcards when expanding summary variables. -*/ - -void ensemble_config_init(ensemble_config_type * ensemble_config , const config_type * config , ecl_grid_type * grid, const ecl_sum_type * refcase) { - int i; - ensemble_config->field_trans_table = field_trans_table_alloc(); - ensemble_config_set_refcase( ensemble_config , refcase ); - - if (config_item_set( config , GEN_KW_TAG_FORMAT_KEY)) - ensemble_config_set_gen_kw_format( ensemble_config , config_iget( config , GEN_KW_TAG_FORMAT_KEY , 0 , 0 )); - - /* gen_param - should be unified with the gen_data*/ - for (i=0; i < config_get_occurences(config , GEN_PARAM_KEY); i++) { - stringlist_type * tokens = config_iget_stringlist_ref(config , GEN_PARAM_KEY , i); - const char * key = stringlist_iget(tokens , 0); - const char * ecl_file = stringlist_iget(tokens , 1); /* only difference from gen_data is that the ecl_file is not a ":" keyword. */ - enkf_config_node_type * config_node = ensemble_config_add_gen_data( ensemble_config , key ); - { - hash_type * options = hash_alloc_from_options( tokens ); - gen_data_file_format_type input_format = gen_data_config_check_format( hash_safe_get( options , INPUT_FORMAT_KEY)); - gen_data_file_format_type output_format = gen_data_config_check_format( hash_safe_get( options , OUTPUT_FORMAT_KEY)); - const char * init_file_fmt = hash_safe_get( options , INIT_FILES_KEY); - const char * template = hash_safe_get( options , TEMPLATE_KEY); - const char * key = hash_safe_get( options , KEY_KEY); - const char * result_file = hash_safe_get( options , RESULT_FILE_KEY); - const char * min_std_file = hash_safe_get( options , MIN_STD_KEY); - - enkf_config_node_update_gen_data( config_node , input_format , output_format , init_file_fmt , template , key , ecl_file , result_file , min_std_file); +void ensemble_config_init_GEN_DATA( ensemble_config_type * ensemble_config , const config_type * config ) { +/* gen_param - should be unified with the gen_data*/ + const config_content_item_type * item = config_get_content_item( config , GEN_DATA_KEY ); + if (item != NULL) { + int i; + for (i=0; i < config_content_item_get_size(item); i++) { + const config_content_node_type * node = config_content_item_iget_node( item , i ); + const char * key = config_content_node_iget( node , 0 ); + enkf_config_node_type * config_node = ensemble_config_add_gen_data( ensemble_config , key ); { - const gen_data_config_type * gen_data_config = enkf_config_node_get_ref( config_node ); - if (!gen_data_config_is_valid( gen_data_config )) - util_abort("%s: sorry the gen_param key:%s is not valid \n",__func__ , key); - } - hash_free( options ); - } - } - - /* gen_data */ - for (i=0; i < config_get_occurences(config , GEN_DATA_KEY); i++) { - stringlist_type * tokens = config_iget_stringlist_ref(config , GEN_DATA_KEY , i); - const char * key = stringlist_iget(tokens , 0); - enkf_config_node_type * config_node = ensemble_config_add_gen_data( ensemble_config , key ); - { - hash_type * options = hash_alloc_from_options( tokens ); - gen_data_file_format_type input_format = gen_data_config_check_format( hash_safe_get( options , INPUT_FORMAT_KEY)); - gen_data_file_format_type output_format = gen_data_config_check_format( hash_safe_get( options , OUTPUT_FORMAT_KEY)); - const char * init_file_fmt = hash_safe_get( options , INIT_FILES_KEY); - const char * template = hash_safe_get( options , TEMPLATE_KEY); - const char * key = hash_safe_get( options , KEY_KEY); - const char * ecl_file = hash_safe_get( options , ECL_FILE_KEY); - const char * result_file = hash_safe_get( options , RESULT_FILE_KEY); - const char * min_std_file = hash_safe_get( options , MIN_STD_KEY); - - enkf_config_node_update_gen_data( config_node , - input_format , - output_format , - init_file_fmt , - template , - key , - ecl_file , - result_file , - min_std_file); - { - const gen_data_config_type * gen_data_config = enkf_config_node_get_ref( config_node ); - if (!gen_data_config_is_valid( gen_data_config )) - util_abort("%s: sorry the gen_data key:%s is not valid \n",__func__ , key); - } - hash_free( options ); - } - } - - - /* surface */ - { - for (i=0; i < config_get_occurences( config , SURFACE_KEY ); i++) { - stringlist_type * tokens = config_iget_stringlist_ref(config , SURFACE_KEY , i); - const char * key = stringlist_iget(tokens , 0); - { - hash_type * options = hash_alloc_from_options( tokens ); /* INIT_FILE: OUTPUT_FILE: BASE_SURFACE: */ - - const char * init_file_fmt = hash_safe_get( options , INIT_FILES_KEY ); - const char * output_file = hash_safe_get( options , OUTPUT_FILE_KEY); - const char * base_surface = hash_safe_get( options , BASE_SURFACE_KEY); - const char * min_std_file = hash_safe_get( options , MIN_STD_KEY); - - if ((init_file_fmt == NULL) || (output_file == NULL) || (base_surface == NULL)) { - fprintf(stderr,"** error: when entering a surface you must provide arguments:\n"); - fprintf(stderr,"** %s:/path/to/input/files%%d \n",INIT_FILES_KEY); - fprintf(stderr,"** %s:name_of_output_file\n", OUTPUT_FILE_KEY); - fprintf(stderr,"** %s:base_surface_file\n",base_surface); - exit(1); - } - - { - enkf_config_node_type * config_node = ensemble_config_add_surface( ensemble_config , key ); - enkf_config_node_update_surface( config_node , base_surface , init_file_fmt , output_file , min_std_file ); - } + hash_type * options = hash_alloc(); + config_content_node_init_opt_hash( node , options , 1 ); + { + gen_data_file_format_type input_format = gen_data_config_check_format( hash_safe_get( options , INPUT_FORMAT_KEY)); + gen_data_file_format_type output_format = gen_data_config_check_format( hash_safe_get( options , OUTPUT_FORMAT_KEY)); + const char * init_file_fmt = hash_safe_get( options , INIT_FILES_KEY); + const char * ecl_file = hash_safe_get( options , ECL_FILE_KEY); + const char * template = hash_safe_get( options , TEMPLATE_KEY); + const char * key = hash_safe_get( options , KEY_KEY); + const char * result_file = hash_safe_get( options , RESULT_FILE_KEY); + const char * min_std_file = hash_safe_get( options , MIN_STD_KEY); + + enkf_config_node_update_gen_data( config_node , input_format , output_format , init_file_fmt , template , key , ecl_file , result_file , min_std_file); + { + const gen_data_config_type * gen_data_config = enkf_config_node_get_ref( config_node ); + if (!gen_data_config_is_valid( gen_data_config )) + util_abort("%s: sorry the gen_param key:%s is not valid \n",__func__ , key); + } + } hash_free( options ); } } } +} + + +void ensemble_config_init_GEN_PARAM( ensemble_config_type * ensemble_config , const config_type * config ) { + /* gen_param - should be unified with the gen_data*/ + const config_content_item_type * item = config_get_content_item( config , GEN_PARAM_KEY ); + if (item != NULL) { + int i; + for (i=0; i < config_content_item_get_size(item); i++) { + const config_content_node_type * node = config_content_item_iget_node( item , i ); + const char * key = config_content_node_iget( node , 0 ); + const char * ecl_file = config_content_node_iget( node , 1 ); + enkf_config_node_type * config_node = ensemble_config_add_gen_data( ensemble_config , key ); + { + hash_type * options = hash_alloc(); + + config_content_node_init_opt_hash( node , options , 2 ); + { + gen_data_file_format_type input_format = gen_data_config_check_format( hash_safe_get( options , INPUT_FORMAT_KEY)); + gen_data_file_format_type output_format = gen_data_config_check_format( hash_safe_get( options , OUTPUT_FORMAT_KEY)); + const char * init_file_fmt = hash_safe_get( options , INIT_FILES_KEY); + const char * template = hash_safe_get( options , TEMPLATE_KEY); + const char * key = hash_safe_get( options , KEY_KEY); + const char * result_file = hash_safe_get( options , RESULT_FILE_KEY); + const char * min_std_file = hash_safe_get( options , MIN_STD_KEY); + + enkf_config_node_update_gen_data( config_node , input_format , output_format , init_file_fmt , template , key , ecl_file , result_file , min_std_file); + { + const gen_data_config_type * gen_data_config = enkf_config_node_get_ref( config_node ); + if (!gen_data_config_is_valid( gen_data_config )) + util_abort("%s: sorry the gen_param key:%s is not valid \n",__func__ , key); + } + } + hash_free( options ); + } + } + } +} + + +void ensemble_config_init_GEN_KW( ensemble_config_type * ensemble_config , const config_type * config ) { + const config_content_item_type * gen_kw_item = config_get_content_item( config , GEN_KW_KEY ); + if (gen_kw_item != NULL) { + int i; + for (i=0; i < config_content_item_get_size( gen_kw_item ); i++) { + config_content_node_type * node = config_content_item_iget_node( gen_kw_item , i ); + + const char * key = config_content_node_iget( node , 0 ); + const char * template_file = config_content_node_iget_as_path( node , 1 ); + const char * enkf_outfile = config_content_node_iget( node , 2 ); + const char * parameter_file = config_content_node_iget_as_path( node , 3 ); + + { + hash_type * opt_hash = hash_alloc(); + enkf_config_node_type * config_node = ensemble_config_add_gen_kw( ensemble_config , key ); + config_content_node_init_opt_hash( node , opt_hash , 4 ); + enkf_config_node_update_gen_kw( config_node , + enkf_outfile , + template_file , + parameter_file , + hash_safe_get( opt_hash , MIN_STD_KEY ) , + hash_safe_get( opt_hash , INIT_FILES_KEY)); + hash_free( opt_hash ); + } + } + } +} +void ensemble_config_init_SURFACE( ensemble_config_type * ensemble_config , const config_type * config ) { + const config_content_item_type * item = config_get_content_item( config , SURFACE_KEY ); + if (item != NULL) { + int i; + for (i=0; i < config_content_item_get_size( item ); i++) { + const config_content_node_type * node = config_content_item_iget_node( item , i ); + const char * key = config_content_node_iget( node , 0 ); + { + hash_type * options = hash_alloc(); /* INIT_FILE: OUTPUT_FILE: BASE_SURFACE: */ + + config_content_node_init_opt_hash( node , options , 1 ); + { + const char * init_file_fmt = hash_safe_get( options , INIT_FILES_KEY ); + const char * output_file = hash_safe_get( options , OUTPUT_FILE_KEY); + const char * base_surface = hash_safe_get( options , BASE_SURFACE_KEY); + const char * min_std_file = hash_safe_get( options , MIN_STD_KEY); + + if ((init_file_fmt == NULL) || (output_file == NULL) || (base_surface == NULL)) { + fprintf(stderr,"** error: when entering a surface you must provide arguments:\n"); + fprintf(stderr,"** %s:/path/to/input/files%%d \n",INIT_FILES_KEY); + fprintf(stderr,"** %s:name_of_output_file\n", OUTPUT_FILE_KEY); + fprintf(stderr,"** %s:base_surface_file\n",base_surface); + exit(1); + } + + { + enkf_config_node_type * config_node = ensemble_config_add_surface( ensemble_config , key ); + enkf_config_node_update_surface( config_node , base_surface , init_file_fmt , output_file , min_std_file ); + } + } + hash_free( options ); + } + } + } +} - /* field */ - { - for (i=0; i < config_get_occurences(config , FIELD_KEY); i++) { - stringlist_type * tokens = config_iget_stringlist_ref(config , FIELD_KEY , i); - const char * key = stringlist_iget(tokens , 0); - const char * var_type_string = stringlist_iget(tokens , 1); - enkf_config_node_type * config_node = ensemble_config_add_field( ensemble_config , key , grid ); + +void ensemble_config_init_SUMMARY( ensemble_config_type * ensemble_config , const config_type * config , const ecl_sum_type * refcase) { + const config_content_item_type * item = config_get_content_item( config , SUMMARY_KEY ); + + if (item != NULL) { + int i; + for (i=0; i < config_content_item_get_size( item ); i++) { + const config_content_node_type * node = config_content_item_iget_node( item , i ); + int j; + for (j= 0; j < config_content_node_get_size( node ); j++) { + const char * key = config_content_node_iget( node , j ); + + if (util_string_has_wildcard( key )) { + if (ensemble_config->refcase != NULL) { + int k; + stringlist_type * keys = stringlist_alloc_new ( ); + + ecl_sum_select_matching_general_var_list( ensemble_config->refcase , key , keys ); /* expanding the wildcard notatition with help of the refcase. */ + for (k=0; k < stringlist_get_size( keys ); k++) + ensemble_config_add_summary(ensemble_config , stringlist_iget(keys , k) , LOAD_FAIL_SILENT ); + + stringlist_free( keys ); + } else + util_exit("error: when using summary wildcards like: \"%s\" you must supply a valid refcase.\n",key); + } else + ensemble_config_add_summary(ensemble_config , key , LOAD_FAIL_SILENT); + } + } + } +} + + +void ensemble_config_init_FIELD( ensemble_config_type * ensemble_config , const config_type * config , ecl_grid_type * grid) { + const config_content_item_type * item = config_get_content_item( config , FIELD_KEY ); + if (item != NULL) { + int i; + for (i=0; i < config_content_item_get_size( item ); i++) { + const config_content_node_type * node = config_content_item_iget_node( item , i ); + const char * key = config_content_node_iget( node , 0 ); + const char * var_type_string = config_content_node_iget( node , 1 ); + enkf_config_node_type * config_node = ensemble_config_add_field( ensemble_config , key , grid ); { - hash_type * options = hash_alloc_from_options( tokens ); + hash_type * options = hash_alloc(); int truncation = TRUNCATE_NONE; double value_min = -1; double value_max = -1; + config_content_node_init_opt_hash( node , options , 2 ); if (hash_has_key( options , MIN_KEY)) { truncation |= TRUNCATE_MIN; value_min = atof(hash_get( options , MIN_KEY)); @@ -474,12 +558,12 @@ void ensemble_config_init(ensemble_config_type * ensemble_config , const config_ if (strcmp(var_type_string , DYNAMIC_KEY) == 0) enkf_config_node_update_state_field( config_node , truncation , value_min , value_max ); else if (strcmp(var_type_string , PARAMETER_KEY) == 0) { - const char * ecl_file = stringlist_iget(tokens , 2); + const char * ecl_file = config_content_node_iget( node , 2 ); const char * init_file_fmt = hash_safe_get( options , INIT_FILES_KEY ); const char * init_transform = hash_safe_get( options , INIT_TRANSFORM_KEY ); const char * output_transform = hash_safe_get( options , OUTPUT_TRANSFORM_KEY ); const char * min_std_file = hash_safe_get( options , MIN_STD_KEY ); - + enkf_config_node_update_parameter_field( config_node, ecl_file , init_file_fmt , @@ -490,8 +574,8 @@ void ensemble_config_init(ensemble_config_type * ensemble_config , const config_ init_transform , output_transform ); } else if (strcmp(var_type_string , GENERAL_KEY) == 0) { - const char * ecl_file = stringlist_iget(tokens , 2); - const char * enkf_infile = stringlist_iget(tokens , 3); + const char * ecl_file = config_content_node_iget( node , 2 ); + const char * enkf_infile = config_content_node_iget( node , 3 ); const char * init_file_fmt = hash_safe_get( options , INIT_FILES_KEY ); const char * init_transform = hash_safe_get( options , INIT_TRANSFORM_KEY ); const char * output_transform = hash_safe_get( options , OUTPUT_TRANSFORM_KEY ); @@ -517,63 +601,31 @@ void ensemble_config_init(ensemble_config_type * ensemble_config , const config_ } } } +} - /* gen_kw */ - for (i=0; i < config_get_occurences(config , GEN_KW_KEY); i++) { - stringlist_type * tokens = config_iget_stringlist_ref(config , GEN_KW_KEY , i); - char * key = stringlist_iget_copy(tokens , 0); - char * template_file = stringlist_iget_copy(tokens , 1); - char * enkf_outfile = stringlist_iget_copy(tokens , 2); - char * parameter_file = stringlist_iget_copy(tokens , 3); - stringlist_idel( tokens , 0); - stringlist_idel( tokens , 0); - stringlist_idel( tokens , 0); - stringlist_idel( tokens , 0); - { - hash_type * opt_hash = hash_alloc_from_options( tokens ); - enkf_config_node_type * config_node = ensemble_config_add_gen_kw( ensemble_config , key ); - enkf_config_node_update_gen_kw( config_node , - enkf_outfile , - template_file , - parameter_file , - hash_safe_get( opt_hash , MIN_STD_KEY ) , - hash_safe_get( opt_hash , INIT_FILES_KEY)); - hash_free( opt_hash ); - } + +/** + observe that if the user has not given a refcase with the refcase + key the refcase pointer will be NULL. in that case it will be + impossible to use wildcards when expanding summary variables. +*/ + +void ensemble_config_init(ensemble_config_type * ensemble_config , const config_type * config , ecl_grid_type * grid, const ecl_sum_type * refcase) { + int i; + ensemble_config_set_refcase( ensemble_config , refcase ); + + if (config_item_set( config , GEN_KW_TAG_FORMAT_KEY)) + ensemble_config_set_gen_kw_format( ensemble_config , config_iget( config , GEN_KW_TAG_FORMAT_KEY , 0 , 0 )); + + ensemble_config_init_GEN_PARAM( ensemble_config , config ); + ensemble_config_init_GEN_DATA( ensemble_config , config ); + ensemble_config_init_GEN_KW(ensemble_config , config ); + ensemble_config_init_SURFACE( ensemble_config , config ); + ensemble_config_init_SUMMARY( ensemble_config , config , refcase ); + ensemble_config_init_FIELD( ensemble_config , config , grid ); + - free(key); - free(template_file); - free(enkf_outfile); - free(parameter_file); - } - - - /* summary */ - { - stringlist_type * keys = stringlist_alloc_new ( ); - - for (i=0; i < config_get_occurences(config , SUMMARY_KEY ); i++) { - int j,k; - const stringlist_type * summary_kw_list = config_iget_stringlist_ref(config , SUMMARY_KEY , i); - for (j= 0; j < stringlist_get_size( summary_kw_list ); j++) { - const char * key = stringlist_iget( summary_kw_list , j); - - if (util_string_has_wildcard( key )) { - if (ensemble_config->refcase != NULL) { - ecl_sum_select_matching_general_var_list( ensemble_config->refcase , key , keys ); /* expanding the wildcard notatition with help of the refcase. */ - for (k=0; k < stringlist_get_size( keys ); k++) - ensemble_config_add_summary(ensemble_config , stringlist_iget(keys , k) , LOAD_FAIL_SILENT ); - } else - util_exit("error: when using summary wildcards like: \"%s\" you must supply a valid refcase.\n",key); - } else - ensemble_config_add_summary(ensemble_config , key , LOAD_FAIL_SILENT); - } - } - - stringlist_free( keys ); - } - /* Containers - this must come last, to ensure that the other nodes have been added. */ { for (i=0; i < config_get_occurences(config , CONTAINER_KEY ); i++) { @@ -793,7 +845,7 @@ enkf_config_node_type * ensemble_config_add_surface( ensemble_config_type * ense If key == NULL the function will create a random key. */ enkf_config_node_type * ensemble_config_add_container( ensemble_config_type * ensemble_config , const char * key) { - char * local_key = key; + char * local_key = (char *) key; bool random_key = false; if (key == NULL) { local_key = util_calloc( 11 , sizeof * local_key ); diff --git a/ThirdParty/Ert/devel/libenkf/src/ert_report.c b/ThirdParty/Ert/devel/libenkf/src/ert_report.c index 211d8a7ce6..92dba7eee6 100644 --- a/ThirdParty/Ert/devel/libenkf/src/ert_report.c +++ b/ThirdParty/Ert/devel/libenkf/src/ert_report.c @@ -41,7 +41,6 @@ */ #define LATEX_PATH_FMT "/tmp/latex-XXXXXX" #define ERT_REPORT_TYPE_ID 919191653 -#define LATEX_TIMEOUT 20 /* @@ -75,7 +74,6 @@ struct ert_report_struct { UTIL_TYPE_ID_DECLARATION; template_type * template; - int latex_timeout; char * latex_basename; char * input_path; bool with_xref; @@ -96,6 +94,7 @@ static void ert_report_set_work_path( ert_report_type * report ) { ert_report_type * ert_report_alloc( const char * source_file , const char * target_file ) { ert_report_type * report = util_malloc( sizeof * report ); + UTIL_TYPE_ID_INIT(report , ERT_REPORT_TYPE_ID); report->template = template_alloc( source_file , false , NULL ); { @@ -118,7 +117,6 @@ ert_report_type * ert_report_alloc( const char * source_file , const char * targ report->ignore_errors = true; report->target_file = NULL; report->work_path = NULL; - report->latex_timeout = LATEX_TIMEOUT; ert_report_set_work_path( report ); return report; } @@ -135,7 +133,8 @@ static void ert_report_clear( ert_report_type * ert_report , bool mkdir_work_pat -bool ert_report_create( ert_report_type * ert_report , const subst_list_type * context , const char * plot_path , const char * target_path ) { + +bool ert_report_create( ert_report_type * ert_report , int latex_timeout , const subst_list_type * context , const char * plot_path , const char * target_path ) { bool success; { char * latex_file = util_alloc_filename( ert_report->work_path , ert_report->latex_basename , LATEX_EXTENSION ); @@ -144,11 +143,11 @@ bool ert_report_create( ert_report_type * ert_report , const subst_list_type * c latex_type * latex = latex_alloc( latex_file , true ); char * target_file = util_alloc_filename( target_path , ert_report->latex_basename , "pdf"); - latex_set_timeout( latex , ert_report->latex_timeout ); + latex_set_timeout( latex , latex_timeout ); latex_link_directory_content( latex , ert_report->input_path ); latex_link_directory_content( latex , plot_path ); latex_set_target_file( latex , target_file ); - success = latex_compile( latex , ert_report->ignore_errors , ert_report->with_xref); + success = latex_compile( latex , ert_report->ignore_errors , ert_report->with_xref , true); if (success) ert_report->target_file = util_realloc_string_copy( ert_report->target_file , latex_get_target_file( latex )); diff --git a/ThirdParty/Ert/devel/libenkf/src/ert_report_list.c b/ThirdParty/Ert/devel/libenkf/src/ert_report_list.c index 98aa060da4..cb38a1502b 100644 --- a/ThirdParty/Ert/devel/libenkf/src/ert_report_list.c +++ b/ThirdParty/Ert/devel/libenkf/src/ert_report_list.c @@ -33,6 +33,7 @@ #include #include #include +#include #define WELL_LIST_TAG "$WELL_LIST" #define GROUP_LIST_TAG "$GROUP_LIST" @@ -42,6 +43,7 @@ + struct ert_report_list_struct { stringlist_type * path_list; vector_type * report_list; @@ -50,10 +52,36 @@ struct ert_report_list_struct { stringlist_type * well_list; stringlist_type * group_list; subst_list_type * global_context; + int latex_timeout; + bool init_large_report; }; +void ert_report_list_set_latex_timeout( ert_report_list_type * report_list , int timeout) { + report_list->latex_timeout = timeout; +} +int ert_report_list_get_latex_timeout( const ert_report_list_type * report_list ) { + return report_list->latex_timeout; +} + +static void ert_report_list_init_large_report( ert_report_list_type * report_list ) { + if (report_list->init_large_report) { + printf("Running script \'fmtutil --all\' to regenerate pdflatex config information ..... "); + fflush(stdout); + util_fork_exec("fmtutil" , 1 , (const char *[1]) {"--all"} , true , NULL , NULL , NULL , "/dev/null" , "/dev/null"); + printf("\n"); + } + report_list->init_large_report = false; +} + +bool ert_report_list_get_init_large_report( const ert_report_list_type * report_list ) { + return report_list->init_large_report; +} + +void ert_report_list_set_large_report(ert_report_list_type * report_list , bool init_large_report) { + report_list->init_large_report = init_large_report; +} ert_report_list_type * ert_report_list_alloc(const char * target_path, const char * plot_path ) { @@ -62,12 +90,14 @@ ert_report_list_type * ert_report_list_alloc(const char * target_path, const cha report_list->report_list = vector_alloc_new( ); report_list->target_path = NULL; report_list->plot_path = NULL; + report_list->init_large_report = DEFAULT_REPORT_LARGE; report_list->well_list = stringlist_alloc_new(); report_list->group_list = stringlist_alloc_new(); report_list->global_context = subst_list_alloc( NULL ); ert_report_list_set_plot_path( report_list , plot_path ); ert_report_list_set_target_path( report_list , target_path ); + ert_report_list_set_latex_timeout( report_list , DEFAULT_REPORT_TIMEOUT); return report_list; } @@ -189,7 +219,7 @@ char * alloc_list(const stringlist_type * list) { /*****************************************************************/ -void ert_report_list_create( const ert_report_list_type * report_list , const char * current_case , bool verbose ) { +void ert_report_list_create( ert_report_list_type * report_list , const char * current_case , bool verbose ) { if (vector_get_size( report_list->report_list ) > 0) { subst_list_type * context = subst_list_alloc( report_list->global_context ); char * target_path = util_alloc_filename( report_list->target_path , current_case , NULL ); @@ -199,6 +229,7 @@ void ert_report_list_create( const ert_report_list_type * report_list , const ch subst_list_append_owned_ref( context , WELL_LIST_TAG , alloc_list( report_list->well_list ), "The list of wells for plotting"); subst_list_append_owned_ref( context , GROUP_LIST_TAG , alloc_list( report_list->group_list ), "The list of groups for plotting"); + ert_report_list_init_large_report( report_list ); for (int ir = 0; ir < vector_get_size( report_list->report_list ); ir++) { ert_report_type * ert_report = vector_iget( report_list->report_list , ir); @@ -207,7 +238,7 @@ void ert_report_list_create( const ert_report_list_type * report_list , const ch fflush( stdout ); } { - bool success = ert_report_create( vector_iget( report_list->report_list , ir ) , context , report_list->plot_path , target_path ); + bool success = ert_report_create( vector_iget( report_list->report_list , ir ) , report_list->latex_timeout , context , report_list->plot_path , target_path ); if (success) printf("OK??\n"); else @@ -227,11 +258,17 @@ void ert_report_list_site_init( ert_report_list_type * report_list , config_type for (int j=0; j < stringlist_get_size( path_list ); j++) ert_report_list_add_path( report_list , stringlist_iget( path_list , j )); } - } + void ert_report_list_init( ert_report_list_type * report_list , config_type * config , const ecl_sum_type * refcase) { ert_report_list_site_init( report_list , config ); + + if (config_item_set( config , REPORT_LARGE_KEY)) + ert_report_list_set_large_report(report_list , config_get_value_as_bool( config , REPORT_LARGE_KEY )); + + if (config_item_set( config , REPORT_TIMEOUT_KEY)) + ert_report_list_set_latex_timeout( report_list , config_get_value_as_int( config , REPORT_TIMEOUT_KEY )); /* Installing the list of reports. */ for (int i=0; i < config_get_occurences( config , REPORT_LIST_KEY ); i++) { @@ -264,10 +301,37 @@ void ert_report_list_init( ert_report_list_type * report_list , config_type * co } /* Installing the target path for reports*/ - if (config_has_set_item(config , REPORT_PATH_KEY)) + if (config_item_set(config , REPORT_PATH_KEY)) ert_report_list_set_target_path( report_list , config_iget( config , REPORT_PATH_KEY , 0 , 0)); ert_report_list_add_global_context( report_list , CONFIG_FILE_TAG , config_get_config_file( config , true )); ert_report_list_add_global_context( report_list , USER_TAG , getenv("USER")); - +} + + +void ert_report_list_add_config_items( config_type * config ) { + config_schema_item_type * item; + + item = config_add_schema_item(config , REPORT_LIST_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , CONFIG_DEFAULT_ARG_MAX); + + item = config_add_schema_item(config , REPORT_CONTEXT_KEY , false ); + config_schema_item_set_argc_minmax(item , 2 , 2); + + item = config_add_schema_item(config , REPORT_PATH_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1); + + item = config_add_schema_item( config , REPORT_WELL_LIST_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , CONFIG_DEFAULT_ARG_MAX); + + item = config_add_schema_item( config , REPORT_GROUP_LIST_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , CONFIG_DEFAULT_ARG_MAX); + + item = config_add_schema_item( config , REPORT_TIMEOUT_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_INT); + + item = config_add_schema_item( config , REPORT_LARGE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_BOOL); } diff --git a/ThirdParty/Ert/devel/libenkf/src/ert_template.c b/ThirdParty/Ert/devel/libenkf/src/ert_template.c index 196ca905c2..db02b383c4 100644 --- a/ThirdParty/Ert/devel/libenkf/src/ert_template.c +++ b/ThirdParty/Ert/devel/libenkf/src/ert_template.c @@ -211,6 +211,33 @@ stringlist_type * ert_templates_alloc_list( ert_templates_type * ert_templates) } +void ert_templates_init( ert_templates_type * templates , const config_type * config ) { + const config_content_item_type * template_item = config_get_content_item( config , RUN_TEMPLATE_KEY ); + if (template_item != NULL) { + for (int i=0; i < config_content_item_get_size( template_item ); i++) { + config_content_node_type * template_node = config_content_item_iget_node( template_item , i ); + const char * template_file = config_content_node_iget_as_path(template_node , 0 ); + const char * target_file = config_content_node_iget( template_node , 1 ); + + ert_template_type * template = ert_templates_add_template( templates , NULL , template_file , target_file , NULL); + + for (int iarg = 2; iarg < config_content_node_get_size( template_node ); iarg++) { + char * key , *value; + const char * key_value = config_content_node_iget( template_node , iarg ); + util_binary_split_string( key_value , "=:" , true , &key , &value); + + if (value != NULL) + ert_template_add_arg( template ,key , value ); + else + fprintf(stderr,"** Warning - failed to parse argument:%s as key:value - ignored \n",config_iget( config , "RUN_TEMPLATE" , i , iarg )); + + free( key ); + util_safe_free( value ); + } + } + } +} + void ert_templates_fprintf_config( const ert_templates_type * ert_templates , FILE * stream ) { if (hash_get_size( ert_templates->templates ) > 0 ) { diff --git a/ThirdParty/Ert/devel/libenkf/src/ert_workflow_list.c b/ThirdParty/Ert/devel/libenkf/src/ert_workflow_list.c new file mode 100644 index 0000000000..5bebfbca43 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/src/ert_workflow_list.c @@ -0,0 +1,239 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_workflow_list.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + + +struct ert_workflow_list_struct { + stringlist_type * path_list; + hash_type * workflows; + workflow_joblist_type * joblist; + const subst_list_type * context; + const config_error_type * last_error; + bool verbose; +}; + + + +ert_workflow_list_type * ert_workflow_list_alloc(const subst_list_type * context) { + ert_workflow_list_type * workflow_list = util_malloc( sizeof * workflow_list ); + workflow_list->path_list = stringlist_alloc_new(); + workflow_list->workflows = hash_alloc(); + workflow_list->joblist = workflow_joblist_alloc(); + workflow_list->context = context; + workflow_list->last_error = NULL; + ert_workflow_list_set_verbose( workflow_list , DEFAULT_WORKFLOW_VERBOSE ); + return workflow_list; +} + + +void ert_workflow_list_set_verbose( ert_workflow_list_type * workflow_list , bool verbose) { + workflow_list->verbose = verbose; +} + + +void ert_workflow_list_free( ert_workflow_list_type * workflow_list ) { + hash_free( workflow_list->workflows ); + stringlist_free( workflow_list->path_list ); + workflow_joblist_free( workflow_list->joblist ); + free( workflow_list ); +} + + + +workflow_type * ert_workflow_list_add_workflow( ert_workflow_list_type * workflow_list , const char * workflow_file , const char * workflow_name) { + if (util_file_exists( workflow_file )) { + workflow_type * workflow = workflow_alloc( workflow_file , workflow_list->joblist ); + if (workflow_name != NULL) + hash_insert_hash_owned_ref( workflow_list->workflows , workflow_name , workflow , workflow_free__); + else { + char * name; + util_alloc_file_components( workflow_file , NULL , &name , NULL ); + hash_insert_hash_owned_ref( workflow_list->workflows , name , workflow , workflow_free__); + free( name ); + } + return workflow; + } else + return NULL; +} + + + +void ert_workflow_list_add_alias( ert_workflow_list_type * workflow_list , const char * real_name , const char * alias) { + workflow_type * workflow = ert_workflow_list_get_workflow( workflow_list , real_name ); + hash_insert_ref( workflow_list->workflows , alias , workflow ); +} + + +void ert_workflow_list_add_job( ert_workflow_list_type * workflow_list , const char * job_name , const char * config_file ) { + char * name = (char *) job_name; + + if (job_name == NULL) + util_alloc_file_components( config_file , NULL , &name , NULL ); + + if (!workflow_joblist_add_job_from_file( workflow_list->joblist , name , config_file )) + fprintf(stderr,"** Warning: failed to add workflow job:%s from:%s \n",job_name , config_file ); + + if (job_name == NULL) + free(name); +} + + + + +void ert_workflow_list_add_jobs_in_directory( ert_workflow_list_type * workflow_list , const char * path , log_type * logh) { + DIR * dirH = opendir( path ); + while (true) { + struct dirent * entry = readdir( dirH ); + if (entry != NULL) { + if ((strcmp(entry->d_name , ".") != 0) && (strcmp(entry->d_name , "..") != 0)) { + char * full_path = util_alloc_filename( path , entry->d_name , NULL ); + + if (util_is_file( full_path )) { + if (log_is_open( logh )) + log_add_message( logh , 1 , NULL , util_alloc_sprintf("Adding workflow job:%s " , full_path ), true); + ert_workflow_list_add_job( workflow_list , entry->d_name , full_path ); + } + + free( full_path ); + } + } else + break; + } + closedir( dirH ); +} + + +void ert_workflow_list_init( ert_workflow_list_type * workflow_list , config_type * config , log_type * logh) { + /* Adding jobs */ + { + const config_content_item_type * jobpath_item = config_get_content_item( config , WORKFLOW_JOB_DIRECTORY_KEY); + if (jobpath_item != NULL) { + for (int i=0; i < config_content_item_get_size( jobpath_item ); i++) { + config_content_node_type * path_node = config_content_item_iget_node( jobpath_item , i ); + + for (int j=0; j < config_content_node_get_size( path_node ); j++) + ert_workflow_list_add_jobs_in_directory( workflow_list , config_content_node_iget_as_abspath( path_node , j ) , logh); + } + } + } + + { + const config_content_item_type * job_item = config_get_content_item( config , LOAD_WORKFLOW_JOB_KEY); + if (job_item != NULL) { + for (int i=0; i < config_content_item_get_size( job_item ); i++) { + config_content_node_type * job_node = config_content_item_iget_node( job_item , i ); + const char * config_file = config_content_node_iget_as_path( job_node , 0 ); + const char * job_name = config_content_node_safe_iget( job_node , 1 ); + ert_workflow_list_add_job( workflow_list , job_name , config_file); + } + } + } + + + /* Adding workflows */ + { + const config_content_item_type * workflow_item = config_get_content_item( config , LOAD_WORKFLOW_KEY); + + if (workflow_item != NULL) { + for (int i=0; i < config_content_item_get_size( workflow_item ); i++) { + config_content_node_type * workflow_node = config_content_item_iget_node( workflow_item , i ); + const char * workflow_file = config_content_node_iget_as_path( workflow_node , 0 ); + const char * workflow_name = config_content_node_safe_iget( workflow_node , 1 ); + + ert_workflow_list_add_workflow( workflow_list , workflow_file , workflow_name ); + } + } + } +} + + +void ert_workflow_list_add_config_items( config_type * config ) { + config_schema_item_type * item = config_add_schema_item( config , WORKFLOW_JOB_DIRECTORY_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); + + item = config_add_schema_item( config , LOAD_WORKFLOW_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 2 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); + + item = config_add_schema_item( config , LOAD_WORKFLOW_JOB_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 2 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); +} + + + +workflow_type * ert_workflow_list_get_workflow(ert_workflow_list_type * workflow_list , const char * workflow_name ) { + return hash_get( workflow_list->workflows , workflow_name ); +} + +bool ert_workflow_list_has_workflow(ert_workflow_list_type * workflow_list , const char * workflow_name ) { + return hash_has_key( workflow_list->workflows , workflow_name ); +} + + +bool ert_workflow_list_run_workflow__(ert_workflow_list_type * workflow_list , workflow_type * workflow, bool verbose , void * self ) { + bool runOK = workflow_run( workflow , self , verbose , workflow_list->context ); + + if (runOK) + workflow_list->last_error = NULL; + else + workflow_list->last_error = workflow_get_last_error( workflow ); + + return runOK; +} + +bool ert_workflow_list_run_workflow(ert_workflow_list_type * workflow_list , const char * workflow_name , void * self) { + workflow_type * workflow = ert_workflow_list_get_workflow( workflow_list , workflow_name ); + return ert_workflow_list_run_workflow__( workflow_list , workflow , workflow_list->verbose , self ); +} + + +/*****************************************************************/ + +stringlist_type * ert_workflow_list_alloc_namelist( ert_workflow_list_type * workflow_list ) { + return hash_alloc_stringlist( workflow_list->workflows ); +} + + +const config_error_type * ert_workflow_list_get_last_error( const ert_workflow_list_type * workflow_list) { + return workflow_list->last_error; +} diff --git a/ThirdParty/Ert/devel/libenkf/src/field_config.c b/ThirdParty/Ert/devel/libenkf/src/field_config.c index 6721de679c..b3822cd006 100644 --- a/ThirdParty/Ert/devel/libenkf/src/field_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/field_config.c @@ -943,14 +943,18 @@ void field_config_assert_binary( const field_config_type * config1 , const field bool field_config_parse_user_key__( const char * index_key , int *i , int *j , int *k) { int length; - int * indices = util_sscanf_alloc_active_list(index_key, &length); - if (length == 3) { - *i = indices[0] - 1; - *j = indices[1] - 1; - *k = indices[2] - 1; - } + { + int_vector_type * indices = string_util_alloc_active_list( index_key ); + length = int_vector_size( indices ); - free( indices ); + if (length == 3) { + *i = int_vector_iget( indices , 0) - 1; + *j = int_vector_iget( indices , 1) - 1; + *k = int_vector_iget( indices , 2) - 1; + } + + int_vector_free( indices ); + } if (length == 3) return true; else @@ -958,6 +962,7 @@ bool field_config_parse_user_key__( const char * index_key , int *i , int *j , i } + int field_config_parse_user_key(const field_config_type * config, const char * index_key , int *i , int *j , int *k) { int return_value = 0; diff --git a/ThirdParty/Ert/devel/libenkf/src/gen_kw.c b/ThirdParty/Ert/devel/libenkf/src/gen_kw.c index 8d9261afaf..6920be35a5 100644 --- a/ThirdParty/Ert/devel/libenkf/src/gen_kw.c +++ b/ThirdParty/Ert/devel/libenkf/src/gen_kw.c @@ -164,7 +164,7 @@ void gen_kw_filter_file(const gen_kw_type * gen_kw , const char * target_file) { int ikw; for (ikw = 0; ikw < size; ikw++) { - const char * key = gen_kw_config_get_tagged_name(gen_kw->config , ikw); + const char * key = gen_kw_config_get_tagged_name(gen_kw->config , ikw); subst_list_append_owned_ref(gen_kw->subst_list , key , util_alloc_sprintf("%g" , gen_kw_config_transform( gen_kw->config , ikw , gen_kw->data[ikw] )) , NULL); } @@ -231,7 +231,7 @@ const char * gen_kw_get_name(const gen_kw_type * gen_kw, int kw_nr) { void gen_kw_fload(gen_kw_type * gen_kw , const char * filename) { const int size = gen_kw_config_get_data_size(gen_kw->config ); FILE * stream = util_fopen( filename , "r"); - bool readOK = true; + bool readOK = true; /* First try reading all the data as one long vector. */ { diff --git a/ThirdParty/Ert/devel/libenkf/src/gen_obs.c b/ThirdParty/Ert/devel/libenkf/src/gen_obs.c index a2446ab625..2430269349 100644 --- a/ThirdParty/Ert/devel/libenkf/src/gen_obs.c +++ b/ThirdParty/Ert/devel/libenkf/src/gen_obs.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -197,7 +198,13 @@ gen_obs_type * gen_obs_alloc(const gen_data_config_type * data_config , const ch obs->data_index_list = gen_common_fscanf_alloc( data_index_file , ECL_INT_TYPE , &obs->obs_size); else /* Parsing a string of the type "1,3,5,9-100,200,202,300-1000" */ - obs->data_index_list = util_sscanf_alloc_active_list(data_index_string , &obs->obs_size); + { + int_vector_type * index_list = string_util_alloc_active_list( data_index_string ); + int_vector_shrink( index_list ); + obs->data_index_list = int_vector_get_ptr( index_list ); + obs->obs_size = int_vector_size( index_list ); + int_vector_free_container( index_list ); + } } if (error_covar_file != NULL) { diff --git a/ThirdParty/Ert/devel/libenkf/src/local_config.c b/ThirdParty/Ert/devel/libenkf/src/local_config.c index 7f13693a5d..9bd4a995b9 100644 --- a/ThirdParty/Ert/devel/libenkf/src/local_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/local_config.c @@ -528,7 +528,6 @@ struct local_config_struct { hash_type * dataset_storage; hash_type * obsset_storage; stringlist_type * config_files; - int history_length; }; @@ -539,20 +538,12 @@ static void local_config_clear( local_config_type * local_config ) { hash_clear( local_config->dataset_storage ); hash_clear( local_config->obsset_storage ); vector_clear( local_config->updatestep ); - { - int report; - for (report=0; report <= local_config->history_length; report++) - vector_append_ref( local_config->updatestep , NULL ); - } } -/** - Observe that history_length is *INCLUSIVE* -*/ -local_config_type * local_config_alloc( int history_length ) { +local_config_type * local_config_alloc( ) { local_config_type * local_config = util_malloc( sizeof * local_config ); local_config->default_updatestep = NULL; @@ -561,7 +552,6 @@ local_config_type * local_config_alloc( int history_length ) { local_config->dataset_storage = hash_alloc(); local_config->obsset_storage = hash_alloc(); local_config->updatestep = vector_alloc_new(); - local_config->history_length = history_length; local_config->config_files = stringlist_alloc_new(); local_config_clear( local_config ); @@ -672,14 +662,14 @@ local_ministep_type * local_config_alloc_ministep_copy( local_config_type * loca const local_updatestep_type * local_config_iget_updatestep( const local_config_type * local_config , int index) { - const local_updatestep_type * updatestep = vector_iget_const( local_config->updatestep , index ); + const local_updatestep_type * updatestep = vector_safe_iget_const( local_config->updatestep , index ); if (updatestep == NULL) /* - No particular report step has been installed for this - time-index, revert to the default. + No particular report step has been installed for this + time-index, revert to the default. */ updatestep = local_config->default_updatestep; - + if (updatestep == NULL) util_exit("%s: fatal error. No report step information for step:%d - and no default \n",__func__ , index); @@ -702,9 +692,9 @@ local_updatestep_type * local_config_get_updatestep( const local_config_type * l void local_config_set_updatestep(local_config_type * local_config, int step1 , int step2 , const char * key) { local_updatestep_type * updatestep = hash_get( local_config->updatestep_storage , key ); int step; - - for ( step = step1; step < util_int_min(step2 + 1 , vector_get_size( local_config->updatestep )); step++) - vector_iset_ref(local_config->updatestep , step , updatestep ); + + for ( step = step1; step < step2 + 1; step++) + vector_safe_iset_ref(local_config->updatestep , step , updatestep ); } diff --git a/ThirdParty/Ert/devel/libenkf/src/member_config.c b/ThirdParty/Ert/devel/libenkf/src/member_config.c index 1969b9ca06..29f299b360 100644 --- a/ThirdParty/Ert/devel/libenkf/src/member_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/member_config.c @@ -147,8 +147,10 @@ const char * member_config_get_jobname( const member_config_type * member_config else { if (member_config->eclbase != NULL) return member_config->eclbase; - else + else { util_abort("%s: sorry can not submit JOB - must specify name with JOBNAME or ECLBASE config keys\n",__func__); + return NULL; + } } } diff --git a/ThirdParty/Ert/devel/libenkf/src/model_config.c b/ThirdParty/Ert/devel/libenkf/src/model_config.c index 0e2d3e08b7..95867b8d4a 100644 --- a/ThirdParty/Ert/devel/libenkf/src/model_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/model_config.c @@ -281,6 +281,7 @@ void model_config_select_refcase_history( model_config_type * model_config , con util_abort("%s: internal error - trying to load history from REFCASE - but no REFCASE has been loaded.\n",__func__); } + int model_config_get_max_internal_submit( const model_config_type * config ) { return config->max_internal_submit; } @@ -312,11 +313,12 @@ model_config_type * model_config_alloc_empty() { model_config->select_case = NULL; model_config->history = NULL; model_config->jobname_fmt = NULL; + model_config->forward_model = NULL; model_config->internalize_state = bool_vector_alloc( 0 , false ); model_config->__load_state = bool_vector_alloc( 0 , false ); model_config->history_source = HISTORY_SOURCE_INVALID; model_config->runpath_map = hash_alloc(); - + model_config_set_enspath( model_config , DEFAULT_ENSPATH ); model_config_set_rftpath( model_config , DEFAULT_RFTPATH ); model_config_set_dbase_type( model_config , DEFAULT_DBASE_TYPE ); @@ -328,6 +330,42 @@ model_config_type * model_config_alloc_empty() { } +static bool model_config_select_history( model_config_type * model_config , history_source_type source_type, const sched_file_type * sched_file , const ecl_sum_type * refcase) { + bool selectOK = false; + + if (source_type == SCHEDULE && sched_file != NULL) { + model_config_select_schedule_history( model_config , sched_file ); + selectOK = true; + } + + if (((source_type == REFCASE_HISTORY) || (source_type == REFCASE_SIMULATED)) && refcase != NULL) { + if (source_type == REFCASE_HISTORY) + model_config_select_refcase_history( model_config , refcase , true); + else + model_config_select_refcase_history( model_config , refcase , false); + selectOK = true; + } + + return selectOK; +} + + +static bool model_config_select_any_history( model_config_type * model_config , const sched_file_type * sched_file , const ecl_sum_type * refcase) { + bool selectOK = false; + + if (sched_file != NULL) { + model_config_select_schedule_history( model_config , sched_file ); + selectOK = true; + } else if ( refcase != NULL ) { + model_config_select_refcase_history( model_config , refcase , true); + selectOK = true; + } + + return selectOK; +} + + + void model_config_init(model_config_type * model_config , const config_type * config , @@ -336,8 +374,8 @@ void model_config_init(model_config_type * model_config , int last_history_restart , const sched_file_type * sched_file , const ecl_sum_type * refcase) { - - model_config->forward_model = forward_model_alloc( joblist ); + + model_config->forward_model = forward_model_alloc( joblist ); model_config_set_refcase( model_config , refcase ); @@ -369,20 +407,12 @@ void model_config_init(model_config_type * model_config , const char * history_source = config_iget(config , HISTORY_SOURCE_KEY, 0,0); source_type = history_get_source_type( history_source ); } + + if (!model_config_select_history( model_config , source_type , sched_file , refcase )) + if (!model_config_select_history( model_config , DEFAULT_HISTORY_SOURCE , sched_file , refcase )) + if (!model_config_select_any_history( model_config , sched_file , refcase)) + fprintf(stderr,"** Warning:: Do not have enough information to select a history source \n"); - switch (source_type) { - case SCHEDULE: - model_config_select_schedule_history( model_config , sched_file ); - break; - case REFCASE_HISTORY: - model_config_select_refcase_history( model_config , refcase , true); - break; - case REFCASE_SIMULATED: - model_config_select_refcase_history( model_config , refcase , false); - break; - default: - break; - } } @@ -446,9 +476,13 @@ void model_config_free(model_config_type * model_config) { util_safe_free( model_config->enkf_sched_file ); util_safe_free( model_config->select_case ); util_safe_free( model_config->case_table_file ); + if (model_config->history != NULL) history_free(model_config->history); - forward_model_free(model_config->forward_model); + + if (model_config->forward_model != NULL) + forward_model_free(model_config->forward_model); + bool_vector_free(model_config->internalize_state); bool_vector_free(model_config->__load_state); if (model_config->case_names != NULL) stringlist_free( model_config->case_names ); @@ -478,6 +512,7 @@ history_type * model_config_get_history(const model_config_type * config) { } int model_config_get_last_history_restart(const model_config_type * config) { + printf("config->history:%p \n",config->history); return history_get_last_restart( config->history ); } diff --git a/ThirdParty/Ert/devel/libenkf/src/plot_config.c b/ThirdParty/Ert/devel/libenkf/src/plot_config.c index af3650482f..b4efa56192 100644 --- a/ThirdParty/Ert/devel/libenkf/src/plot_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/plot_config.c @@ -31,11 +31,11 @@ struct plot_config_struct { char * plot_path; /* All the plots will be saved as xxxx files in this directory. */ char * image_type; /* Type of plot file - currently only 'png' is tested. */ - char * plot_refcase; /* Full path to DATA file for refcase plotting */ char * driver; /* The driver used by the libplot layer when actually 'rendering' the plots. */ char * viewer; /* The executable used when displaying the newly created image - can be NULL - in which case the plots are not displayed in any way. */ int errorbar_max; /* If the number of observations is less than this it is plotted with errorbars - otherwise with lines. */ bool plot_errorbar; /*Should the errorbars be plotted*/ + bool plot_refcase; int height; int width; bool logy; @@ -65,10 +65,6 @@ void plot_config_set_path(plot_config_type * plot_config , const char * plot_pat util_make_path( plot_path ); } -void plot_config_set_plot_refcase(plot_config_type * plot_config , const char * plot_refcase) { - plot_config->plot_refcase = util_realloc_string_copy(plot_config->plot_refcase , plot_refcase); -} - void plot_config_set_image_type(plot_config_type * plot_config , const char * image_type) { plot_config->image_type = util_realloc_string_copy(plot_config->image_type , image_type); } @@ -108,6 +104,16 @@ void plot_config_set_logy( plot_config_type * plot_config , bool logy) { } +void plot_config_set_plot_refcase( plot_config_type * plot_config , bool plot_refcase) { + plot_config->plot_refcase = plot_refcase; +} + + +bool plot_config_get_plot_refcase( const plot_config_type * plot_config ) { + return plot_config->plot_refcase; +} + + void plot_config_toggle_logy( plot_config_type * plot_config ) { if (plot_config->logy) plot_config->logy = false; @@ -125,10 +131,6 @@ const char * plot_config_get_path(const plot_config_type * plot_config ) { return plot_config->plot_path; } -const char * plot_config_get_plot_refcase(const plot_config_type * plot_config ) { - return plot_config->plot_refcase; -} - const char * plot_config_get_image_type(const plot_config_type * plot_config ) { return plot_config->image_type; } @@ -160,7 +162,6 @@ bool plot_config_get_plot_errorbar( const plot_config_type * plot_config) { void plot_config_free( plot_config_type * plot_config) { free(plot_config->plot_path); - free(plot_config->plot_refcase); util_safe_free(plot_config->viewer); free(plot_config->image_type); free(plot_config->driver ); @@ -174,33 +175,29 @@ void plot_config_free( plot_config_type * plot_config) { plot_config_type * plot_config_alloc_default() { plot_config_type * info = util_malloc( sizeof * info ); info->plot_path = NULL; - info->plot_refcase = NULL; info->image_type = NULL; info->viewer = NULL; info->driver = NULL; + - plot_config_set_path(info , DEFAULT_PLOT_PATH ); - plot_config_set_plot_refcase(info , DEFAULT_PLOT_REFCASE ); - plot_config_set_image_type(info , DEFAULT_IMAGE_TYPE ); - plot_config_set_viewer(info , DEFAULT_IMAGE_VIEWER ); - plot_config_set_driver(info , DEFAULT_PLOT_DRIVER ); - plot_config_set_width(info , DEFAULT_PLOT_WIDTH ); - plot_config_set_height(info , DEFAULT_PLOT_HEIGHT ); - plot_config_set_errorbar_max(info , DEFAULT_PLOT_ERRORBAR_MAX); - plot_config_set_plot_errorbar(info, DEFAULT_PLOT_ERRORBAR); - plot_config_set_logy( info , DEFAULT_PLOT_LOGY ); + plot_config_set_plot_refcase( info , DEFAULT_PLOT_REFCASE); + plot_config_set_path(info , DEFAULT_PLOT_PATH ); + plot_config_set_image_type(info , DEFAULT_IMAGE_TYPE ); + plot_config_set_viewer(info , DEFAULT_IMAGE_VIEWER ); + plot_config_set_driver(info , DEFAULT_PLOT_DRIVER ); + plot_config_set_width(info , DEFAULT_PLOT_WIDTH ); + plot_config_set_height(info , DEFAULT_PLOT_HEIGHT ); + plot_config_set_errorbar_max(info , DEFAULT_PLOT_ERRORBAR_MAX); + plot_config_set_plot_errorbar(info , DEFAULT_PLOT_ERRORBAR); + plot_config_set_logy( info , DEFAULT_PLOT_LOGY ); return info; } - void plot_config_init(plot_config_type * plot_config , const config_type * config ) { if (config_item_set( config , PLOT_PATH_KEY)) plot_config_set_path( plot_config , config_get_value( config , PLOT_PATH_KEY )); - if (config_item_set( config , PLOT_REFCASE_KEY)) - plot_config_set_plot_refcase( plot_config , config_get_value( config , PLOT_REFCASE_KEY )); - if (config_item_set( config , PLOT_DRIVER_KEY)) plot_config_set_driver( plot_config , config_get_value( config , PLOT_DRIVER_KEY )); @@ -209,7 +206,7 @@ void plot_config_init(plot_config_type * plot_config , const config_type * confi if (config_item_set( config , PLOT_DRIVER_KEY)) plot_config_set_driver( plot_config , config_get_value( config , PLOT_DRIVER_KEY )); - + if (config_item_set( config , PLOT_ERRORBAR_MAX_KEY)) plot_config_set_errorbar_max( plot_config , config_get_value_as_int( config , PLOT_ERRORBAR_MAX_KEY )); @@ -221,6 +218,19 @@ void plot_config_init(plot_config_type * plot_config , const config_type * confi if (config_item_set( config , PLOT_WIDTH_KEY)) plot_config_set_width( plot_config , config_get_value_as_int( config , PLOT_WIDTH_KEY )); + + if (config_item_set( config , PLOT_REFCASE_KEY)) { + const char * plot_refcase_string = config_get_value( config , PLOT_REFCASE_KEY ); + bool plot_refcase; + if (!util_sscanf_bool( plot_refcase_string , &plot_refcase)) { + fprintf(stderr , + "Warning: The PLOT_REFCASE option should have value True | False. The value:%s will be interpreted as True" , + plot_refcase_string); + + plot_refcase = true; + } + plot_config_set_plot_refcase( plot_config , plot_refcase ); + } } @@ -228,9 +238,8 @@ void plot_config_add_config_items( config_type * config ) { config_add_key_value(config , PLOT_HEIGHT_KEY , false , CONFIG_INT); config_add_key_value(config , PLOT_WIDTH_KEY , false , CONFIG_INT); config_add_key_value(config , PLOT_PATH_KEY , false , CONFIG_STRING); - config_add_key_value(config , PLOT_REFCASE_KEY , false , CONFIG_STRING); - config_add_key_value(config , IMAGE_VIEWER_KEY , false , CONFIG_FILE); - config_add_key_value(config , PLOT_ERRORBAR_KEY , false , CONFIG_BOOLEAN); + config_add_key_value(config , IMAGE_VIEWER_KEY , false , CONFIG_PATH); + config_add_key_value(config , PLOT_ERRORBAR_KEY , false , CONFIG_BOOL); config_add_key_value(config , PLOT_ERRORBAR_MAX_KEY , false , CONFIG_INT); { @@ -240,8 +249,11 @@ void plot_config_add_config_items( config_type * config ) { config_schema_item_set_common_selection_set( item , 3 , (const char *[3]) {"png" , "jpg" , "psc"}); item = config_add_key_value(config , PLOT_DRIVER_KEY , false , CONFIG_STRING); - config_schema_item_set_common_selection_set( item , 2 , (const char *[2]) {"PLPLOT" , "TEXT"}); + config_schema_item_set_common_selection_set( item , 2 , ( const char *[2]) {"PLPLOT" , "TEXT"}); } + + config_add_key_value(config , PLOT_REFCASE_KEY , false , CONFIG_STRING); + // Should be CONFIG_BOOL } @@ -263,11 +275,6 @@ void plot_config_fprintf_config( const plot_config_type * plot_config , FILE * s fprintf(stream , CONFIG_ENDVALUE_FORMAT , plot_config->plot_path ); } - if (!util_string_equal( plot_config->plot_refcase , DEFAULT_PLOT_REFCASE)) { - fprintf(stream , CONFIG_KEY_FORMAT , PLOT_REFCASE_KEY ); - fprintf(stream , CONFIG_ENDVALUE_FORMAT , plot_config->plot_refcase ); - } - if (!util_string_equal( plot_config->image_type , DEFAULT_IMAGE_TYPE)) { fprintf(stream , CONFIG_KEY_FORMAT , IMAGE_TYPE_KEY ); fprintf(stream , CONFIG_ENDVALUE_FORMAT , plot_config->image_type ); @@ -310,3 +317,16 @@ void plot_config_fprintf_config( const plot_config_type * plot_config , FILE * s fprintf(stream , "\n\n"); } +stringlist_type * plot_config_refcase_fscanf(const char * plot_refcase_file ) { + stringlist_type * list_of_refcases = stringlist_alloc_new(); + if (plot_refcase_file != NULL){ + FILE * stream = util_fopen(plot_refcase_file , "r"); + bool at_eof; + do { + stringlist_append_copy( list_of_refcases ,util_fscanf_alloc_line(stream , &at_eof)); + } while (!at_eof); + + fclose( stream ); + } + return list_of_refcases; +} diff --git a/ThirdParty/Ert/devel/libenkf/src/qc_config.c b/ThirdParty/Ert/devel/libenkf/src/qc_config.c deleted file mode 100644 index 1e00c0e8d7..0000000000 --- a/ThirdParty/Ert/devel/libenkf/src/qc_config.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ert_qc_config.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT 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. - - ERT 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 -#include - -#include - -#include - -#include -#include - - -struct qc_config_struct { - char * qc_path; -}; - - - - -qc_config_type * qc_config_alloc( const char * qc_path ) { - qc_config_type * qc_config = util_malloc( sizeof * qc_config ); - qc_config->qc_path = NULL; - qc_config_set_path( qc_config , qc_path ); - return qc_config; -} - - -void qc_config_free( qc_config_type * qc_config ) { - util_safe_free( qc_config->qc_path ); - free( qc_config ); -} - - -void qc_config_set_path( qc_config_type * qc_config , const char * qc_path) { - qc_config->qc_path = util_realloc_string_copy( qc_config->qc_path , qc_path ); -} - - -const char * qc_config_get_path( const qc_config_type * qc_config ) { - return qc_config->qc_path; -} - - -void qc_config_init( qc_config_type * qc_config , const config_type * config) { - if (config_item_set( config , QC_PATH_KEY )) - qc_config_set_path( qc_config , config_get_value( config , QC_PATH_KEY )); -} diff --git a/ThirdParty/Ert/devel/libenkf/src/qc_module.c b/ThirdParty/Ert/devel/libenkf/src/qc_module.c new file mode 100644 index 0000000000..8b2c1f8b3d --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/src/qc_module.c @@ -0,0 +1,160 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'qc_module.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#define QC_WORKFLOW_NAME "QC" +#define RUNPATH_LIST_FILE "/tmp/ert_runpath_list" + + +struct qc_module_struct { + char * qc_path; + workflow_type * qc_workflow; + ert_workflow_list_type * workflow_list; + runpath_list_type * runpath_list; + char * runpath_list_file; +}; + + + + +qc_module_type * qc_module_alloc( ert_workflow_list_type * workflow_list , const char * qc_path ) { + qc_module_type * qc_module = util_malloc( sizeof * qc_module ); + qc_module->qc_workflow = NULL; + qc_module->qc_path = NULL; + qc_module->workflow_list = workflow_list; + qc_module->runpath_list = runpath_list_alloc(); + qc_module->runpath_list_file = NULL; + qc_module_set_path( qc_module , qc_path ); + qc_module_set_runpath_list_file( qc_module , RUNPATH_LIST_FILE ); + return qc_module; +} + + +void qc_module_free( qc_module_type * qc_module ) { + util_safe_free( qc_module->qc_path ); + runpath_list_free( qc_module->runpath_list ); + free( qc_module ); +} + +runpath_list_type * qc_module_get_runpath_list( qc_module_type * qc_module ) { + return qc_module->runpath_list; +} + + +void qc_module_export_runpath_list( const qc_module_type * qc_module ) { + FILE * stream = util_fopen( qc_module->runpath_list_file , "w"); + runpath_list_fprintf( qc_module->runpath_list , stream ); + fclose( stream ); +} + +void qc_module_set_runpath_list_file( qc_module_type * qc_module , const char * filename) { + qc_module->runpath_list_file = util_realloc_string_copy( qc_module->runpath_list_file , filename ); +} + +const char * qc_module_get_runpath_list_file( qc_module_type * qc_module) { + return qc_module->runpath_list_file; +} + + +void qc_module_set_path( qc_module_type * qc_module , const char * qc_path) { + qc_module->qc_path = util_realloc_string_copy( qc_module->qc_path , qc_path ); +} + + +const char * qc_module_get_path( const qc_module_type * qc_module ) { + return qc_module->qc_path; +} + + +void qc_module_set_workflow( qc_module_type * qc_module , const char * qc_workflow ) { + char * workflow_name; + util_alloc_file_components( qc_workflow , NULL , &workflow_name , NULL ); + { + workflow_type * workflow = ert_workflow_list_add_workflow( qc_module->workflow_list , qc_workflow , workflow_name); + if (workflow != NULL) { + ert_workflow_list_add_alias( qc_module->workflow_list , workflow_name , QC_WORKFLOW_NAME ); + qc_module->qc_workflow = workflow; + } + } + free( workflow_name ); +} + + +bool qc_module_run_workflow( qc_module_type * qc_module , void * self) { + bool verbose = false; + if (qc_module->qc_workflow != NULL ) { + if (!util_file_exists( qc_module->runpath_list_file )) + fprintf(stderr,"** Warning: the file:%s with a list of runpath directories was not found - QC workflow wil probably fail.\n" , qc_module->runpath_list_file); + + return ert_workflow_list_run_workflow__( qc_module->workflow_list , qc_module->qc_workflow , verbose , self); + } else + return false; +} + + +bool qc_module_has_workflow( const qc_module_type * qc_module ) { + if (qc_module->qc_workflow == NULL) + return false; + else + return true; +} + + + +/*****************************************************************/ + + +void qc_module_init( qc_module_type * qc_module , const config_type * config) { + if (config_item_set( config , QC_PATH_KEY )) + qc_module_set_path( qc_module , config_get_value( config , QC_PATH_KEY )); + + if (config_item_set( config , QC_WORKFLOW_KEY)) { + const char * qc_workflow = config_get_value_as_path(config , QC_WORKFLOW_KEY); + qc_module_set_workflow( qc_module , qc_workflow ); + } +} + + + +void qc_module_add_config_items( config_type * config ) { + config_schema_item_type * item; + + item = config_add_schema_item( config , QC_PATH_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + + item = config_add_schema_item( config , QC_WORKFLOW_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH ); +} + + + diff --git a/ThirdParty/Ert/devel/libenkf/src/rng_config.c b/ThirdParty/Ert/devel/libenkf/src/rng_config.c index 0441d979ac..bea6a62229 100644 --- a/ThirdParty/Ert/devel/libenkf/src/rng_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/rng_config.c @@ -21,8 +21,10 @@ #include #include #include +#include #include +#include #include #include @@ -80,23 +82,59 @@ void rng_config_free( rng_config_type * rng) { free( rng ); } + +rng_type * rng_config_alloc_rng( rng_config_type * rng_config ) { + const char * seed_load = rng_config_get_seed_load_file( rng_config ); + const char * seed_store = rng_config_get_seed_store_file( rng_config ); + rng_type * rng = rng_alloc( rng_config_get_type(rng_config) , INIT_DEFAULT); + + if (seed_load != NULL) { + if (util_file_exists( seed_load)) { + FILE * stream = util_fopen( seed_load , "r"); + rng_fscanf_state( rng , stream ); + fclose( stream ); + } else { + /* + In the special case that seed_load == seed_store; we accept a + seed_load argument pointing to a non-existant file. + */ + if (test_string_equal( seed_load , seed_store)) + rng_init( rng , INIT_DEV_URANDOM ); + else + util_abort("%s: tried to load random seed from non-existing file:%s \n",__func__ , seed_load); + } + } else + rng_init( rng , INIT_DEV_URANDOM ); + + + if (seed_store != NULL) { + FILE * stream = util_mkdir_fopen( seed_store , "w"); + rng_fprintf_state( rng , stream ); + fclose( stream ); + } + + return rng; +} + /*****************************************************************/ void rng_config_add_config_items( config_type * config ) { config_schema_item_type * item; - item= config_add_schema_item( config , STORE_SEED_KEY , false , false ); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , NULL ); + item= config_add_schema_item( config , STORE_SEED_KEY , false); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_PATH ); - item = config_add_schema_item( config , LOAD_SEED_KEY , false , false ); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) { CONFIG_EXISTING_FILE}); + item = config_add_schema_item( config , LOAD_SEED_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_PATH ); } void rng_config_init( rng_config_type * rng_config , config_type * config ) { if (config_item_set( config , STORE_SEED_KEY )) rng_config_set_seed_store_file( rng_config , config_iget(config , STORE_SEED_KEY ,0,0)); - + if (config_item_set( config , LOAD_SEED_KEY )) rng_config_set_seed_load_file( rng_config , config_iget(config , LOAD_SEED_KEY ,0,0)); } diff --git a/ThirdParty/Ert/devel/libenkf/src/runpath_list.c b/ThirdParty/Ert/devel/libenkf/src/runpath_list.c new file mode 100644 index 0000000000..a6d8e6556d --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/src/runpath_list.c @@ -0,0 +1,199 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + The file 'runpath_list.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include + +#include + +typedef struct runpath_node_struct runpath_node_type; + + +struct runpath_list_struct { + pthread_rwlock_t lock; + vector_type * list; + char * line_fmt; // Format string : Values are in the order: (iens , runpath , basename) +}; + + +#define RUNPATH_NODE_TYPE_ID 661400541 +struct runpath_node_struct { + UTIL_TYPE_ID_DECLARATION; + int iens; + char * runpath; + char * basename; +}; + + +/*****************************************************************/ + + UTIL_SAFE_CAST_FUNCTION( runpath_node , RUNPATH_NODE_TYPE_ID ) + UTIL_SAFE_CAST_FUNCTION_CONST( runpath_node , RUNPATH_NODE_TYPE_ID ) + + static runpath_node_type * runpath_node_alloc( int iens, const char * runpath , const char * basename) { + runpath_node_type * node = util_malloc( sizeof * node ); + UTIL_TYPE_ID_INIT( node , RUNPATH_NODE_TYPE_ID ); + + node->iens = iens; + node->runpath = util_alloc_string_copy( runpath ); + node->basename = util_alloc_string_copy( basename ); + + return node; + } + + +static void runpath_node_free( runpath_node_type * node ) { + free(node->basename); + free(node->runpath); + free(node); +} + + +static void runpath_node_free__( void * arg ) { + runpath_node_type * node = runpath_node_safe_cast( arg ); + runpath_node_free( node ); +} + +static int runpath_node_cmp( const void * arg1 , const void * arg2) { + const runpath_node_type * node1 = runpath_node_safe_cast_const( arg1 ); + const runpath_node_type * node2 = runpath_node_safe_cast_const( arg2 ); + { + if (node1->iens > node2->iens) + return 1; + else if (node1->iens < node2->iens) + return -1; + else + return 0; + } +} + + +static void runpath_node_fprintf( const runpath_node_type * node , const char * line_fmt , FILE * stream) { + fprintf(stream , line_fmt , node->iens, node->runpath , node->basename); +} + + +/*****************************************************************/ + + +runpath_list_type * runpath_list_alloc() { + runpath_list_type * list = util_malloc( sizeof * list ); + list->list = vector_alloc_new(); + list->line_fmt = NULL; + pthread_rwlock_init( &list->lock , NULL ); + return list; +} + + +void runpath_list_free( runpath_list_type * list ) { + vector_free( list->list ); + util_safe_free( list->line_fmt ); + free( list ); +} + + +int runpath_list_size( const runpath_list_type * list ) { + return vector_get_size( list->list ); +} + + +void runpath_list_sort( runpath_list_type * list ) { + pthread_rwlock_wrlock( &list->lock ); + { + vector_sort( list->list , runpath_node_cmp ); + } + pthread_rwlock_unlock( &list->lock ); +} + + +void runpath_list_add( runpath_list_type * list , int iens , const char * runpath , const char * basename) { + runpath_node_type * node = runpath_node_alloc( iens , runpath , basename ); + pthread_rwlock_wrlock( &list->lock ); + { + vector_append_owned_ref( list->list , node , runpath_node_free__ ); + } + pthread_rwlock_unlock( &list->lock ); +} + + +void runpath_list_clear( runpath_list_type * list ) { + pthread_rwlock_wrlock( &list->lock ); + { + vector_clear( list->list ); + } + pthread_rwlock_unlock( &list->lock ); +} + +/*****************************************************************/ + +void runpath_list_set_line_fmt( runpath_list_type * list , const char * line_fmt ) { + list->line_fmt = util_realloc_string_copy( list->line_fmt , line_fmt ); +} + + +const char * runpath_list_get_line_fmt( const runpath_list_type * list ) { + if (list->line_fmt == NULL) + return RUNPATH_LIST_DEFAULT_LINE_FMT; + else + return list->line_fmt; +} + +/*****************************************************************/ + + +static const runpath_node_type * runpath_list_iget_node__( const runpath_list_type * list , int index) { + return vector_iget_const( list->list , index ); +} + + + +static const runpath_node_type * runpath_list_iget_node( runpath_list_type * list , int index) { + const runpath_node_type * node; + { + pthread_rwlock_rdlock( &list->lock ); + node = runpath_list_iget_node__( list , index ); + pthread_rwlock_unlock( &list->lock ); + } + return node; +} + + +int runpath_list_iget_iens( runpath_list_type * list , int index) { + const runpath_node_type * node = runpath_list_iget_node( list , index ); + return node->iens; +} + + +void runpath_list_fprintf(runpath_list_type * list , FILE * stream) { + pthread_rwlock_rdlock( &list->lock ); + { + const char * line_fmt = runpath_list_get_line_fmt( list ); + int index; + for (index =0; index < vector_get_size( list->list ); index++) { + const runpath_node_type * node = runpath_list_iget_node__( list , index ); + runpath_node_fprintf( node , line_fmt , stream ); + } + } + pthread_rwlock_unlock( &list->lock ); +} diff --git a/ThirdParty/Ert/devel/libenkf/src/site_config.c b/ThirdParty/Ert/devel/libenkf/src/site_config.c index 59dccf66f7..444d01086f 100644 --- a/ThirdParty/Ert/devel/libenkf/src/site_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/site_config.c @@ -35,10 +35,13 @@ #include #include +#include +#include #include #include #include +#include /** This struct contains information which is specific to the site @@ -180,9 +183,8 @@ site_config_type * site_config_alloc_empty() { site_config_type * site_config = util_malloc( sizeof * site_config); site_config->joblist = ext_joblist_alloc( ); - site_config->job_queue = NULL; site_config->queue_drivers = hash_alloc( ); - + site_config->lsf_queue_name_site = NULL; site_config->lsf_request_site = NULL; site_config->rsh_command_site = NULL; @@ -196,19 +198,19 @@ site_config_type * site_config_alloc_empty() { site_config->user_mode = false; site_config->driver_type = NULL_DRIVER; - /* Some hooops to get the current umask. */ - site_config->umask = umask( 0 ); - site_config_set_umask( site_config , site_config->umask ); - site_config_set_manual_url( site_config , DEFAULT_MANUAL_URL ); - site_config_set_default_browser( site_config , DEFAULT_BROWSER ); - + site_config->job_queue = job_queue_alloc(DEFAULT_MAX_SUBMIT , "OK" , "ERROR" ); site_config->env_variables_user = hash_alloc(); site_config->env_variables_site = hash_alloc(); site_config->path_variables_user = stringlist_alloc_new(); site_config->path_values_user = stringlist_alloc_new(); site_config->path_variables_site = hash_alloc(); - + + /* Some hooops to get the current umask. */ + site_config->umask = umask( 0 ); + site_config_set_umask( site_config , site_config->umask ); + site_config_set_manual_url( site_config , DEFAULT_MANUAL_URL ); + site_config_set_default_browser( site_config , DEFAULT_BROWSER ); site_config_set_max_submit( site_config , DEFAULT_MAX_SUBMIT ); return site_config; } @@ -281,14 +283,17 @@ bool site_config_del_job( site_config_type * site_config , const char * job_name static void site_config_add_jobs(site_config_type * site_config , const config_type * config) { - int i; - - stringlist_type *item_list = config_alloc_complete_stringlist(config , INSTALL_JOB_KEY); - - for (i=0; i < stringlist_get_size(item_list); i+=2) - site_config_install_job(site_config , stringlist_iget(item_list , i) , stringlist_iget(item_list , i + 1)); - - stringlist_free(item_list); + if (config_item_set( config , INSTALL_JOB_KEY)) { + const config_content_item_type * content_item = config_get_content_item( config , INSTALL_JOB_KEY ); + int num_jobs = config_content_item_get_size( content_item ); + for (int job_nr = 0; job_nr < num_jobs; job_nr++) { + config_content_node_type * node = config_content_item_iget_node( content_item , job_nr ); + const char * job_key = config_content_node_iget( node , 0 ); + const char * description_file = config_content_node_iget_as_abspath( node , 1 ); + + site_config_install_job(site_config , job_key , description_file ); + } + } } @@ -660,6 +665,7 @@ void site_config_set_max_submit( site_config_type * site_config , int max_submit site_config->max_submit = max_submit; if (!site_config->user_mode) site_config->max_submit_site = max_submit; + job_queue_set_max_submit( site_config->job_queue , max_submit ); } @@ -672,13 +678,43 @@ static void site_config_install_job_queue(site_config_type * site_config ) { if (site_config->job_script == NULL) util_exit("Must set the path to the job script with the %s key in the site_config / config file\n",JOB_SCRIPT_KEY); - site_config->job_queue = job_queue_alloc(site_config->max_submit , "OK" , "ERROR" ); - /* All the various driver options are set, unconditionally of which driver is actually selected in the end. */ - site_config_set_job_queue__( site_config , site_config->driver_type ); + if (site_config->driver_type != NULL_DRIVER) + site_config_set_job_queue__( site_config , site_config->driver_type ); +} + + +void site_config_init_env( site_config_type * site_config , const config_type * config ) { + { + config_content_item_type * setenv_item = config_get_content_item( config , SETENV_KEY ); + if (setenv_item != NULL) { + int i; + for (i = 0; i < config_content_item_get_size( setenv_item ); i++) { + const config_content_node_type * setenv_node = config_content_item_iget_node( setenv_item , i ); + const char * var = config_content_node_iget( setenv_node , 0 ); + const char * value = config_content_node_iget( setenv_node , 1 ); + + site_config_setenv( site_config , var , value ); + } + } + } + + { + config_content_item_type * path_item = config_get_content_item( config , UPDATE_PATH_KEY ); + if (path_item != NULL) { + int i; + for (i = 0; i < config_content_item_get_size( path_item ); i++) { + const config_content_node_type * path_node = config_content_item_iget_node( path_item , i ); + const char * path = config_content_node_iget( path_node , 0 ); + const char * value = config_content_node_iget( path_node , 1 ); + + site_config_update_pathvar( site_config , path , value ); + } + } + } } @@ -692,26 +728,10 @@ static void site_config_install_job_queue(site_config_type * site_config ) { */ -void site_config_init(site_config_type * site_config , const config_type * config, bool user_config) { +bool site_config_init(site_config_type * site_config , const config_type * config) { site_config_add_jobs(site_config , config); - { - int i; - for (i = 0; i < config_get_occurences( config , SETENV_KEY); i++) { - const stringlist_type * tokens = config_iget_stringlist_ref(config , SETENV_KEY , i); - const char * var = stringlist_iget( tokens , 0); - const char * value = stringlist_iget( tokens , 1); - - site_config_setenv( site_config , var , value ); - } - - for (i=0; i < config_get_occurences( config, UPDATE_PATH_KEY); i++) { - const stringlist_type * tokens = config_iget_stringlist_ref(config , UPDATE_PATH_KEY , i); - const char * path = stringlist_iget( tokens , 0); - const char * value = stringlist_iget( tokens , 1); - - site_config_update_pathvar( site_config , path , value ); - } - } + site_config_init_env(site_config , config); + /* When LSF is used several enviroment variables must be set (by the site wide file) - i.e. the calls to SETENV must come first. @@ -730,7 +750,7 @@ void site_config_init(site_config_type * site_config , const config_type * confi prefix characters). */ if (config_item_set(config , UMASK_KEY)) { - const char * string_mask = config_iget( config , UMASK_KEY , 0 , 0); + const char * string_mask = config_get_value( config , UMASK_KEY); mode_t umask_value; if (util_sscanf_octal_int( string_mask , &umask_value)) site_config_set_umask( site_config , umask_value); @@ -745,7 +765,7 @@ void site_config_init(site_config_type * site_config , const config_type * confi /* LSF options */ { if (config_item_set(config , LSF_QUEUE_KEY)) - site_config_set_lsf_queue( site_config , config_iget( config , LSF_QUEUE_KEY , 0 , 0)); + site_config_set_lsf_queue( site_config , config_get_value( config , LSF_QUEUE_KEY )); if (config_item_set(config , LSF_RESOURCES_KEY)) { char * lsf_resource_request = config_alloc_joined_string(config , LSF_RESOURCES_KEY , " "); @@ -754,24 +774,25 @@ void site_config_init(site_config_type * site_config , const config_type * confi } if (config_item_set(config , MAX_RUNNING_LSF_KEY)) - site_config_set_max_running_lsf( site_config , config_iget_as_int( config , MAX_RUNNING_LSF_KEY , 0 , 0)); + site_config_set_max_running_lsf( site_config , config_get_value_as_int( config , MAX_RUNNING_LSF_KEY)); if (config_item_set(config , LSF_SERVER_KEY)) - site_config_set_lsf_server( site_config , config_iget( config , LSF_SERVER_KEY , 0 , 0)); + site_config_set_lsf_server( site_config , config_get_value( config , LSF_SERVER_KEY)); } /* RSH options */ { if (config_item_set( config , RSH_COMMAND_KEY )) - site_config_set_rsh_command( site_config , config_iget(config , RSH_COMMAND_KEY , 0,0)); + site_config_set_rsh_command( site_config , config_get_value(config , RSH_COMMAND_KEY)); if (config_item_set( config , MAX_RUNNING_RSH_KEY)) - site_config_set_max_running_rsh( site_config , config_iget_as_int( config , MAX_RUNNING_RSH_KEY , 0,0)); - + site_config_set_max_running_rsh( site_config , config_get_value_as_int( config , MAX_RUNNING_RSH_KEY)); + /* Parsing the "host1:4" strings. */ - if (user_config) { - if (config_item_set( config , RSH_HOST_KEY)) { + { + const config_content_item_type * rsh_host_item = config_get_content_item( config , RSH_HOST_KEY ); + if (rsh_host_item != NULL) { stringlist_type * rsh_host_list = config_alloc_complete_stringlist(config , RSH_HOST_KEY); int i; for (i=0; i < stringlist_get_size( rsh_host_list ); i++) @@ -781,11 +802,12 @@ void site_config_init(site_config_type * site_config , const config_type * confi } } } + if (config_item_set( config , QUEUE_SYSTEM_KEY)) { job_driver_type driver_type; { - const char * queue_system = config_iget(config , QUEUE_SYSTEM_KEY , 0,0); + const char * queue_system = config_get_value(config , QUEUE_SYSTEM_KEY); if (strcmp(queue_system , LSF_DRIVER_NAME) == 0) { driver_type = LSF_DRIVER; } else if (strcmp(queue_system , RSH_DRIVER_NAME) == 0) @@ -805,19 +827,18 @@ void site_config_init(site_config_type * site_config , const config_type * confi site_config_set_max_running_local( site_config , config_iget_as_int( config , MAX_RUNNING_LOCAL_KEY , 0,0)); if (config_item_set(config , JOB_SCRIPT_KEY)) - site_config_set_job_script( site_config , config_iget( config , JOB_SCRIPT_KEY , 0 , 0)); + site_config_set_job_script( site_config , config_get_value_as_abspath( config , JOB_SCRIPT_KEY)); if (config_item_set(config , LICENSE_PATH_KEY)) - site_config_set_license_root_path( site_config , config_iget( config , LICENSE_PATH_KEY , 0 , 0)); + site_config_set_license_root_path( site_config , config_get_value_as_abspath( config , LICENSE_PATH_KEY)); - if (user_config) - site_config_install_job_queue( site_config ); + site_config_install_job_queue( site_config ); /* Setting QUEUE_OPTIONS */ { int i; for (i=0; i < config_get_occurences(config , QUEUE_OPTION_KEY); i++) { - stringlist_type * tokens = config_iget_stringlist_ref(config , QUEUE_OPTION_KEY , i); + const stringlist_type * tokens = config_iget_stringlist_ref(config , QUEUE_OPTION_KEY , i); const char * driver_name = stringlist_iget( tokens , 0 ); const char * option_key = stringlist_iget( tokens , 1 ); const char * option_value = stringlist_alloc_joined_substring( tokens , 2 , stringlist_get_size( tokens ), " "); @@ -829,6 +850,7 @@ void site_config_init(site_config_type * site_config , const config_type * confi site_config_set_queue_option( site_config , driver_name , option_key , option_value ); } } + return true; } @@ -989,7 +1011,7 @@ void site_config_fprintf_config( const site_config_type * site_config , FILE * s { queue_driver_type * rsh_driver = site_config_get_queue_driver( site_config , RSH_DRIVER_NAME ); - const hash_type * host_list = queue_driver_get_option( rsh_driver , RSH_HOSTLIST ); + hash_type * host_list = queue_driver_get_option( rsh_driver , RSH_HOSTLIST ); hash_iter_type * iter = hash_iter_alloc( host_list ); while (!hash_iter_is_complete( iter )) { const char * host_name = hash_iter_get_next_key( iter ); @@ -1006,18 +1028,15 @@ void site_config_fprintf_config( const site_config_type * site_config , FILE * s /*****************************************************************/ - -void site_config_add_config_items( config_type * config , bool site_only) { - config_schema_item_type * item; - - item = config_add_schema_item(config , QUEUE_SYSTEM_KEY , site_only , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); +void site_config_add_queue_config_items( config_type * config , bool site_mode) { + config_schema_item_type * item = config_add_schema_item(config , QUEUE_SYSTEM_KEY , site_mode); + config_schema_item_set_argc_minmax(item , 1 , 1); { stringlist_type * lsf_dep = stringlist_alloc_argv_ref( (const char *[2]) {"LSF_QUEUE" , "MAX_RUNNING_LSF"} , 2); stringlist_type * rsh_dep = stringlist_alloc_argv_ref( (const char *[3]) {"RSH_HOST" , "RSH_COMMAND" , "MAX_RUNNING_RSH"} , 2); stringlist_type * local_dep = stringlist_alloc_argv_ref( (const char *[1]) {"MAX_RUNNING_LOCAL"} , 1); - if (site_only) { + if (site_mode) { config_schema_item_set_common_selection_set( item , 3 , (const char *[3]) {LSF_DRIVER_NAME , LOCAL_DRIVER_NAME , RSH_DRIVER_NAME}); config_schema_item_set_required_children_on_value( item , LSF_DRIVER_NAME , lsf_dep); config_schema_item_set_required_children_on_value( item , RSH_DRIVER_NAME , rsh_dep); @@ -1029,75 +1048,92 @@ void site_config_add_config_items( config_type * config , bool site_only) { stringlist_free(local_dep); } - item = config_add_schema_item(config , MAX_SUBMIT_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_INT}); + item = config_add_schema_item(config , MAX_SUBMIT_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1); + config_schema_item_iset_type( item , 0 , CONFIG_INT ); +} + + +void site_config_add_config_items( config_type * config , bool site_mode) { + config_schema_item_type * item; + ert_workflow_list_add_config_items( config ); + site_config_add_queue_config_items( config , site_mode ); + + /* You can set environment variables which will be applied to the run-time environment. Can unfortunately not use constructions like PATH=$PATH:/some/new/path, use the UPDATE_PATH function instead. */ - item = config_add_schema_item(config , SETENV_KEY , false , true); - config_schema_item_set_argc_minmax(item , 2 , 2 , 0 , NULL); + item = config_add_schema_item(config , SETENV_KEY , false ); + config_schema_item_set_argc_minmax(item , 2 , 2 ); config_schema_item_set_envvar_expansion( item , false ); /* Do not expand $VAR expressions (that is done in util_interp_setenv()). */ - item = config_add_schema_item(config , UMASK_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); + item = config_add_schema_item(config , UMASK_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); /** UPDATE_PATH LD_LIBRARY_PATH /path/to/some/funky/lib Will prepend "/path/to/some/funky/lib" at the front of LD_LIBRARY_PATH. */ - item = config_add_schema_item(config , UPDATE_PATH_KEY , false , true); - config_schema_item_set_argc_minmax(item , 2 , 2 , 0 , NULL); + item = config_add_schema_item(config , UPDATE_PATH_KEY , false ); + config_schema_item_set_argc_minmax(item , 2 , 2 ); config_schema_item_set_envvar_expansion( item , false ); /* Do not expand $VAR expressions (that is done in util_interp_setenv()). */ - item = config_add_schema_item( config , LICENSE_PATH_KEY , site_only , false ); - config_schema_item_set_argc_minmax(item , 1 , 1, 0 , NULL ); + item = config_add_schema_item( config , LICENSE_PATH_KEY , site_mode ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_PATH ); /*****************************************************************/ /* Items related to running jobs with lsf/rsh/local ... */ /* These must be set IFF QUEUE_SYSTEM == LSF */ - item = config_add_schema_item(config , LSF_QUEUE_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); + item = config_add_schema_item(config , LSF_QUEUE_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1); - item = config_add_schema_item(config , LSF_RESOURCES_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , -1 , 0 , NULL); + item = config_add_schema_item(config , LSF_RESOURCES_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , CONFIG_DEFAULT_ARG_MAX); - item = config_add_schema_item(config , MAX_RUNNING_LSF_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_INT}); + item = config_add_schema_item(config , MAX_RUNNING_LSF_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_INT ); - item = config_add_schema_item(config , LSF_SERVER_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_STRING}); + item = config_add_schema_item(config , LSF_SERVER_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); /* These must be set IFF QUEUE_SYSTEM == RSH */ - if (!site_only) - config_add_schema_item(config , RSH_HOST_KEY , false , false); /* Only added when user parse. */ - item = config_add_schema_item(config , RSH_COMMAND_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_EXECUTABLE}); - item = config_add_schema_item(config , MAX_RUNNING_RSH_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_INT}); + if (!site_mode) + config_add_schema_item(config , RSH_HOST_KEY , false ); /* Only added when user parse. */ + item = config_add_schema_item(config , RSH_COMMAND_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_EXECUTABLE); + item = config_add_schema_item(config , MAX_RUNNING_RSH_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1); + config_schema_item_iset_type( item , 0 , CONFIG_INT); /* These must be set IFF QUEUE_SYSTEM == LOCAL */ - item = config_add_schema_item(config , MAX_RUNNING_LOCAL_KEY , false , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_INT}); + item = config_add_schema_item(config , MAX_RUNNING_LOCAL_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_INT); /*****************************************************************/ - item = config_add_schema_item(config , QUEUE_OPTION_KEY , false , true); - config_schema_item_set_argc_minmax(item , 3 , -1 , 0 , NULL); + item = config_add_schema_item(config , QUEUE_OPTION_KEY , false ); + config_schema_item_set_argc_minmax(item , 3 , CONFIG_DEFAULT_ARG_MAX); - item = config_add_schema_item(config , JOB_SCRIPT_KEY , site_only , false); - config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_EXISTING_FILE}); + item = config_add_schema_item(config , JOB_SCRIPT_KEY , site_mode ); + config_schema_item_set_argc_minmax(item , 1 , 1); + config_schema_item_iset_type( item , 0 , CONFIG_EXISTING_PATH); + + item = config_add_schema_item(config , INSTALL_JOB_KEY , false ); + config_schema_item_set_argc_minmax(item , 2 , 2 ); + config_schema_item_iset_type( item , 1 , CONFIG_EXISTING_PATH); - item = config_add_schema_item(config , INSTALL_JOB_KEY , false , true); - config_schema_item_set_argc_minmax(item , 2 , 2 , 2 , (const config_item_types [2]) {CONFIG_STRING , CONFIG_EXISTING_FILE}); - /* Items related to the reports. */ - item = config_add_schema_item( config , REPORT_SEARCH_PATH_KEY , false , true ); - config_schema_item_set_argc_minmax(item , 1 , -1 , 0 , NULL); + item = config_add_schema_item( config , REPORT_SEARCH_PATH_KEY , false ); + config_schema_item_set_argc_minmax(item , 1 , CONFIG_DEFAULT_ARG_MAX); } diff --git a/ThirdParty/Ert/devel/libenkf/src/time_map.c b/ThirdParty/Ert/devel/libenkf/src/time_map.c index 9b5595d85a..7302484f19 100644 --- a/ThirdParty/Ert/devel/libenkf/src/time_map.c +++ b/ThirdParty/Ert/devel/libenkf/src/time_map.c @@ -23,6 +23,7 @@ #include #include +#include #include @@ -31,21 +32,31 @@ #define DEFAULT_TIME -1 +#define TIME_MAP_TYPE_ID 7751432 struct time_map_struct { + UTIL_TYPE_ID_DECLARATION; time_t_vector_type * map; - time_t start_time; pthread_rwlock_t rw_lock; + bool modified; }; +UTIL_SAFE_CAST_FUNCTION( time_map , TIME_MAP_TYPE_ID ) + time_map_type * time_map_alloc( ) { time_map_type * map = util_malloc( sizeof * map ); + UTIL_TYPE_ID_INIT( map , TIME_MAP_TYPE_ID ); + map->map = time_t_vector_alloc(0 , DEFAULT_TIME ); - map->start_time = DEFAULT_TIME; + map->modified = false; pthread_rwlock_init( &map->rw_lock , NULL); return map; } +bool time_map_equal( const time_map_type * map1 , const time_map_type * map2) { + return time_t_vector_equal( map1->map , map2->map ); +} + void time_map_free( time_map_type * map ) { time_t_vector_free( map->map ); @@ -57,32 +68,25 @@ void time_map_free( time_map_type * map ) { Must hold the write lock. */ -static void time_map_update__( time_map_type * map , int step , time_t time) { + +static bool time_map_update__( time_map_type * map , int step , time_t time) { + bool updateOK = true; time_t current_time = time_t_vector_safe_iget( map->map , step); if (current_time == DEFAULT_TIME) time_t_vector_iset( map->map , step , time ); - else { - if (current_time != time) { - int current[3]; - int new[3]; - - util_set_date_values( current_time , ¤t[0] , ¤t[1] , ¤t[2]); - util_set_date_values( time , &new[0] , &new[1] , &new[2]); - - util_abort("%s: time mismatch for step:%d New: %02d/%02d/%04d existing: %02d/%02d/%04d \n",__func__ , step , - new[0] , new[1] , new[2] , - current[0] , current[1] , current[2]); - - } - } + else if (current_time != time) + updateOK = false; - if (step == 0) - map->start_time = time; + if (updateOK) + map->modified = true; + + return updateOK; } -static void time_map_summary_update__( time_map_type * map , const ecl_sum_type * ecl_sum) { +static bool time_map_summary_update__( time_map_type * map , const ecl_sum_type * ecl_sum) { + bool updateOK = true; int first_step = ecl_sum_get_first_report_step( ecl_sum ); int last_step = ecl_sum_get_last_report_step( ecl_sum ); int step; @@ -90,10 +94,11 @@ static void time_map_summary_update__( time_map_type * map , const ecl_sum_type for (step = first_step; step <= last_step; step++) { if (ecl_sum_has_report_step(ecl_sum , step)) { time_t time = ecl_sum_get_report_time( ecl_sum , step ); - time_map_update__( map , step , time ); + updateOK = (updateOK && time_map_update__( map , step , time )); } } - time_map_update__(map , 0 , ecl_sum_get_start_time( ecl_sum )); + updateOK = (updateOK && time_map_update__(map , 0 , ecl_sum_get_start_time( ecl_sum ))); + return updateOK; } @@ -113,9 +118,9 @@ double time_map_iget_sim_days( time_map_type * map , int step ) { time_t sim_time = time_map_iget__( map , step ); if (sim_time >= start_time) - return 1.0 * (sim_time - start_time) / (3600 * 24); + days = 1.0 * (sim_time - start_time) / (3600 * 24); else - return -1; + days = -1; } pthread_rwlock_unlock( &map->rw_lock ); @@ -133,33 +138,32 @@ time_t time_map_iget( time_map_type * map , int step ) { return t; } -void time_map_update( time_map_type * map , int step , time_t time) { - pthread_rwlock_wrlock( &map->rw_lock ); - time_map_update__( map , step , time ); - pthread_rwlock_unlock( &map->rw_lock ); -} -void time_map_summary_update( time_map_type * map , const ecl_sum_type * ecl_sum) { - pthread_rwlock_wrlock( &map->rw_lock ); - time_map_summary_update__( map , ecl_sum ); - pthread_rwlock_unlock( &map->rw_lock ); -} +/** + Observe that the locking is opposite of the function name; i.e. + the time_map_fwrite() function reads the time_map and takes the + read lock, whereas the time_map_fread() function takes the write + lock. +*/ void time_map_fwrite( time_map_type * map , const char * filename ) { - pthread_rwlock_wrlock( &map->rw_lock ); + pthread_rwlock_rdlock( &map->rw_lock ); { - FILE * stream = util_fopen(filename , "w"); - time_t_vector_fwrite( map->map , stream ); - fclose( stream ); -} + if (map->modified) { + FILE * stream = util_mkdir_fopen(filename , "w"); + time_t_vector_fwrite( map->map , stream ); + fclose( stream ); + } + map->modified = false; + } pthread_rwlock_unlock( &map->rw_lock ); } void time_map_fread( time_map_type * map , const char * filename) { - pthread_rwlock_rdlock( &map->rw_lock ); + pthread_rwlock_wrlock( &map->rw_lock ); { if (util_file_exists( filename )) { FILE * stream = util_fopen( filename , "r"); @@ -173,6 +177,8 @@ void time_map_fread( time_map_type * map , const char * filename) { } } pthread_rwlock_unlock( &map->rw_lock ); + time_map_get_last_step( map ); + map->modified = false; } @@ -189,6 +195,102 @@ int time_map_get_last_step( time_map_type * map) { pthread_rwlock_rdlock( &map->rw_lock ); last_step = time_t_vector_size( map->map ) - 1; pthread_rwlock_unlock( &map->rw_lock ); - + return last_step; } + +int time_map_get_size( time_map_type * map) { + return time_map_get_last_step( map ); +} + + +time_t time_map_get_start_time( time_map_type * map) { + return time_map_iget( map , 0 ); +} + + +time_t time_map_get_end_time( time_map_type * map) { + int last_step = time_map_get_last_step( map ); + return time_map_iget( map , last_step ); +} + +double time_map_get_end_days( time_map_type * map) { + int last_step = time_map_get_last_step( map ); + return time_map_iget_sim_days( map , last_step ); +} + +/*****************************************************************/ + +bool time_map_update( time_map_type * map , int step , time_t time) { + bool updateOK; + pthread_rwlock_wrlock( &map->rw_lock ); + { + updateOK = time_map_update__( map , step , time ); + } + pthread_rwlock_unlock( &map->rw_lock ); + return updateOK; +} + + +bool time_map_summary_update( time_map_type * map , const ecl_sum_type * ecl_sum) { + bool updateOK; + pthread_rwlock_wrlock( &map->rw_lock ); + { + updateOK = time_map_summary_update__( map , ecl_sum ); + } + pthread_rwlock_unlock( &map->rw_lock ); + return updateOK; +} + + +void time_map_clear( time_map_type * map ) { + pthread_rwlock_wrlock( &map->rw_lock ); + { + time_t_vector_reset( map->map ); + map->modified = true; + } + pthread_rwlock_unlock( &map->rw_lock ); +} + +/*****************************************************************/ + +void time_map_update_strict( time_map_type * map , int step , time_t time) { + if (!time_map_update( map , step , time )) { + time_t current_time = time_map_iget__( map , step ); + int current[3]; + int new[3]; + + util_set_date_values( current_time , ¤t[0] , ¤t[1] , ¤t[2]); + util_set_date_values( time , &new[0] , &new[1] , &new[2]); + + util_abort("%s: time mismatch for step:%d New: %02d/%02d/%04d existing: %02d/%02d/%04d \n",__func__ , step , + new[0] , new[1] , new[2] , + current[0] , current[1] , current[2]); + + } +} + +void time_map_summary_update_strict( time_map_type * map , const ecl_sum_type * ecl_sum) { + if (!time_map_summary_update( map , ecl_sum)) { + /* + If the normal summary update fails we just play through all + time steps to pinpoint exactly the step where the update fails. + */ + int first_step = ecl_sum_get_first_report_step( ecl_sum ); + int last_step = ecl_sum_get_last_report_step( ecl_sum ); + int step; + + for (step = first_step; step <= last_step; step++) { + if (ecl_sum_has_report_step(ecl_sum , step)) { + time_t time = ecl_sum_get_report_time( ecl_sum , step ); + time_map_update_strict( map , step , time ); + } + } + } +} + + + + + +/*****************************************************************/ diff --git a/ThirdParty/Ert/devel/libenkf/src/trans_func.c b/ThirdParty/Ert/devel/libenkf/src/trans_func.c index c546741653..344441b068 100644 --- a/ThirdParty/Ert/devel/libenkf/src/trans_func.c +++ b/ThirdParty/Ert/devel/libenkf/src/trans_func.c @@ -77,7 +77,9 @@ static void trans_errf_check(const char * func_name , const arg_pack_type * arg) } - +static double trans_none(double x , const arg_pack_type * arg) { + return x; +} static double trans_const(double x , const arg_pack_type * arg) { @@ -363,6 +365,10 @@ trans_func_type * trans_func_alloc( const char * func_name ) { arg_pack_append_double( trans_func->params , 0 ); trans_func->func = trans_const; } + + if (util_string_equal( func_name , "NONE")) + trans_func->func = trans_const; + if (trans_func->func == NULL) util_exit("%s: Sorry: function name:%s not recognized \n",__func__ , func_name); diff --git a/ThirdParty/Ert/devel/libenkf/tests/CMakeLists.txt b/ThirdParty/Ert/devel/libenkf/tests/CMakeLists.txt new file mode 100644 index 0000000000..a5e5a966b0 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/CMakeLists.txt @@ -0,0 +1,65 @@ +add_executable( enkf_runpath_list enkf_runpath_list.c ) +target_link_libraries( enkf_runpath_list enkf ) + +add_executable( enkf_site_config enkf_site_config.c ) +target_link_libraries( enkf_site_config enkf ) + +add_executable( enkf_time_map enkf_time_map.c ) +target_link_libraries( enkf_time_map enkf ) + +add_executable( enkf_ensemble_GEN_PARAM enkf_ensemble_GEN_PARAM.c ) +target_link_libraries( enkf_ensemble_GEN_PARAM enkf ) + +add_executable( enkf_ensemble enkf_ensemble.c ) +target_link_libraries( enkf_ensemble enkf ) + +add_executable( enkf_main enkf_main.c ) +target_link_libraries( enkf_main enkf ) +add_test( enkf_main ${EXECUTABLE_OUTPUT_PATH}/enkf_main ) + +add_executable( enkf_iter_config enkf_iter_config.c ) +target_link_libraries( enkf_iter_config enkf ) +add_test( enkf_iter_config ${EXECUTABLE_OUTPUT_PATH}/enkf_iter_config ) + +add_executable( enkf_model_config enkf_model_config.c ) +target_link_libraries( enkf_model_config enkf ) +add_test( enkf_model_config ${EXECUTABLE_OUTPUT_PATH}/enkf_model_config ) + +add_executable( enkf_rng enkf_rng.c ) +target_link_libraries( enkf_rng enkf ) +add_test( enkf_rng ${EXECUTABLE_OUTPUT_PATH}/enkf_rng ${CMAKE_CURRENT_SOURCE_DIR}/data/config/rng) + +add_executable( enkf_report_list enkf_report_list.c ) +target_link_libraries( enkf_report_list enkf ) +add_test( enkf_report_list ${EXECUTABLE_OUTPUT_PATH}/enkf_report_list ${CMAKE_CURRENT_SOURCE_DIR}/data/config/ert_report_list) + +add_executable( enkf_refcase_list enkf_refcase_list.c ) +target_link_libraries( enkf_refcase_list enkf ) +add_test( enkf_refcase_list ${EXECUTABLE_OUTPUT_PATH}/enkf_refcase_list ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat*/ECLIPSE) +add_test( enkf_refcase_list2 ${EXECUTABLE_OUTPUT_PATH}/enkf_refcase_list ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat*/ECLIPSE.*) +set_property( TEST enkf_refcase_list PROPERTY LABELS Statoil ) +set_property( TEST enkf_refcase_list2 PROPERTY LABELS Statoil ) + + +add_executable( enkf_ecl_config enkf_ecl_config.c ) +target_link_libraries( enkf_ecl_config enkf ) +add_test( enkf_ecl_config1 ${EXECUTABLE_OUTPUT_PATH}/enkf_ecl_config ) +add_test( enkf_ecl_config2 ${EXECUTABLE_OUTPUT_PATH}/enkf_ecl_config ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE) +set_property( TEST enkf_ecl_config2 PROPERTY LABELS Statoil ) + +add_executable( enkf_ecl_config_config enkf_ecl_config_config.c ) +target_link_libraries( enkf_ecl_config_config enkf ) +add_test( enkf_ecl_config_config ${EXECUTABLE_OUTPUT_PATH}/enkf_ecl_config_config ${PROJECT_SOURCE_DIR}/test-data/Statoil/config/ecl_config ) +set_property( TEST enkf_ecl_config_config PROPERTY LABELS Statoil ) + +add_test( enkf_runpath_list ${EXECUTABLE_OUTPUT_PATH}/enkf_runpath_list ) +add_test( enkf_site_config ${EXECUTABLE_OUTPUT_PATH}/enkf_site_config /project/res/etc/ERT/site-config) +add_test( enkf_time_map1 ${EXECUTABLE_OUTPUT_PATH}/enkf_time_map ) +add_test( enkf_time_map2 ${EXECUTABLE_OUTPUT_PATH}/enkf_time_map ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST ) +add_test( enkf_ensemble_GEN_PARAM ${EXECUTABLE_OUTPUT_PATH}/enkf_ensemble_GEN_PARAM ${CMAKE_CURRENT_SOURCE_DIR}/data/ensemble/GEN_PARAM ) +add_test( enkf_ensemble ${EXECUTABLE_OUTPUT_PATH}/enkf_ensemble ) + + +set_property( TEST enkf_time_map2 PROPERTY LABELS Statoil ) +set_property( TEST enkf_site_config PROPERTY LABELS Statoil ) + diff --git a/ThirdParty/Ert/devel/libenkf/tests/data/config/ert_report_list b/ThirdParty/Ert/devel/libenkf/tests/data/config/ert_report_list new file mode 100644 index 0000000000..270780b1f1 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/data/config/ert_report_list @@ -0,0 +1,3 @@ +REPORT_TIMEOUT 167 + +REPORT_LARGE TRUE \ No newline at end of file diff --git a/ThirdParty/Ert/devel/libenkf/tests/data/config/rng b/ThirdParty/Ert/devel/libenkf/tests/data/config/rng new file mode 100644 index 0000000000..64f4d50888 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/data/config/rng @@ -0,0 +1,6 @@ +NUM_REALIZATIONS 25 +STORE_SEED /tmp/seed2 +LOAD_SEED /tmp/seed2 + +-- The settings below here are artifacts which should not be necessary ... +JOB_SCRIPT /private/joaho/ERT/Statoil/etc/ERT/Scripts/job_dispatch.py diff --git a/ThirdParty/Ert/devel/libenkf/tests/data/ensemble/GEN_PARAM b/ThirdParty/Ert/devel/libenkf/tests/data/ensemble/GEN_PARAM new file mode 100644 index 0000000000..8f2fdaa749 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/data/ensemble/GEN_PARAM @@ -0,0 +1 @@ +GEN_PARAM GP GP.txt INIT_FILES:GP/GP.txt INPUT_FORMAT:ASCII OUTPUT_FORMAT:ASCII \ No newline at end of file diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_ecl_config.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_ecl_config.c new file mode 100644 index 0000000000..0381e75059 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_ecl_config.c @@ -0,0 +1,54 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_ecl_config.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include + +#include +#include + +int main(int argc , char ** argv) { + ecl_config_type * ecl_config = ecl_config_alloc_empty(); + + if (argc == 2) { + test_assert_true(ecl_config_load_refcase( ecl_config , argv[1])); + + ecl_refcase_list_type * refcase_list = ecl_config_get_refcase_list( ecl_config ); + test_assert_int_equal( ecl_refcase_list_get_size( refcase_list ) , 1 ); + { + const ecl_sum_type * iget0 = ecl_refcase_list_iget_case( refcase_list , 0 ); + const ecl_sum_type * def = ecl_refcase_list_get_default( refcase_list ); + + test_assert_ptr_equal( iget0 , def ); + test_assert_string_equal( argv[1] , ecl_sum_get_case( def )); + test_assert_string_equal( ecl_refcase_list_iget_pathcase( refcase_list , 0) , ecl_sum_get_case( def )); + + } + } + test_assert_false(ecl_config_load_refcase( ecl_config , "DOES_NOT_EXIST" )); + test_assert_true(ecl_config_load_refcase( ecl_config , NULL )); + + + + ecl_config_free( ecl_config ); + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_ecl_config_config.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_ecl_config_config.c new file mode 100644 index 0000000000..c5a052198d --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_ecl_config_config.c @@ -0,0 +1,55 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_ecl_config_config.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +int main(int argc , char ** argv) { + const char * config_file = argv[1]; + + ecl_config_type * ecl_config = ecl_config_alloc_empty(); + ecl_refcase_list_type * refcase_list = ecl_config_get_refcase_list( ecl_config ); + { + config_type * config = config_alloc(); + + ecl_config_add_config_items( config ); + test_assert_true( config_parse( config , config_file , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_WARN , true)); + ecl_config_init( ecl_config , config ); + + config_free( config ); + } + + test_assert_true( ecl_config_has_refcase( ecl_config )); + test_assert_int_equal( ecl_refcase_list_get_size( refcase_list) , 17); + + ecl_config_free( ecl_config ); + + + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_ensemble.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_ensemble.c new file mode 100644 index 0000000000..0c8298781a --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_ensemble.c @@ -0,0 +1,46 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_ensemble.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include +#include + + + + + + + +int main(int argc , char ** argv) { + ensemble_config_type * ensemble = ensemble_config_alloc_empty(); + ensemble_config_free( ensemble ); + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_ensemble_GEN_PARAM.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_ensemble_GEN_PARAM.c new file mode 100644 index 0000000000..d515d6fa40 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_ensemble_GEN_PARAM.c @@ -0,0 +1,55 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_ensemble_GEN_PARAM.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include +#include + + + + + + + +int main(int argc , char ** argv) { + const char * config_file = argv[1]; + config_type * config = config_alloc(); + ensemble_config_type * ensemble = ensemble_config_alloc_empty(); + + ensemble_config_add_GEN_PARAM_config_item( config ); + test_assert_true( config_parse( config , config_file , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_WARN , true ) ); + + ensemble_config_init_GEN_PARAM( ensemble, config ); + + config_free( config ); + ensemble_config_free( ensemble ); + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_iter_config.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_iter_config.c new file mode 100644 index 0000000000..8232c59bff --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_iter_config.c @@ -0,0 +1,79 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_iter_config.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + + +#define TMP_PATH "/tmp" +char * create_config_file( const char * enspath_fmt , const char * runpath_fmt , int iter_count) { + char * config_file = util_alloc_tmp_file(TMP_PATH , "iter-config" , false); + FILE * stream = util_fopen( config_file , "w"); + fprintf(stream , "%s %s\n" , ITER_CASE_KEY , enspath_fmt); + fprintf(stream , "%s %s\n" , ITER_RUNPATH_KEY , runpath_fmt); + fprintf(stream , "%s %d\n" , ITER_COUNT_KEY , iter_count); + fclose( stream ); + return config_file; +} + + +int main(int argc , char ** argv) { + const char * enspath_fmt = "iter%d"; + const char * runpath_fmt = "run/iter%d/real%d"; + const int iter_count = 10; + char * config_file = create_config_file( enspath_fmt , runpath_fmt , iter_count); + + + config_type * config = config_alloc(); + analysis_iter_config_add_config_items( config ); + + test_assert_true( config_parse( config , config_file , NULL , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true)); + + test_assert_true( config_item_set( config , ITER_CASE_KEY )); + test_assert_true( config_item_set( config , ITER_RUNPATH_KEY )); + test_assert_true( config_item_set( config , ITER_COUNT_KEY )); + + { + analysis_iter_config_type * iter_config = analysis_iter_config_alloc(); + test_assert_string_equal( analysis_iter_config_iget_case( iter_config , 5) , NULL ); + test_assert_string_equal( analysis_iter_config_iget_runpath_fmt( iter_config , 5) , NULL ); + + analysis_iter_config_init( iter_config , config ); + + test_assert_int_equal( analysis_iter_config_get_num_iterations( iter_config ) , iter_count ); + test_assert_string_equal( analysis_iter_config_iget_case( iter_config , 5) , "iter5"); + test_assert_string_equal( analysis_iter_config_iget_runpath_fmt( iter_config , 5) , "run/iter5/real%d" ); + + analysis_iter_config_free( iter_config ); + } + remove( config_file ); + free( config_file ); + config_free( config ); + exit(0); +} diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_main.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_main.c new file mode 100644 index 0000000000..5c8ac55eb4 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_main.c @@ -0,0 +1,33 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_main.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include + + +int main(int argc , char ** argv) { + { + enkf_main_type * enkf_main = enkf_main_alloc_empty(); + enkf_main_free( enkf_main ); + } + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_model_config.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_model_config.c new file mode 100644 index 0000000000..519b51917d --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_model_config.c @@ -0,0 +1,31 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_model_config.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include + + +int main(int argc , char ** argv) { + model_config_type * model_config = model_config_alloc_empty(); + model_config_free( model_config ); + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_refcase_list.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_refcase_list.c new file mode 100644 index 0000000000..c247f69bf1 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_refcase_list.c @@ -0,0 +1,128 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_refcase_list.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + + +int main(int argc , char ** argv) { + const char * case1 = argv[1]; + const char * case_glob = argv[2]; + + { + ecl_refcase_list_type * refcase_list = ecl_refcase_list_alloc( ); + + test_assert_false( ecl_refcase_list_has_case( refcase_list , "DoesNotExist" )); + test_assert_NULL( ecl_refcase_list_get_case( refcase_list , "DoesNotExist")); + + test_assert_int_equal( ecl_refcase_list_add_matching( refcase_list , "DoesNotExist") , 0); + ecl_refcase_list_add_case( refcase_list , "DoesNotExist" ); + test_assert_false( ecl_refcase_list_has_case( refcase_list , "DoesNotExist")); + + ecl_refcase_list_add_case( refcase_list , case1 ); + test_assert_true( ecl_refcase_list_has_case( refcase_list , case1)); + + + test_assert_not_NULL( refcase_list ); + test_assert_false( ecl_refcase_list_has_default( refcase_list )); + test_assert_NULL( ecl_refcase_list_get_default( refcase_list )); + + test_assert_false( ecl_refcase_list_set_default( refcase_list , "DoesNotExist")); + test_assert_false( ecl_refcase_list_has_default( refcase_list )); + test_assert_NULL( ecl_refcase_list_get_default( refcase_list )); + test_assert_int_equal( 1 , ecl_refcase_list_get_size( refcase_list )); + + test_assert_true( ecl_refcase_list_set_default( refcase_list , case1)); + test_assert_true( ecl_refcase_list_has_default( refcase_list )); + test_assert_not_NULL( ecl_refcase_list_get_default( refcase_list )); + test_assert_int_equal( 1 , ecl_refcase_list_get_size( refcase_list )); + + test_assert_false( ecl_refcase_list_set_default( refcase_list , "DoesNotExist")); + test_assert_true( ecl_refcase_list_has_default( refcase_list )); + test_assert_not_NULL( ecl_refcase_list_get_default( refcase_list )); + test_assert_int_equal( 1 , ecl_refcase_list_get_size( refcase_list )); + test_assert_NULL( ecl_refcase_list_iget_case( refcase_list , 100)); + + ecl_refcase_list_free( refcase_list ); + } + + { + ecl_refcase_list_type * refcase_list = ecl_refcase_list_alloc( ); + test_assert_int_equal( ecl_refcase_list_add_matching( refcase_list , case_glob ) , 11); + test_assert_int_equal( 11 , ecl_refcase_list_get_size( refcase_list )); + + test_assert_true( ecl_refcase_list_set_default( refcase_list , case1)); + test_assert_true( ecl_refcase_list_has_default( refcase_list )); + test_assert_not_NULL( ecl_refcase_list_get_default( refcase_list )); + test_assert_int_equal( 11 , ecl_refcase_list_get_size( refcase_list )); + + test_assert_int_equal( ecl_refcase_list_add_matching( refcase_list , case_glob ) , 0); + test_assert_int_equal( ecl_refcase_list_add_matching( refcase_list , case_glob ) , 0); + { + const ecl_sum_type * ecl_sum = ecl_refcase_list_iget_case( refcase_list , 0 ); + test_assert_not_NULL( ecl_sum ); + } + test_assert_int_equal( 11 , ecl_refcase_list_get_size( refcase_list )); + + { + stringlist_type * case_list = stringlist_alloc_new( ); + const int N = ecl_refcase_list_get_size( refcase_list ); + int i; + for (i=0; i < N; i++) + stringlist_append_ref( case_list , ecl_refcase_list_iget_pathcase( refcase_list , N - 1 - i )); + + { + bool equal = true; + for (i=0; i < N; i++) + equal = equal && util_string_equal( stringlist_iget( case_list , i ) , ecl_refcase_list_iget_pathcase( refcase_list , i)); + + test_assert_false( equal ); + stringlist_sort( case_list , util_strcmp_int); + + equal = true; + for (i=0; i < N; i++) + equal = equal && util_string_equal( stringlist_iget( case_list , i ) , ecl_refcase_list_iget_pathcase( refcase_list , i)); + test_assert_true( equal ); + } + + } + ecl_refcase_list_add_matching( refcase_list , "DoesNotExist*"); + test_assert_int_equal( 11 , ecl_refcase_list_get_size( refcase_list )); + ecl_refcase_list_free( refcase_list ); + } + + + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_report_list.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_report_list.c new file mode 100644 index 0000000000..fa2fe1d285 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_report_list.c @@ -0,0 +1,44 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_main.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include + +#include + +#include + +int main(int argc , char ** argv) { + config_type * config = config_alloc(); + ert_report_list_type * report_list = ert_report_list_alloc( NULL , NULL ); + + test_assert_not_NULL( report_list ); + ert_report_list_add_config_items( config ); + test_assert_true( config_parse( config , argv[1] , "--" , NULL, NULL , CONFIG_UNRECOGNIZED_IGNORE , true )); + ert_report_list_init( report_list , config , NULL); + + test_assert_int_equal( 167 , ert_report_list_get_latex_timeout( report_list )); + test_assert_true( ert_report_list_get_init_large_report( report_list )); + + ert_report_list_free( report_list ); + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_rng.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_rng.c new file mode 100644 index 0000000000..98e31631cc --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_rng.c @@ -0,0 +1,118 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_rng.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include + +#include +#include +#include + +int main(int argc , char ** argv) { + unsigned int rand1,rand2; + { + { + enkf_main_type * enkf_main = enkf_main_alloc_empty(); + enkf_main_resize_ensemble( enkf_main , 10 ); + { + enkf_state_type * state = enkf_main_iget_state( enkf_main , 9 ); + rand1 = enkf_state_get_random( state ); + } + enkf_main_free( enkf_main ); + } + + { + enkf_main_type * enkf_main = enkf_main_alloc_empty(); + enkf_main_resize_ensemble( enkf_main , 10 ); + { + enkf_state_type * state = enkf_main_iget_state( enkf_main , 9 ); + rand2 = enkf_state_get_random( state ); + } + enkf_main_free( enkf_main ); + } + test_assert_uint_not_equal( rand1 , rand2 ); + } + + /*****************************************************************/ + + { + const char * seed_file = "/tmp/seed"; + { + enkf_main_type * enkf_main = enkf_main_alloc_empty(); + { + rng_config_type * rng_config = enkf_main_get_rng_config( enkf_main ); + rng_config_set_seed_store_file( rng_config , seed_file ); + } + enkf_main_rng_init( enkf_main ); + + enkf_main_resize_ensemble( enkf_main , 10 ); + { + enkf_state_type * state = enkf_main_iget_state( enkf_main , 9 ); + rand1 = enkf_state_get_random( state ); + } + enkf_main_free( enkf_main ); + } + + { + enkf_main_type * enkf_main = enkf_main_alloc_empty(); + { + rng_config_type * rng_config = enkf_main_get_rng_config( enkf_main ); + rng_config_set_seed_load_file( rng_config , seed_file ); + } + enkf_main_rng_init( enkf_main ); + + enkf_main_resize_ensemble( enkf_main , 10 ); + { + enkf_state_type * state = enkf_main_iget_state( enkf_main , 9 ); + rand2 = enkf_state_get_random( state ); + } + enkf_main_free( enkf_main ); + } + test_assert_uint_equal( rand1 , rand2 ); + } + /*****************************************************************/ + { + { + enkf_main_type * enkf_main = enkf_main_bootstrap( NULL , argv[1] , true , true ); + enkf_state_type * state = enkf_main_iget_state( enkf_main , 9 ); + rand1 = enkf_state_get_random( state ); + enkf_main_free( enkf_main ); + } + + { + enkf_main_type * enkf_main = enkf_main_bootstrap( NULL , argv[1] , true , true ); + enkf_state_type * state = enkf_main_iget_state( enkf_main , 9 ); + rand2 = enkf_state_get_random( state ); + enkf_main_free( enkf_main ); + } + test_assert_uint_equal( rand1 , rand2 ); + + { + enkf_main_type * enkf_main = enkf_main_bootstrap( NULL , argv[1] , true , true ); + enkf_state_type * state = enkf_main_iget_state( enkf_main , 9 ); + rand2 = enkf_state_get_random( state ); + enkf_main_free( enkf_main ); + } + test_assert_uint_equal( rand1 , rand2 ); + } + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_runpath_list.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_runpath_list.c new file mode 100644 index 0000000000..4fe6d9676a --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_runpath_list.c @@ -0,0 +1,126 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_runpath_list.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include +#include + +#include + +void * add_pathlist( void * arg ) { + arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); + runpath_list_type * list = arg_pack_iget_ptr( arg_pack , 0 ); + int offset = arg_pack_iget_int( arg_pack , 1 ); + int bs = arg_pack_iget_int( arg_pack , 2 ); + + int i; + for (i=0; i < bs; i++) + runpath_list_add( list , i + offset , "Path" , "Basename"); + + return NULL; +} + + + + +int main(int argc , char ** argv) { + + runpath_list_type * list = runpath_list_alloc(); + + test_assert_int_equal( runpath_list_size( list ) , 0 ); + + runpath_list_add( list , 3 , "path" , "base"); + runpath_list_add( list , 2 , "path" , "base"); + runpath_list_add( list , 1 , "path" , "base"); + + test_assert_int_equal( runpath_list_size( list ) , 3 ); + test_assert_int_equal( runpath_list_iget_iens( list , 0 ) , 3 ); + test_assert_int_equal( runpath_list_iget_iens( list , 2 ) , 1 ); + runpath_list_sort( list ); + + test_assert_int_equal( runpath_list_iget_iens( list , 0 ) , 1 ); + test_assert_int_equal( runpath_list_iget_iens( list , 2 ) , 3 ); + runpath_list_clear( list ); + test_assert_int_equal( runpath_list_size( list ) , 0 ); + + test_assert_string_equal( runpath_list_get_line_fmt( list ) , RUNPATH_LIST_DEFAULT_LINE_FMT ); + { + const char * other_line = "%d %s %s"; + runpath_list_set_line_fmt( list , other_line ); + test_assert_string_equal( runpath_list_get_line_fmt( list ) , other_line ); + } + runpath_list_set_line_fmt( list , NULL ); + test_assert_string_equal( runpath_list_get_line_fmt( list ) , RUNPATH_LIST_DEFAULT_LINE_FMT ); + + { + const int block_size = 100; + const int threads = 100; + thread_pool_type * tp = thread_pool_alloc( threads , true ); + int it; + + for (it = 0; it < threads; it++) { + int iens_offset = it * block_size; + arg_pack_type * arg_pack = arg_pack_alloc(); + + arg_pack_append_ptr( arg_pack , list ); + arg_pack_append_int( arg_pack , iens_offset ); + arg_pack_append_int( arg_pack , block_size ); + + thread_pool_add_job( tp , add_pathlist , arg_pack ); + } + thread_pool_join( tp ); + test_assert_int_equal( runpath_list_size( list ) , block_size * threads ); + runpath_list_sort( list ); + { + int iens; + for (iens = 0; iens < block_size * threads; iens++) + test_assert_int_equal( runpath_list_iget_iens( list , iens ) , iens ); + } + + { + const char *filename = "/tmp/runpath_list.txt"; + { + FILE * stream = util_fopen( filename, "w"); + runpath_list_fprintf( list , stream ); + fclose( stream ); + } + + { + int file_iens; + char file_path[256]; + char file_base[256]; + int iens; + FILE * stream = util_fopen( filename, "r"); + for (iens = 0; iens < threads * block_size; iens++) { + int fscanf_return = fscanf( stream , "%d %s %s" , &file_iens , file_path , file_base); + test_assert_int_equal(fscanf_return, 3 ); + test_assert_int_equal( file_iens , iens ); + } + fclose( stream ); + } + } + } + runpath_list_free( list ); + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_site_config.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_site_config.c new file mode 100644 index 0000000000..0f1f672d74 --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_site_config.c @@ -0,0 +1,73 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_site_config.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include + + +#include + + + + +#define INCLUDE_KEY "INCLUDE" +#define DEFINE_KEY "DEFINE" + + +void test_empty() { + site_config_type * site_config = site_config_alloc_empty(); + site_config_free( site_config ); +} + + +void test_init(const char * config_file) { + site_config_type * site_config = site_config_alloc_empty(); + config_type * config = config_alloc(); + + site_config_add_config_items( config , true ); + if (!config_parse(config , config_file , "--" , INCLUDE_KEY , DEFINE_KEY , CONFIG_UNRECOGNIZED_WARN , true)) + test_error_exit("Parsing site config file:%s failed \n",config_file ); + + if (!site_config_init( site_config , config )) + test_error_exit("Loading site_config from config failed\n"); + + config_free( config ); + site_config_free( site_config ); +} + + +int main(int argc , char ** argv) { + const char * site_config_file = argv[1]; + test_empty(); + test_init( site_config_file ); + + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_time_map.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_time_map.c new file mode 100644 index 0000000000..21c6d50f9b --- /dev/null +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_time_map.c @@ -0,0 +1,133 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'enkf_time_map.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + + + +void ecl_test( const char * ecl_case ) { + ecl_sum_type * ecl_sum = ecl_sum_fread_alloc_case( ecl_case , ":"); + time_t start_time = ecl_sum_get_start_time( ecl_sum ); + time_t end_time = ecl_sum_get_end_time( ecl_sum ); + time_map_type * ecl_map = time_map_alloc( ); + + test_assert_true( time_map_summary_update( ecl_map , ecl_sum ) ); + test_assert_true( time_map_summary_update( ecl_map , ecl_sum ) ); + + test_assert_time_t_equal( time_map_get_start_time( ecl_map ) , start_time ); + test_assert_time_t_equal( time_map_get_end_time( ecl_map ) , end_time ); + test_assert_double_equal( time_map_get_end_days( ecl_map ) , ecl_sum_get_sim_length( ecl_sum )); + + time_map_clear( ecl_map ); + time_map_update( ecl_map , 1 , 256 ); + test_assert_false( time_map_summary_update( ecl_map , ecl_sum )); + + time_map_free( ecl_map ); + ecl_sum_free( ecl_sum ); +} + + + +void simple_test() { +time_map_type * time_map = time_map_alloc( ); + const char * mapfile = "/tmp/map"; + + test_assert_true( time_map_update( time_map , 0 , 100 ) ); + test_assert_true( time_map_update( time_map , 1 , 200 ) ); + test_assert_true( time_map_update( time_map , 1 , 200 ) ); + test_assert_false( time_map_update( time_map , 1 , 250 ) ); + + test_assert_true( time_map_equal( time_map , time_map ) ); + time_map_fwrite( time_map , mapfile); + { + time_map_type * time_map2 = time_map_alloc( ); + + test_assert_false( time_map_equal( time_map , time_map2 ) ); + time_map_fread( time_map2 , mapfile ); + test_assert_true( time_map_equal( time_map , time_map2 ) ); + time_map_free( time_map2 ); + } + { + time_t mtime1 = util_file_mtime( mapfile ); + sleep(2); + time_map_fwrite( time_map , mapfile); + + test_assert_time_t_equal( mtime1 , util_file_mtime( mapfile ) ); + time_map_update( time_map , 2 , 300 ); + time_map_fwrite( time_map , mapfile); + test_assert_time_t_not_equal( mtime1 , util_file_mtime( mapfile ) ); + } +} + + +#define MAP_SIZE 10000 + +void * update_time_map( void * arg ) { + time_map_type * time_map = time_map_safe_cast( arg ); + int i; + for (i=0; i < MAP_SIZE; i++) + time_map_update( time_map , i , i ); + return NULL; +} + + +void thread_test() { + time_map_type * time_map = time_map_alloc( ); + + { + int pool_size = 1000; + thread_pool_type * tp = thread_pool_alloc( pool_size/2 , true ); + + thread_pool_add_job( tp , update_time_map , time_map ); + + thread_pool_join(tp); + thread_pool_free(tp); + } + { + int i; + for (i=0; i < MAP_SIZE; i++) + test_assert_true( time_map_iget( time_map , i ) == i ); + } + time_map_free( time_map ); +} + + +int main(int argc , char ** argv) { + + if (argc == 1) { + simple_test(); + thread_test(); + } else + ecl_test( argv[1] ); + + + + exit(0); +} + diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/CMakeLists.txt b/ThirdParty/Ert/devel/libert_util/include/ert/util/CMakeLists.txt index 4fe85bd641..57291c4b47 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/CMakeLists.txt @@ -13,10 +13,11 @@ if (MSVC) list( APPEND header_files ${CMAKE_CURRENT_BINARY_DIR}/stdbool.h) endif() -foreach(header ${header_files}) - install(FILES ${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/util) -endforeach() - +if (INSTALL_ERT) + foreach(header ${header_files}) + install(FILES ${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/util) + endforeach() +endif() diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/hash.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/hash.h index 74f9212c1f..6e95b3ba9d 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/hash.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/hash.h @@ -71,6 +71,7 @@ void * hash_iter_get_next_value(hash_iter_type *); void hash_iter_restart( hash_iter_type * iter ); hash_type * hash_alloc_from_options(const stringlist_type *); +bool hash_add_option( hash_type * hash, const char * key_value); int hash_inc_counter(hash_type * hash , const char * counter_key); int hash_get_counter(hash_type * hash , const char * key); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/latex.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/latex.h index e4753d3984..6a21b54f13 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/latex.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/latex.h @@ -34,11 +34,13 @@ extern "C" { latex_type * latex_alloc( const char * input_file , bool in_place); void latex_free( latex_type * latex ); void latex_set_target_file( latex_type * latex , const char * target_file ); - bool latex_compile( latex_type * latex , bool ignore_errors , bool with_xref); + bool latex_compile( latex_type * latex , bool ignore_errors , bool with_xref , bool cleanup); + void latex_cleanup( latex_type * latex ); void latex_set_timeout( latex_type * latex , int timeout); int latex_get_timeout( const latex_type * latex ); const char * latex_get_runpath( const latex_type * latex ); const char * latex_get_target_file( const latex_type * latex ); + bool latex_compile_in_place( const latex_type * latex ); void latex_link_path( const latex_type * latex , const char * path); void latex_link_directory_content(const latex_type * latex , const char * path); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/log.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/log.h index f7a8c38ab5..01a243cfbe 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/log.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/log.h @@ -29,10 +29,8 @@ extern "C" { typedef struct log_struct log_type; FILE * log_get_stream(log_type * logh ); - void log_reset_filename( log_type * logh , const char * filename ); - void log_set_file(log_type * , const char *); - log_type * log_alloc_new(const char *filename, int log_level); - log_type * log_alloc_existing(const char *filename, int log_level); + void log_reopen( log_type * logh , const char * filename ); + log_type * log_open(const char *filename, int log_level); void log_add_message(log_type *logh, int message_level , FILE * dup_stream , char* message, bool free_message); void log_add_fmt_message(log_type * logh , int message_level , FILE * dup_stream , const char * fmt , ...); int log_get_level( const log_type * logh); @@ -42,6 +40,7 @@ typedef struct log_struct log_type; const char * log_get_filename( const log_type * logh ); int log_get_level( const log_type * logh); void log_set_level( log_type * logh , int log_level); + bool log_is_open( const log_type * logh); #ifdef __cplusplus diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/mzran.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/mzran.h index 23f1332d1b..564cc2116f 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/mzran.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/mzran.h @@ -35,6 +35,7 @@ void mzran_fscanf_state( void * __rng , FILE * stream ); unsigned int mzran_forward(void * __rng); void * mzran_alloc( void ); void mzran_set_state(void * __rng , const char * seed_buffer); +void mzran_get_state(void * __rng , char * state_buffer); double mzran_get_double(mzran_type * rng); int mzran_get_int( mzran_type * rng, int max); void mzran_fprintf_state( const void * __rng , FILE * stream); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/path_stack.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/path_stack.h new file mode 100644 index 0000000000..76f91edde1 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/path_stack.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'path_stack.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + + +#ifndef __PATH_STACK_H__ +#define __PATH_STACK_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct path_stack_struct path_stack_type; + + path_stack_type * path_stack_alloc(); + const char * path_stack_pop( path_stack_type * path_stack ); + void path_stack_push_cwd( path_stack_type * path_stack ); + bool path_stack_push( path_stack_type * path_stack , const char * path ); + void path_stack_free( path_stack_type * path_stack ); + int path_stack_size( const path_stack_type * path_stack ); + const char * path_stack_peek( const path_stack_type * path_stack ); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/rng.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/rng.h index aba2a3d0d5..bfe0f2db32 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/rng.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/rng.h @@ -41,6 +41,7 @@ typedef enum { typedef unsigned int ( rng_forward_ftype ) ( void * ); typedef void ( rng_set_state_ftype ) ( void * , const char * ); + typedef void ( rng_get_state_ftype ) ( void * , char * ); typedef void * ( rng_alloc_ftype ) ( void ); typedef void ( rng_free_ftype ) ( void * ); typedef void ( rng_fscanf_ftype ) ( void * , FILE * ); @@ -58,6 +59,10 @@ typedef enum { rng_alg_type rng_get_type( const rng_type * rng ); void rng_fprintf_state( rng_type * rng , FILE * stream ); void rng_fscanf_state( rng_type * rng , FILE * stream ); + int rng_state_size( const rng_type * rng ); + + void rng_set_state( rng_type * rng , const char * state); + void rng_get_state( const rng_type * rng , char * state); unsigned int rng_forward( rng_type * rng ); double rng_get_double( rng_type * rng ); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/string_util.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/string_util.h new file mode 100644 index 0000000000..af73d98f62 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/string_util.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'string_util.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ +#ifndef __STRING_UTIL_H__ +#define __STRING_UTIL_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include +#include + + bool string_util_init_active_list( const char * range_string , int_vector_type * active_list ); + bool string_util_update_active_list( const char * range_string , int_vector_type * active_list ); + int_vector_type * string_util_alloc_active_list( const char * range_string ); + + bool string_util_init_active_mask( const char * range_string , bool_vector_type * active_mask); + bool string_util_update_active_mask( const char * range_string , bool_vector_type * active_mask); + bool_vector_type * string_util_alloc_active_mask( const char * range_string ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/stringlist.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/stringlist.h index 7d1d98c8f4..450a875392 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/stringlist.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/stringlist.h @@ -32,7 +32,8 @@ extern "C" { typedef struct stringlist_struct stringlist_type; typedef int ( string_cmp_ftype) (const void * , const void *); - + const char * stringlist_get_last( const stringlist_type * stringlist ); + char * stringlist_pop( stringlist_type * stringlist); void stringlist_deep_copy( stringlist_type * target , const stringlist_type * src); stringlist_type * stringlist_alloc_deep_copy_with_limits(const stringlist_type * src , int offset, int num_strings); stringlist_type * stringlist_alloc_deep_copy_with_offset(const stringlist_type * src , int offset); @@ -50,6 +51,7 @@ typedef int ( string_cmp_ftype) (const void * , const void *); const char * stringlist_safe_iget( const stringlist_type * stringlist , int index); bool stringlist_iequal( const stringlist_type * stringlist , int index, const char * s ); const char * stringlist_iget(const stringlist_type * , int); + int stringlist_iget_as_int( const stringlist_type * stringlist , int index , bool * valid); char * stringlist_iget_copy(const stringlist_type * stringlist , int ); char * stringlist_alloc_joined_string(const stringlist_type * , const char * ); char * stringlist_alloc_joined_substring( const stringlist_type * s , int start_index , int end_index , const char * sep ); @@ -94,7 +96,8 @@ typedef int ( string_cmp_ftype) (const void * , const void *); void stringlist_buffer_fread( stringlist_type * s , buffer_type * buffer ); void stringlist_buffer_fwrite( const stringlist_type * s , buffer_type * buffer ); void stringlist_sort(stringlist_type * , string_cmp_ftype * string_cmp); - void stringlist_python_sort( stringlist_type * s , int cmp_flag); + void stringlist_reverse( stringlist_type * s ); + void stringlist_python_sort( stringlist_type * s , int cmp_flag); #ifdef HAVE_GLOB int stringlist_select_matching(stringlist_type * names , const char * pattern); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/subst_func.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/subst_func.h index dc41aeccf2..d31a7ba508 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/subst_func.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/subst_func.h @@ -33,8 +33,8 @@ typedef struct subst_func_pool_struct subst_func_pool_type; /*****************************************************************/ -subst_func_pool_type * subst_func_pool_alloc( ); -void subst_func_pool_free( subst_func_pool_type * pool ); + subst_func_pool_type * subst_func_pool_alloc( ); + void subst_func_pool_free( subst_func_pool_type * pool ); void subst_func_pool_add_func( subst_func_pool_type * pool , const char * func_name , const char * doc_string , subst_func_ftype * func , bool vararg, int argc_min , int argc_max , void * arg); subst_func_type * subst_func_pool_get_func( const subst_func_pool_type * pool , const char * func_name ); bool subst_func_pool_has_func( const subst_func_pool_type * pool , const char * func_name ); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/subst_list.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/subst_list.h index 909a2c7c24..548ba35518 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/subst_list.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/subst_list.h @@ -23,11 +23,12 @@ extern "C" { #endif #include +#include #include typedef struct subst_list_struct subst_list_type; - void subst_list_update_buffer( const subst_list_type * subst_list , buffer_type * buffer ); + bool subst_list_update_buffer( const subst_list_type * subst_list , buffer_type * buffer ); void subst_list_insert_func(subst_list_type * subst_list , const char * func_name , const char * local_func_name); void subst_list_fprintf(const subst_list_type * , FILE * stream); void subst_list_set_parent( subst_list_type * subst_list , const subst_list_type * parent); @@ -43,9 +44,9 @@ extern "C" { void subst_list_prepend_ref(subst_list_type * , const char * , const char * , const char * doc_string); void subst_list_prepend_owned_ref(subst_list_type * , const char * , const char * , const char * doc_string); - void subst_list_filter_file(const subst_list_type * , const char * , const char * ); - void subst_list_update_file(const subst_list_type * , const char * ); - void subst_list_update_string(const subst_list_type * , char ** ); + bool subst_list_filter_file(const subst_list_type * , const char * , const char * ); + bool subst_list_update_file(const subst_list_type * , const char * ); + bool subst_list_update_string(const subst_list_type * , char ** ); char * subst_list_alloc_filtered_string(const subst_list_type * , const char * ); void subst_list_filtered_fprintf(const subst_list_type * , const char * , FILE * ); int subst_list_get_size( const subst_list_type *); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/template.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/template.h index bccbedc6b8..691bd9538b 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/template.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/template.h @@ -32,7 +32,7 @@ typedef struct template_struct template_type; template_type * template_alloc( const char * template_file , bool internalize_template, subst_list_type * parent_subst); void template_free( template_type * template ); -void template_instansiate( const template_type * template , const char * __target_file , const subst_list_type * arg_list , bool override_symlink); +void template_instantiate( const template_type * template , const char * __target_file , const subst_list_type * arg_list , bool override_symlink); void template_add_arg( template_type * template , const char * key , const char * value ); void template_clear_args( template_type * template ); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/test_util.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/test_util.h index 4dc39eafab..70dad43e99 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/test_util.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/test_util.h @@ -38,36 +38,57 @@ extern "C" { #define test_assert_int_not_equal( i1 , i2 ) test_assert_int_not_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) void test_assert_int_not_equal__( int i1 , int i2 , const char * file , int line ); +#define test_assert_uint_equal( i1 , i2 ) test_assert_uint_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) + void test_assert_uint_equal__( unsigned int i1 , unsigned int i2 , const char * file , int line ); + +#define test_assert_uint_not_equal( i1 , i2 ) test_assert_uint_not_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) + void test_assert_uint_not_equal__( unsigned int i1 , unsigned int i2 , const char * file , int line ); + + +#define test_assert_double_equal( d1 , d2 ) test_assert_double_equal__( (d1) , (d2) , __FILE__ , __LINE__ ) + void test_assert_double_equal__( double d1 , double d2 , const char * file , int line ); + +#define test_assert_double_not_equal( d1 , d2 ) test_assert_double_not_equal__( (d1) , (d2) , __FILE__ , __LINE__ ) + void test_assert_double_not_equal__( double d1 , double d2 , const char * file , int line ); + #define test_assert_bool_equal( b1 , b2 ) test_assert_bool_equal__( (b1) , (b2) , __FILE__ , __LINE__ ) void test_assert_bool_equal__( bool b1 , bool b2 , const char * file , int line); -#define test_assert_true( value ) test_assert_true__( (value) , __FILE__ , __LINE__); +#define test_assert_true( value ) test_assert_true__( (value) , __FILE__ , __LINE__) void test_assert_true__( bool value, const char * file , int line); -#define test_assert_false( value ) test_assert_false__( (value) , __FILE__ , __LINE__); +#define test_assert_false( value ) test_assert_false__( (value) , __FILE__ , __LINE__) void test_assert_false__( bool value, const char * file , int line); - -#define test_assert_time_t_equal( t1 , t2) test_assert_time_t_equal__((t1) , (t2) , __FILE__ , __LINE__); + +#define test_assert_time_t_equal( t1 , t2) test_assert_time_t_equal__((t1) , (t2) , __FILE__ , __LINE__) void test_assert_time_t_equal__( time_t t1 , time_t t2 , const char * file , int line); -#define test_assert_time_t_not_equal( t1 , t2) test_assert_time_t_not_equal__((t1) , (t2) , __FILE__ , __LINE__); +#define test_assert_time_t_not_equal( t1 , t2) test_assert_time_t_not_equal__((t1) , (t2) , __FILE__ , __LINE__) void test_assert_time_t_not_equal__( time_t t1 , time_t t2 , const char * file , int line); -#define test_assert_ptr_equal( p1 , p2 ) test_assert_ptr_equal__( (p1) , (p2) , __FILE__ , __LINE__); +#define test_assert_ptr_equal( p1 , p2 ) test_assert_ptr_equal__( (p1) , (p2) , __FILE__ , __LINE__) void test_assert_ptr_equal__( const void * p1 , const void * p2 , const char * file , int line); -#define test_assert_NULL( p ) test_assert_NULL__( (p) , __FILE__ , __LINE__); +#define test_assert_ptr_not_equal(p1 , p2) test_assert_ptr_not_equal__( (p1) , (p2) , __FILE__ , __LINE__) + void test_assert_ptr_not_equal__( const void * p1 , const void * p2 , const char * file , int line); + +#define test_assert_NULL( p ) test_assert_NULL__( (p) , __FILE__ , __LINE__) void test_assert_NULL__( const void * p , const char * file , int line); -#define test_assert_not_NULL( p ) test_assert_not_NULL__( (p) , __FILE__ , __LINE__); +#define test_assert_not_NULL( p ) test_assert_not_NULL__( (p) , __FILE__ , __LINE__) void test_assert_not_NULL__( const void * p , const char * file , int line); -#define test_assert_mem_equal( p1 , p2 , byte_size ) test_assert_mem_equal__( (p1) , (p2) , (byte_size), __FILE__ , __LINE__); +#define test_assert_mem_equal( p1 , p2 , byte_size ) test_assert_mem_equal__( (p1) , (p2) , (byte_size), __FILE__ , __LINE__) void test_assert_mem_equal__( const void * p1 , const void * p2 , size_t byte_size , const char * file , int line); -#define test_assert_mem_not_equal( p1 , p2 , byte_size ) test_assert_mem_not_equal__( (p1) , (p2) , (byte_size), __FILE__ , __LINE__); +#define test_assert_mem_not_equal( p1 , p2 , byte_size ) test_assert_mem_not_equal__( (p1) , (p2) , (byte_size), __FILE__ , __LINE__) void test_assert_mem_not_equal__( const void * p1 , const void * p2 , size_t byte_size , const char * file , int line); + +#ifdef HAVE_UTIL_ABORT + void test_util_addr2line(); +#endif + #ifdef __cplusplus } #endif diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/time_interval.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/time_interval.h new file mode 100644 index 0000000000..048d5f25f2 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/time_interval.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'time_interval.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + +#ifndef __TIME_INTERVAL_H__ +#define __TIME_INTERVAL_H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + typedef struct time_interval_struct time_interval_type; + + time_interval_type * time_interval_alloc( time_t start_time , time_t end_time ); + time_interval_type * time_interval_alloc_open( ); + time_interval_type * time_interval_alloc_copy( const time_interval_type * src); + void time_interval_reopen( time_interval_type * time_interval); + void time_interval_free( time_interval_type * ti ); + bool time_interval_is_empty( time_interval_type * ti ); + bool time_interval_update( time_interval_type * ti , time_t start_time , time_t end_time); + bool time_interval_contains( const time_interval_type * ti , time_t t); + bool time_interval_has_overlap( const time_interval_type * t1 , const time_interval_type * t2); + bool time_interval_is_adjacent( const time_interval_type * t1 , const time_interval_type * t2); + bool time_interval_update_start( time_interval_type * ti , time_t start_time ); + bool time_interval_update_end( time_interval_type * ti , time_t end_time ); + time_t time_interval_get_start( const time_interval_type * ti); + time_t time_interval_get_end( const time_interval_type * ti); + bool time_interval_extend( time_interval_type * t1 , const time_interval_type * t2); + bool time_interval_intersect( time_interval_type * t1 , const time_interval_type * t2); + bool time_interval_equal( const time_interval_type * t1 , const time_interval_type * t2); + bool time_interval_arg_before( const time_interval_type * ti , time_t arg); + bool time_interval_arg_after( const time_interval_type * ti , time_t arg); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/util.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/util.h index b519fb9514..a4f09bf665 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/util.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/util.h @@ -76,9 +76,14 @@ typedef enum {left_pad = 0, void util_fprintf_datetime(time_t , FILE * ); void util_fprintf_date(time_t , FILE * ); time_t util_make_date(int , int , int); + time_t util_make_pure_date(time_t t); void util_inplace_forward_days(time_t * , double); + time_t util_file_mtime(const char * file); double util_difftime(time_t , time_t , int * , int * , int * , int *); double util_difftime_days(time_t , time_t ); + double util_difftime_seconds( time_t start_time , time_t end_time); + bool util_after( time_t t , time_t limit); + bool util_before( time_t t , time_t limit); bool util_file_newer( const char * file , time_t t0); bool util_file_older( const char * file , time_t t0); char * util_alloc_date_string( time_t t ); @@ -87,6 +92,7 @@ typedef enum {left_pad = 0, bool util_char_in(char c, int , const char *); char * util_alloc_sprintf_va(const char * fmt , va_list ap); char * util_alloc_sprintf(const char * , ...); + char * util_alloc_sprintf_escape(const char * src , int max_escape); char * util_realloc_sprintf(char * , const char * , ...); void util_fprintf_int(int , int , FILE * ); void util_fprintf_string(const char * , int , string_alignement_type , FILE * ); @@ -100,6 +106,7 @@ typedef enum {left_pad = 0, bool util_file_exists(const char *); bool util_is_abs_path(const char * ); char * util_alloc_abs_path( const char * path ); + char * util_alloc_rel_path( const char * __root_path , const char * path); bool util_fmt_bit8 (const char *); bool util_fmt_bit8_stream(FILE * ); void util_make_path (const char *); @@ -118,9 +125,12 @@ typedef enum {left_pad = 0, void util_move_file4( const char * src_name , const char * target_name , const char *src_path , const char * target_path); bool util_copy_file(const char * , const char * ); char * util_alloc_cwd(void); + bool util_is_cwd( const char * path ); char * util_alloc_realpath(const char * ); + char * util_alloc_realpath__(const char * input_path); bool util_string_match(const char * string , const char * pattern); bool util_string_has_wildcard( const char * s); + bool util_file_readable( const char * file ); bool util_entry_readable( const char * entry ); bool util_entry_writable( const char * entry ); void util_ftruncate(FILE * stream , long size); @@ -220,11 +230,13 @@ typedef enum {left_pad = 0, char * util_alloc_dequoted_copy(const char *s); void util_safe_free(void *); void util_free_stringlist(char **, int ); + void util_free_NULL_terminated_stringlist(char ** string_list); char * util_alloc_substring_copy(const char *, int offset , int N); bool util_is_directory(const char * ); bool util_is_file(const char * ); void util_set_datetime_values(time_t , int * , int * , int * , int * , int * , int *); void util_set_date_values(time_t , int * , int * , int * ); + bool util_is_first_day_in_month( time_t t); void util_fread_from_buffer(void * , size_t , size_t , char ** ); @@ -239,7 +251,7 @@ typedef enum {left_pad = 0, void util_abort_signal(int ); void util_abort_append_version_info(const char * ); void util_abort_free_version_info(); - void util_abort_set_executable( const char * executable ); + void util_abort_set_executable( const char * argv0 ); void * util_realloc(void * , size_t ); void * util_malloc(size_t ); void * util_calloc( size_t elements , size_t element_size ); @@ -303,8 +315,6 @@ typedef enum {left_pad = 0, bool util_sscanf_bytesize(const char * , size_t *); - void util_sscanf_active_range(const char * , int , bool * ); - int * util_sscanf_alloc_active_list(const char * , int * ); int util_get_current_linenr(FILE * stream); const char * util_update_path_var(const char * , const char * , bool ); @@ -317,9 +327,11 @@ typedef enum {left_pad = 0, char * util_fscanf_alloc_upto(FILE * stream , const char * stop_string, bool include_stop_string); bool util_files_equal( const char * file1 , const char * file2 ); double util_kahan_sum(const double *data, size_t N); + bool util_double_approx_equal( double d1 , double d2); int util_fnmatch( const char * pattern , const char * string ); void util_localtime( time_t * t , struct tm * ts ); - + + char ** util_alloc_PATH_list(); char * util_alloc_PATH_executable(const char * executable ); char * util_isscanf_alloc_envvar( const char * string , int env_index ); void util_setenv( const char * variable , const char * value); @@ -422,13 +434,17 @@ const char * util_enum_iget( int index , int size , const util_enum_element_type #ifdef HAVE_SYMLINK void util_make_slink(const char *, const char * ); char * util_alloc_link_target(const char * link); - #ifdef HAVE_READLINKAT - char * util_alloc_atlink_target(const char * path , const char * link); - #endif +#ifdef HAVE_READLINKAT + char * util_alloc_atlink_target(const char * path , const char * link); +#endif #endif + #ifdef HAVE_FORK -#include "util_fork.h" + pid_t util_fork_exec(const char * , int , const char ** , bool , const char * , const char * , const char * , const char * , const char * ); + uid_t * util_alloc_file_users( const char * filename , int * __num_users); + char * util_alloc_filename_from_stream( FILE * input_stream ); + bool util_ping( const char * hostname); #endif @@ -437,6 +453,17 @@ const char * util_enum_iget( int index , int size , const util_enum_element_type bool util_try_lockf(const char * , mode_t , int * ); #endif +#ifdef HAVE_FORK +#ifdef WITH_PTHREAD +#ifdef HAVE_EXECINFO + + bool util_addr2line_lookup(const void * bt_addr , char ** func_name , char ** file_line, int * line_nr); + +#define HAVE_UTIL_ABORT +#endif +#endif +#endif + diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/util_fork.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/util_fork.h deleted file mode 100644 index a64f9e1c13..0000000000 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/util_fork.h +++ /dev/null @@ -1,11 +0,0 @@ -/** - Headers for the functions in util_fork.c - i.e. the functions which - are based on the fork() system call. - - This file will be included directly from the util.h header file. -*/ - -pid_t util_fork_exec(const char * , int , const char ** , bool , const char * , const char * , const char * , const char * , const char * ); -uid_t * util_alloc_file_users( const char * filename , int * __num_users); -char * util_alloc_filename_from_stream( FILE * input_stream ); - diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/vector.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/vector.h index ca24a17435..64552a831d 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/vector.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/vector.h @@ -74,6 +74,7 @@ extern "C" { int vector_get_size( const vector_type * ); void * vector_pop(vector_type * ); void vector_sort(vector_type * vector , vector_cmp_ftype * cmp); + void vector_inplace_reverse(vector_type * vector); vector_type * vector_alloc_copy(const vector_type * src , bool deep_copy); void vector_iset_buffer(vector_type * vector , int index , const void * buffer, int buffer_size); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/vector_template.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/vector_template.h index fa875cd7f1..f104253b1a 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/vector_template.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/vector_template.h @@ -22,6 +22,7 @@ extern "C" { #endif #include +#include #include #include @@ -63,6 +64,7 @@ typedef @TYPE@ (@TYPE@_ftype) (@TYPE@); @TYPE@ @TYPE@_vector_idel( @TYPE@_vector_type * vector , int index); void @TYPE@_vector_insert( @TYPE@_vector_type * vector , int index , @TYPE@ value); void @TYPE@_vector_append(@TYPE@_vector_type * , @TYPE@); + void @TYPE@_vector_free_container(@TYPE@_vector_type * vector); void @TYPE@_vector_free(@TYPE@_vector_type *); void @TYPE@_vector_free__(void *); void @TYPE@_vector_free_data(@TYPE@_vector_type *); @@ -75,6 +77,7 @@ typedef @TYPE@ (@TYPE@_ftype) (@TYPE@); @TYPE@ * @TYPE@_vector_get_ptr(const @TYPE@_vector_type * ); @TYPE@ * @TYPE@_vector_alloc_data_copy( const @TYPE@_vector_type * vector ); const @TYPE@ * @TYPE@_vector_get_const_ptr(const @TYPE@_vector_type * ); + bool @TYPE@_vector_init_range(@TYPE@_vector_type * vector , @TYPE@ min_value , @TYPE@ max_value , @TYPE@ delta); void @TYPE@_vector_set_many(@TYPE@_vector_type * , int , const @TYPE@ * , int ); void @TYPE@_vector_set_all(@TYPE@_vector_type * vector , @TYPE@ value); void @TYPE@_vector_append_many(@TYPE@_vector_type * vector , const @TYPE@ * data , int length); diff --git a/ThirdParty/Ert/devel/libert_util/src/CMakeLists.txt b/ThirdParty/Ert/devel/libert_util/src/CMakeLists.txt index cc7766f7b8..a753d36d3b 100644 --- a/ThirdParty/Ert/devel/libert_util/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libert_util/src/CMakeLists.txt @@ -1,7 +1,7 @@ -set(source_files rng.c lookup_table.c statistics.c mzran.c set.c hash_node.c hash_sll.c hash.c node_data.c node_ctype.c util.c thread_pool.c msg.c arg_pack.c path_fmt.c menu.c subst_list.c subst_func.c vector.c parser.c stringlist.c matrix.c buffer.c log.c template.c timer.c test_util.c) +set(source_files rng.c lookup_table.c statistics.c mzran.c set.c hash_node.c hash_sll.c hash.c node_data.c node_ctype.c util.c thread_pool.c msg.c arg_pack.c path_fmt.c menu.c subst_list.c subst_func.c vector.c parser.c stringlist.c matrix.c buffer.c log.c template.c timer.c test_util.c time_interval.c string_util.c) +set(header_files ssize_t.h type_macros.h rng.h lookup_table.h statistics.h mzran.h set.h hash.h hash_node.h hash_sll.h node_data.h node_ctype.h util.h thread_pool.h msg.h arg_pack.h path_fmt.h stringlist.h menu.h subst_list.h subst_func.h vector.h parser.h matrix.h buffer.h log.h template.h timer.h test_util.h time_interval.h string_util.h) -set(header_files ssize_t.h type_macros.h rng.h lookup_table.h statistics.h mzran.h set.h hash.h hash_node.h hash_sll.h node_data.h node_ctype.h util.h thread_pool.h msg.h arg_pack.h path_fmt.h stringlist.h menu.h subst_list.h subst_func.h vector.h parser.h matrix.h buffer.h log.h template.h timer.h test_util.h) if (WITH_LATEX) add_definitions( -DWITH_LATEX ) @@ -16,6 +16,11 @@ if (WITH_LAPACK) list( APPEND header_files matrix_lapack.h matrix_blas.h regression.h lars.h stepwise.h) endif() +if (UNISTD_HEADER) + list( APPEND source_files path_stack.c ) + list( APPEND header_files path_stack.h ) +endif() + foreach (type int double bool long time_t size_t float) set(TYPE ${type} ) set(src_target ${CMAKE_CURRENT_BINARY_DIR}/${type}_vector.c) @@ -25,11 +30,9 @@ foreach (type int double bool long time_t size_t float) list( APPEND source_files ${src_target} ) endforeach( type ) - -#if (WITH_ZLIB) -# list( APPEND source_files util_zlib.c ) -# list( APPEND header_files util_zlib.h ) -#endif() +if (PING_PATH) + add_definitions( -DPING_CMD=\"${PING_PATH}\") +endif() # The block_fs filesystem is so heavily dependant on pthreads that it is not # built if de not have pthreads. @@ -67,13 +70,17 @@ endif() if (NEED_LIBM) target_link_libraries( ert_util m ) endif() +if (NEED_LIBDL) + target_link_libraries( ert_util dl ) +endif() #----------------------------------------------------------------- -install(TARGETS ert_util DESTINATION ${CMAKE_INSTALL_LIBDIR}) -foreach(header ${header_files}) - install(FILES ../include/ert/util/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/util) -endforeach() - +if (INSTALL_ERT) + install(TARGETS ert_util DESTINATION ${CMAKE_INSTALL_LIBDIR}) + foreach(header ${header_files}) + install(FILES ../include/ert/util/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/util) + endforeach() +endif() diff --git a/ThirdParty/Ert/devel/libert_util/src/hash.c b/ThirdParty/Ert/devel/libert_util/src/hash.c index 02f7beb5cc..7a25deb62a 100644 --- a/ThirdParty/Ert/devel/libert_util/src/hash.c +++ b/ThirdParty/Ert/devel/libert_util/src/hash.c @@ -836,6 +836,24 @@ hash_type * hash_alloc_from_options(const stringlist_type * options) { } + bool hash_add_option( hash_type * hash, const char * key_value) { + bool addOK = false; + { + char * value; + char * key; + + util_binary_split_string( key_value , ":" , true , &key , &value); + if (value != NULL) { + hash_insert_hash_owned_ref( hash , key , value , free ); + addOK = true; + } + + util_safe_free( key ); + } + return addOK; +} + + /*****************************************************************/ diff --git a/ThirdParty/Ert/devel/libert_util/src/latex.c b/ThirdParty/Ert/devel/libert_util/src/latex.c index 394e482a7f..d3688bebcc 100644 --- a/ThirdParty/Ert/devel/libert_util/src/latex.c +++ b/ThirdParty/Ert/devel/libert_util/src/latex.c @@ -99,9 +99,24 @@ latex_type * latex_alloc( const char * input_file , bool in_place ) { char * input_path; char * input_extension; latex_type * latex = util_malloc( sizeof * latex ); - + + latex->latex_cmd = NULL; + latex->target_file = NULL; + latex->target_extension = NULL; + latex->target_path = NULL; + latex->result_file = NULL; + latex->basename = NULL; + latex->run_path = NULL; + latex->in_place = in_place; - util_alloc_file_components( input_file , &input_path , &latex->basename , &input_extension ); + { + char * basename; + util_alloc_file_components( input_file , &input_path , &basename , &input_extension ); + if (basename == NULL) + util_abort("%s: must provide a basename \n",__func__); + latex->basename = basename; + } + if (input_path == NULL) input_path = util_alloc_cwd( ); else { @@ -141,12 +156,6 @@ latex_type * latex_alloc( const char * input_file , bool in_place ) { /* Setting various default values. */ - latex->target_file = NULL; - latex->latex_cmd = NULL; - latex->target_extension = NULL; - latex->target_path = NULL; - latex->result_file = NULL; - latex_set_target_extension( latex , TARGET_EXTENSION ); latex_set_target_path( latex , input_path ); latex_set_command( latex , __LATEX_CMD ); @@ -185,7 +194,7 @@ static void latex_copy_target( latex_type * latex ) { } -static void latex_cleanup( latex_type * latex ) { +void latex_cleanup( latex_type * latex ) { if (latex->in_place) { int num_extensions = sizeof( delete_extensions ) / sizeof( delete_extensions[0] ); for (int iext = 0; iext < num_extensions; iext++) { @@ -198,6 +207,10 @@ static void latex_cleanup( latex_type * latex ) { } +bool latex_compile_in_place( const latex_type * latex ) { + return latex->in_place; +} + static void latex_ensure_target_file( latex_type * latex) { if (latex->target_file == NULL) @@ -205,48 +218,52 @@ static void latex_ensure_target_file( latex_type * latex) { } static bool latex_compile__( latex_type * latex , bool ignore_errors) { - bool normal_exit = true; - char ** argv; - int argc; - char * stderr_file = util_alloc_filename( latex->run_path , "latex" , "stderr"); - char * stdout_file = util_alloc_filename( latex->run_path , "latex" , "stdout"); - int usleep_time = 500000; /* 1/2 second. */ + if (util_is_directory( latex->run_path)) { + bool normal_exit = true; + char ** argv; + int argc; + char * stderr_file = util_alloc_filename( latex->run_path , "latex" , "stderr"); + char * stdout_file = util_alloc_filename( latex->run_path , "latex" , "stdout"); + int usleep_time = 500000; /* 1/2 second. */ - argc = 2; - argv = util_malloc( argc * sizeof * argv ); - if (ignore_errors) - argv[0] = "-interaction=nonstopmode"; - else - argv[0] = "-halt-on-error"; - argv[0] = "-halt-on-error";//latex->src_file; - - argv[1] = latex->src_file; - { - pid_t child_pid = util_fork_exec( latex->latex_cmd , argc , (const char **) argv , false , NULL , latex->run_path , NULL , stdout_file , stderr_file ); - double total_wait = 0; - int status; - - while (true) { - if (waitpid(child_pid , &status , WNOHANG) == 0) { - util_usleep( usleep_time ); - total_wait += usleep_time / 1000000.0; - - if (total_wait > latex->timeout) { - // Exit due to excessive time usage. - normal_exit = false; - kill( child_pid , SIGKILL ); - } - } else - // The child has exited - succesfull or not? - break; + argc = 2; + argv = util_malloc( argc * sizeof * argv ); + if (ignore_errors) + argv[0] = "-interaction=nonstopmode"; + else + argv[0] = "-halt-on-error"; + argv[0] = "-halt-on-error";//latex->src_file; + + argv[1] = latex->src_file; + { + pid_t child_pid = util_fork_exec( latex->latex_cmd , argc , (const char **) argv , false , NULL , latex->run_path , NULL , stdout_file , stderr_file ); + double total_wait = 0; + int status; + + while (true) { + if (waitpid(child_pid , &status , WNOHANG) == 0) { + util_usleep( usleep_time ); + total_wait += usleep_time / 1000000.0; + + if (total_wait > latex->timeout) { + // Exit due to excessive time usage. + normal_exit = false; + kill( child_pid , SIGKILL ); + } + } else + // The child has exited - succesfull or not? + break; + } } - } - - free( stderr_file ); - free( stdout_file ); - free( argv ); - - return normal_exit; + + free( stderr_file ); + free( stdout_file ); + free( argv ); + + return normal_exit; + } else + return false; // The runpath directory does not exist; if we try to rerun the latex + // compile on the same instance, after a cleanup this might happen. } /** @@ -254,7 +271,7 @@ static bool latex_compile__( latex_type * latex , bool ignore_errors) { compilation has been successfull or not. */ -bool latex_compile( latex_type * latex , bool ignore_errors , bool with_xref) { +bool latex_compile( latex_type * latex , bool ignore_errors , bool with_xref , bool cleanup) { int num_compile = 1; time_t compile_start; @@ -290,7 +307,8 @@ bool latex_compile( latex_type * latex , bool ignore_errors , bool with_xref) { if (success) { latex_copy_target( latex ); - latex_cleanup( latex ); + if (cleanup) + latex_cleanup( latex ); } return success; @@ -309,13 +327,12 @@ void latex_set_timeout( latex_type * latex , int timeout) { void latex_free( latex_type * latex ) { - - free( latex->latex_cmd ); - free( latex->run_path ); - free( latex->src_file ); - free( latex->basename ); - free( latex->target_extension ); - free( latex->target_path ); + util_safe_free( latex->latex_cmd ); + util_safe_free( latex->run_path ); + util_safe_free( latex->src_file ); + util_safe_free( latex->basename ); + util_safe_free( latex->target_extension ); + util_safe_free( latex->target_path ); util_safe_free( latex->target_file ); util_safe_free( latex->result_file ); diff --git a/ThirdParty/Ert/devel/libert_util/src/log.c b/ThirdParty/Ert/devel/libert_util/src/log.c index b498eed00e..bea28caa3c 100644 --- a/ThirdParty/Ert/devel/libert_util/src/log.c +++ b/ThirdParty/Ert/devel/libert_util/src/log.c @@ -48,7 +48,7 @@ struct log_struct { -void log_reset_filename(log_type *logh , const char *filename) { +void log_reopen(log_type *logh , const char *filename) { if (logh->stream != NULL) { /* Close the existing file descriptor. */ size_t file_size; fclose( logh->stream ); @@ -66,7 +66,7 @@ void log_reset_filename(log_type *logh , const char *filename) { logh->stream = util_mkdir_fopen( filename , "a+"); logh->fd = fileno( logh->stream ); } else { /* It is ~OK to open a log with NULL filename, but then - log_reset_filename() with a VALID filename must be + log_reopen() with a VALID filename must be called before it is actually used. */ logh->stream = NULL; logh->fd = -1; @@ -93,8 +93,9 @@ void log_set_level( log_type * logh , int log_level) { -static log_type *log_alloc_internal(const char *filename , bool new, int log_level) { +log_type * log_open( const char * filename , int log_level) { log_type *logh; + logh = util_malloc(sizeof *logh ); logh->log_level = log_level; @@ -103,24 +104,13 @@ static log_type *log_alloc_internal(const char *filename , bool new, int log_lev #ifdef HAVE_PTHREAD pthread_mutex_init( &logh->mutex , NULL ); #endif - log_reset_filename( logh ,filename ); - + if (filename != NULL) + log_reopen( logh , filename); + return logh; } -log_type * log_alloc_new(const char *filename, int log_level) { - log_type *logh = log_alloc_internal(filename , true , log_level); - return logh; -} - - - -log_type *log_alloc_existing(const char *filename, int log_level) { - return log_alloc_internal(filename , false , log_level); -} - - static bool log_include_message(const log_type *logh , int message_level) { if (message_level <= logh->log_level) @@ -212,9 +202,17 @@ void log_sync(log_type * logh) { void log_close( log_type * logh ) { - if ((logh->stream != stdout) && (logh->stream != stderr)) + if ((logh->stream != stdout) && (logh->stream != stderr) && (logh->stream != NULL)) fclose( logh->stream ); /* This closes BOTH the FILE * stream and the integer file descriptor. */ - free( logh->filename ); + util_safe_free( logh->filename ); free( logh ); } + + +bool log_is_open( const log_type * logh) { + if (logh->stream != NULL) + return true; + else + return false; +} diff --git a/ThirdParty/Ert/devel/libert_util/src/menu.c b/ThirdParty/Ert/devel/libert_util/src/menu.c index 291164287f..70704efba5 100644 --- a/ThirdParty/Ert/devel/libert_util/src/menu.c +++ b/ThirdParty/Ert/devel/libert_util/src/menu.c @@ -141,7 +141,7 @@ static bool __string_contains(const char * string , const char * char_set) { menu_type * menu_alloc(const char * title , const char * quit_label , const char * quit_keys) { menu_type * menu = util_malloc(sizeof * menu ); - menu->title = util_alloc_string_copy( title ); + menu->title = util_alloc_sprintf_escape( title , 0 ); menu->quit_keys = util_alloc_string_copy( quit_keys ); menu->items = vector_alloc_new(); menu->complete_key_set = util_alloc_string_copy( quit_keys ); @@ -311,7 +311,7 @@ static void __print_helptext(char * label, int l){ while(!end_reached){ int i; if(strlen(label_copy) > l){ - util_binary_split_string_from_max_length(label_copy , " ", l , &first_part , &second_part); + util_binary_split_string_from_max_length(label_copy , " ", l , &first_part , &second_part); printf("| %s",first_part); for (i=strlen(first_part); i < l; i++) fputc(' ' , stdout); diff --git a/ThirdParty/Ert/devel/libert_util/src/mzran.c b/ThirdParty/Ert/devel/libert_util/src/mzran.c index bf128a027a..32d83c22ed 100644 --- a/ThirdParty/Ert/devel/libert_util/src/mzran.c +++ b/ThirdParty/Ert/devel/libert_util/src/mzran.c @@ -170,19 +170,38 @@ void mzran_fprintf_state( const void * __rng , FILE * stream) { +static void mzran_set_default_state( mzran_type * rng ) { + mzran_set_state4( rng , DEFAULT_S0 , DEFAULT_S1 , DEFAULT_S2 , DEFAULT_S3); +} + + /** This function will set the state of the rng, based on a buffer of length buffer size. 16 bytes will be read from the seed buffer. */ -void mzran_set_state(void * __rng , const char * seed_buffer) { +void mzran_set_state(void * __rng , const char * state_buffer) { mzran_type * rng = mzran_safe_cast( __rng ); - const unsigned int * seed = (const unsigned int *) seed_buffer; - mzran_set_state4( rng , seed[0] , seed[1] , seed[2] , seed[3]); + if (state_buffer == NULL) + mzran_set_default_state(rng); + else { + const unsigned int * state = (const unsigned int *) state_buffer; + mzran_set_state4( rng , state[0] , state[1] , state[2] , state[3]); + } } +void mzran_get_state(void * __rng , char * state_buffer) { + mzran_type * rng = mzran_safe_cast( __rng ); + unsigned int * state = (unsigned int *) state_buffer; + + state[0] = rng->x; + state[1] = rng->y; + state[2] = rng->z; + state[3] = rng->n; +} + /** @@ -199,7 +218,7 @@ void mzran_set_state(void * __rng , const char * seed_buffer) { void * mzran_alloc( void ) { mzran_type * rng = util_malloc( sizeof * rng ); UTIL_TYPE_ID_INIT( rng , MZRAN_TYPE_ID ); - mzran_set_state4( rng , DEFAULT_S0 , DEFAULT_S1 , DEFAULT_S2 , DEFAULT_S3); + mzran_set_default_state( rng ); return rng; } diff --git a/ThirdParty/Ert/devel/libert_util/src/path_stack.c b/ThirdParty/Ert/devel/libert_util/src/path_stack.c new file mode 100644 index 0000000000..3391c1089e --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/src/path_stack.c @@ -0,0 +1,119 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'path_stack.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include + +/** + This file implements the structure path_stack which is vaguely + inspired by the emacs-lisp scecial form (save-excursion ...). The + intentiation with the 'class' is to push directories onto a stack, + and then each time you pop from the stack the the process will + chdir() back to directory which is popped. + + Observe that the constructor path_stack_alloc() and destructor + path_stack_free() do *not* alter the stack or the cwd of the + process. +*/ + + +struct path_stack_struct { + stringlist_type * stack; + stringlist_type * storage; +}; + + +/** + This will create a new path_stack instance; it will push anything + on the current stack of paths. +*/ + +path_stack_type * path_stack_alloc() { + path_stack_type * path_stack = util_malloc( sizeof * path_stack ); + path_stack->stack = stringlist_alloc_new(); + path_stack->storage = stringlist_alloc_new(); + return path_stack; +} + +/* + This will destroy the storage taken by the current path_stack + instance. This function will NOT pop any elements off the stack; so + if you have not manully clerad the stack with the right number of + path_stack_pop() calls, you will (probably) destroy the path stack + instance with an incorrect value of cwd. +*/ + +void path_stack_free( path_stack_type * path_stack ) { + stringlist_free( path_stack->stack ); + stringlist_free( path_stack->storage ); +} + + +/** + This will push a path on to the stack. The function will start by + chdir() to the input path. If the chdir() call fails the function + will return false, and the stack will be unmodified; if the chdir() + succeeds the input @path will be pushed onto the stack. + + If path is NULL that is interpreted as cwd. +*/ + +bool path_stack_push( path_stack_type * path_stack , const char * path ) { + if (path != NULL) + if (chdir( path ) != 0) + return false; + + path_stack_push_cwd( path_stack ); + return true; +} + + +void path_stack_push_cwd( path_stack_type * path_stack ) { + char * cwd = util_alloc_cwd(); + stringlist_append_owned_ref( path_stack->storage , cwd); + stringlist_append_ref( path_stack->stack , cwd ); +} + +const char * path_stack_pop( path_stack_type * path_stack ) { + char * path = stringlist_pop( path_stack->stack ); + if (chdir( path ) == 0) + return path; + else { + // The directory has become inaccesible ... + util_abort("%s: could not pop back to directory:%s Error:%s\n", __func__ , path , strerror( errno )); + return NULL; + } +} + + +int path_stack_size( const path_stack_type * path_stack ) { + return stringlist_get_size( path_stack->stack ); +} + + +const char * path_stack_peek( const path_stack_type * path_stack ) { + return stringlist_get_last( path_stack->stack ); +} + diff --git a/ThirdParty/Ert/devel/libert_util/src/rng.c b/ThirdParty/Ert/devel/libert_util/src/rng.c index 0a7a74b756..1c5e733e98 100644 --- a/ThirdParty/Ert/devel/libert_util/src/rng.c +++ b/ThirdParty/Ert/devel/libert_util/src/rng.c @@ -42,7 +42,8 @@ struct rng_struct { rng_forward_ftype * forward; /* Brings the rng forward - returning a random unsigned int value. This is the fundamental source of random numbers, and all other random numbers are derived from this through scaling/shifting/type conversion/... */ - rng_set_state_ftype * set_state; /* Takes a char * buffer as input and sets the state of the rng. */ + rng_set_state_ftype * set_state; /* Takes a char * buffer as input and sets the state of the rng; should set the rng into a default state if arg == NULL. */ + rng_get_state_ftype * get_state; rng_alloc_ftype * alloc_state; /* Creates a new instance of this rng. */ rng_free_ftype * free_state; rng_fscanf_ftype * fscanf_state; /* Loads the state from a formatted file with (integer representation of) bytes. */ @@ -64,6 +65,7 @@ rng_type * rng_alloc__(rng_alloc_ftype * alloc_state, rng_free_ftype * free_state , rng_forward_ftype * forward , rng_set_state_ftype * set_state , + rng_get_state_ftype * get_state , rng_fscanf_ftype * fscanf_state , rng_fprintf_ftype * fprintf_state , rng_alg_type type , @@ -76,14 +78,15 @@ rng_type * rng_alloc__(rng_alloc_ftype * alloc_state, rng->free_state = free_state; rng->forward = forward; rng->set_state = set_state; + rng->get_state = get_state; rng->fscanf_state = fscanf_state; rng->fprintf_state = fprintf_state; rng->state_size = state_size; - rng->max_value = max_value; - rng->inv_max = 1.0 / max_value; - rng->type = type; - rng->state = NULL; + rng->max_value = max_value; + rng->inv_max = 1.0 / max_value; + rng->type = type; + rng->state = NULL; rng->state = rng->alloc_state( ); @@ -102,28 +105,32 @@ rng_type * rng_alloc__(rng_alloc_ftype * alloc_state, void rng_init( rng_type * rng , rng_init_mode init_mode ) { - char * seed_buffer = (char *) util_calloc( rng->state_size , sizeof * seed_buffer ); - - switch (init_mode) { - case(INIT_CLOCK): - { - int i; - for (i=0; i < rng->state_size; i++) - seed_buffer[i] = ( char ) util_clock_seed(); + if (init_mode == INIT_DEFAULT) + rng_set_state( rng , NULL ); + else { + char * seed_buffer = (char *) util_calloc( rng->state_size , sizeof * seed_buffer ); + + switch (init_mode) { + case(INIT_CLOCK): + { + int i; + for (i=0; i < rng->state_size; i++) + seed_buffer[i] = ( char ) util_clock_seed(); + } + break; + case(INIT_DEV_RANDOM): + util_fread_dev_random( rng->state_size * sizeof * seed_buffer , seed_buffer ); + break; + case(INIT_DEV_URANDOM): + util_fread_dev_urandom( rng->state_size * sizeof * seed_buffer , seed_buffer ); + break; + default: + util_abort("%s: unrecognized init_code:%d \n",__func__ , init_mode); } - break; - case(INIT_DEV_RANDOM): - util_fread_dev_random( rng->state_size * sizeof * seed_buffer , seed_buffer ); - break; - case(INIT_DEV_URANDOM): - util_fread_dev_urandom( rng->state_size * sizeof * seed_buffer , seed_buffer ); - break; - default: - util_abort("%s: unrecognized init_code:%d \n",__func__ , init_mode); + + rng_set_state( rng , seed_buffer ); + free( seed_buffer ); } - - rng->set_state( rng->state , seed_buffer ); - free( seed_buffer ); } @@ -151,6 +158,8 @@ void rng_rng_init( rng_type * rng , rng_type * seed_src) { + + rng_type * rng_alloc( rng_alg_type type , rng_init_mode init_mode ) { rng_type * rng; switch (type) { @@ -159,6 +168,7 @@ rng_type * rng_alloc( rng_alg_type type , rng_init_mode init_mode ) { mzran_free , mzran_forward , mzran_set_state , + mzran_get_state , mzran_fscanf_state , mzran_fprintf_state , type , @@ -170,13 +180,23 @@ rng_type * rng_alloc( rng_alg_type type , rng_init_mode init_mode ) { rng = NULL; } - if (init_mode != INIT_DEFAULT) - rng_init( rng , init_mode ); - + rng_init( rng , init_mode ); return rng; } +int rng_state_size( const rng_type * rng ) { + return rng->state_size; +} + + +void rng_get_state(const rng_type * rng, char * state) { + rng->get_state( rng->state , state ); +} + +void rng_set_state( rng_type * rng , const char * state) { + rng->set_state( rng->state , state ); +} void rng_free( rng_type * rng) { rng->free_state( rng->state ); diff --git a/ThirdParty/Ert/devel/libert_util/src/string_util.c b/ThirdParty/Ert/devel/libert_util/src/string_util.c new file mode 100644 index 0000000000..28360c2ebc --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/src/string_util.c @@ -0,0 +1,208 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'string_util.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 + +#include +#include +#include +#include +#include + + +/*****************************************************************/ + +/* + This functions parses an input string 'range_string' of the type: + + "0,1,8, 10 - 20 , 15,17-21" + + I.e. integers separated by "," and "-". The integer values are + parsed out. +*/ + +//#include +//#include +//static int * util_sscanf_active_range__NEW(const char * range_string , int max_value , bool * active , int * _list_length) { +// tokenizer_type * tokenizer = tokenizer_alloc( NULL , /* No ordinary split characters. */ +// NULL , /* No quoters. */ +// ",-" , /* Special split on ',' and '-' */ +// " \t" , /* Removing ' ' and '\t' */ +// NULL , /* No comment */ +// NULL ); +// stringlist_type * tokens; +// tokens = tokenize_buffer( tokenizer , range_string , true); +// +// stringlist_free( tokens ); +// tokenizer_free( tokenizer ); +//} + + + +static bool valid_characters( const char * range_string ) { + bool valid = false; + if (range_string) { + int offset = 0; + valid = true; + while (true) { + char c = range_string[offset]; + if (isspace(c) || isdigit(c) || c == ',' || c == '-') + offset++; + else + valid = false; + if (offset == strlen( range_string ) || !valid) + break; + } + } + return valid; +} + + + +static int_vector_type * string_util_sscanf_alloc_active_list(const char * range_string ) { + int_vector_type *active_list = NULL; + bool valid = valid_characters( range_string ); + + if (valid) + { + parser_type * parser = parser_alloc( "," , /* No ordinary split characters. */ + NULL , /* No quoters. */ + NULL , /* No special split */ + " \t" , /* Removing ' ' and '\t' */ + NULL , /* No comment */ + NULL ); + stringlist_type * tokens; + int item; + active_list = int_vector_alloc(0,0); + tokens = parser_tokenize_buffer( parser , range_string , true); + + for (item = 0; item < stringlist_get_size( tokens ); item++) { + const char * string_item = stringlist_iget( tokens , item ); + char * pos_ptr = string_item; + int value1 , value2; + + value1 = strtol( string_item , &pos_ptr , 10); + if (*pos_ptr == '\0') + // The pos_ptr points to the end of the string, i.e. this was a single digit. + value2 = value1; + else { + // OK - this is a range; skip spaces and the range dash '-' + while (isspace(*pos_ptr) || *pos_ptr == '-') + pos_ptr++; + util_sscanf_int( pos_ptr , &value2); + } + + { + int value; + for (value = value1; value <= value2; value++) + int_vector_append( active_list , value ); + } + } + + + stringlist_free( tokens ); + parser_free( parser ); + } + + return active_list; +} + + + + +/*****************************************************************/ + +static bool_vector_type * alloc_mask( const int_vector_type * active_list ) { + bool_vector_type * mask = bool_vector_alloc( 0 , false ); + int i; + for (i=0; i < int_vector_size( active_list ); i++) + bool_vector_iset( mask , int_vector_iget( active_list , i) , true ); + + return mask; +} + + + +bool string_util_update_active_list( const char * range_string , int_vector_type * active_list ) { + int_vector_sort( active_list ); + { + bool_vector_type * mask = alloc_mask( active_list ); + bool valid = false; + + if (string_util_update_active_mask( range_string , mask )) { + int_vector_reset( active_list ); + { + int i; + for (i=0; i < bool_vector_size(mask); i++) { + bool active = bool_vector_iget( mask , i ); + if (active) + int_vector_append( active_list , i ); + } + } + valid = true; + } + bool_vector_free( mask ); + return valid; + } +} + + +bool string_util_init_active_list( const char * range_string , int_vector_type * active_list ) { + int_vector_reset( active_list ); + return string_util_update_active_list( range_string , active_list ); +} + + +int_vector_type * string_util_alloc_active_list( const char * range_string ) { + int_vector_type * active_list = int_vector_alloc( 0 , 0 ); + string_util_init_active_list( range_string , active_list ); + return active_list; +} + +/*****************************************************************/ + +/* + This is the only function which actually invokes the low level + string parsing in util_sscanf_alloc_active_list(). +*/ + +bool string_util_update_active_mask( const char * range_string , bool_vector_type * active_mask) { + int i; + int_vector_type * sscanf_active = string_util_sscanf_alloc_active_list( range_string ); + if (sscanf_active) { + for (i=0; i < int_vector_size( sscanf_active ); i++) + bool_vector_iset( active_mask , int_vector_iget(sscanf_active , i) , true ); + + int_vector_free( sscanf_active ); + return true; + } else + return false; +} + + +bool string_util_init_active_mask( const char * range_string , bool_vector_type * active_mask ) { + bool_vector_reset( active_mask ); + return string_util_update_active_mask( range_string , active_mask ); +} + + +bool_vector_type * string_util_alloc_active_mask( const char * range_string ) { + bool_vector_type * mask = bool_vector_alloc(0 , false ); + string_util_init_active_mask( range_string , mask ); + return mask; +} diff --git a/ThirdParty/Ert/devel/libert_util/src/stringlist.c b/ThirdParty/Ert/devel/libert_util/src/stringlist.c index 83e1fedc5a..0ce5e15880 100644 --- a/ThirdParty/Ert/devel/libert_util/src/stringlist.c +++ b/ThirdParty/Ert/devel/libert_util/src/stringlist.c @@ -56,15 +56,16 @@ struct stringlist_struct { static void stringlist_fprintf__(const stringlist_type * stringlist, const char * sep , FILE * stream) { - int i; int length = vector_get_size( stringlist->strings ); - - for (i=0; i < length - 1; i++) { - const char * s = stringlist_iget(stringlist , i); - fprintf(stream , "%s%s", s , sep); + if (length > 0) { + int i; + for (i=0; i < length - 1; i++) { + const char * s = stringlist_iget(stringlist , i); + fprintf(stream , "%s%s", s , sep); + } + + fprintf(stream , "%s", stringlist_iget( stringlist , length - 1 )); } - - fprintf(stream , "%s", stringlist_iget( stringlist , length - 1 )); } @@ -330,10 +331,33 @@ void stringlist_idel(stringlist_type * stringlist , int index) { } +char * stringlist_pop( stringlist_type * stringlist) { + return vector_pop( stringlist->strings ); +} + + const char * stringlist_iget(const stringlist_type * stringlist , int index) { return vector_iget(stringlist->strings ,index); } +int stringlist_iget_as_int( const stringlist_type * stringlist , int index , bool * valid) { + const char * string_value = stringlist_iget( stringlist , index ); + int value = -1; + + if (valid != NULL) + *valid = false; + + if (util_sscanf_int(string_value , &value)) + if (valid != NULL) + *valid = true; + + return value; +} + +const char * stringlist_get_last( const stringlist_type * stringlist ) { + return vector_get_last( stringlist->strings ); +} + bool stringlist_iequal( const stringlist_type * stringlist , int index, const char * s ) { return util_string_equal( stringlist_iget( stringlist , index ) , s); @@ -646,6 +670,11 @@ void stringlist_python_sort( stringlist_type * s , int cmp_flag) { } +void stringlist_reverse( stringlist_type * s ) { + vector_inplace_reverse( s->strings ); +} + + /*****************************************************************/ /* diff --git a/ThirdParty/Ert/devel/libert_util/src/subst_func.c b/ThirdParty/Ert/devel/libert_util/src/subst_func.c index d90b3882e4..eebdc69836 100644 --- a/ThirdParty/Ert/devel/libert_util/src/subst_func.c +++ b/ThirdParty/Ert/devel/libert_util/src/subst_func.c @@ -61,7 +61,7 @@ char * subst_func_eval( const subst_func_type * subst_func , const stringlist_ty util_abort("%s: Fatal error - aborting \n",__func__); } } - + printf("Running:%s \n",subst_func->name); return subst_func->func( args , subst_func->arg ); } diff --git a/ThirdParty/Ert/devel/libert_util/src/subst_list.c b/ThirdParty/Ert/devel/libert_util/src/subst_list.c index be9c2bced5..577f772968 100644 --- a/ThirdParty/Ert/devel/libert_util/src/subst_list.c +++ b/ThirdParty/Ert/devel/libert_util/src/subst_list.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -82,6 +83,7 @@ struct subst_list_struct { vector_type * string_data; /* The string substitutions we should do. */ vector_type * func_data; /* The functions we support. */ const subst_func_pool_type * func_pool; /* NOT owned by the subst_list instance - can be NULL */ + hash_type * map; }; @@ -207,7 +209,7 @@ static subst_list_string_type * subst_list_get_string_node(const subst_list_type subst_list_string_type * node = NULL; int index = 0; - /* Linear search ... */ + /* Linear search ... */ /*Should use map*/ while ((index < vector_get_size(subst_list->string_data)) && (node == NULL)) { subst_list_string_type * inode = vector_iget( subst_list->string_data , index); @@ -224,10 +226,12 @@ static subst_list_string_type * subst_list_get_string_node(const subst_list_type static subst_list_string_type * subst_list_insert_new_node(subst_list_type * subst_list , const char * key , bool append) { subst_list_string_type * new_node = subst_list_string_alloc(key); + if (append) vector_append_owned_ref( subst_list->string_data , new_node , subst_list_string_free__ ); else vector_insert_owned_ref( subst_list->string_data , 0 , new_node , subst_list_string_free__ ); + return new_node; } @@ -274,6 +278,7 @@ subst_list_type * subst_list_alloc(const void * input_arg) { UTIL_TYPE_ID_INIT( subst_list , SUBST_LIST_TYPE_ID); subst_list->parent = NULL; subst_list->func_pool = NULL; + subst_list->map = hash_alloc(); subst_list->string_data = vector_alloc_new(); subst_list->func_data = vector_alloc_new(); @@ -387,6 +392,7 @@ void subst_list_clear( subst_list_type * subst_list ) { void subst_list_free(subst_list_type * subst_list) { vector_free( subst_list->string_data ); vector_free( subst_list->func_data ); + hash_free( subst_list->map ); free(subst_list); } @@ -417,18 +423,22 @@ void subst_list_free(subst_list_type * subst_list) { subst_list. This is the lowest level function, which does *NOT* consider the parent pointer. */ -static void subst_list_replace_strings__(const subst_list_type * subst_list , buffer_type * buffer) { +static bool subst_list_replace_strings__(const subst_list_type * subst_list , buffer_type * buffer) { int index; + bool global_match = false; for (index = 0; index < vector_get_size( subst_list->string_data ); index++) { const subst_list_string_type * node = vector_iget_const( subst_list->string_data , index ); if (node->value != NULL) { - bool match; + bool match; buffer_rewind( buffer ); do { match = buffer_search_replace( buffer , node->key , node->value); + if (match) + global_match = true; } while (match); } } + return global_match; } @@ -464,63 +474,63 @@ static void subst_list_replace_strings__(const subst_list_type * subst_list , bu */ -static void subst_list_eval_funcs____(const subst_list_type * subst_list , const parser_type * parser , buffer_type * buffer) { - { - int index; - for (index = 0; index < vector_get_size( subst_list->func_data); index++) { - const subst_list_func_type * subst_func = vector_iget_const( subst_list->func_data , index ); - const char * func_name = subst_func->name; +static bool subst_list_eval_funcs____(const subst_list_type * subst_list , const parser_type * parser , buffer_type * buffer) { + bool global_match = false; + int index; + for (index = 0; index < vector_get_size( subst_list->func_data); index++) { + const subst_list_func_type * subst_func = vector_iget_const( subst_list->func_data , index ); + const char * func_name = subst_func->name; + + bool match; + buffer_rewind( buffer ); + do { + size_t match_pos; + match = buffer_strstr( buffer , func_name ); + match_pos = buffer_get_offset( buffer ); - bool match; - buffer_rewind( buffer ); - do { - size_t match_pos; - match = buffer_strstr( buffer , func_name ); - match_pos = buffer_get_offset( buffer ); + if (match) { + bool update = false; + char * arg_start = buffer_get_data( buffer ); + arg_start += buffer_get_offset( buffer ) + strlen( func_name ); - if (match) { - bool update = false; - char * arg_start = buffer_get_data( buffer ); - arg_start += buffer_get_offset( buffer ) + strlen( func_name ); - - if (arg_start[0] == '(') { /* We require that an opening paren follows immediately behind the function name. */ - char * arg_end = strchr( arg_start , ')'); - if (arg_end != NULL) { - /* OK - we found an enclosing () pair. */ - char * arg_content = util_alloc_substring_copy( arg_start, 1 , arg_end - arg_start - 1); - stringlist_type * arg_list = parser_tokenize_buffer( parser , arg_content , true); - char * func_eval = subst_list_func_eval( subst_func , arg_list ); - int old_len = strlen(func_name) + strlen( arg_content) + 2; - - if (func_eval != NULL) { - buffer_memshift( buffer , match_pos + old_len , strlen( func_eval ) - old_len); - buffer_fwrite( buffer , func_eval , strlen( func_eval ) , sizeof * func_eval ); - free( func_eval ); - update = true; - } - - free( arg_content ); - stringlist_free( arg_list ); - } + if (arg_start[0] == '(') { /* We require that an opening paren follows immediately behind the function name. */ + char * arg_end = strchr( arg_start , ')'); + if (arg_end != NULL) { + /* OK - we found an enclosing () pair. */ + char * arg_content = util_alloc_substring_copy( arg_start, 1 , arg_end - arg_start - 1); + stringlist_type * arg_list = parser_tokenize_buffer( parser , arg_content , true); + char * func_eval = subst_list_func_eval( subst_func , arg_list ); + int old_len = strlen(func_name) + strlen( arg_content) + 2; + + if (func_eval != NULL) { + buffer_memshift( buffer , match_pos + old_len , strlen( func_eval ) - old_len); + buffer_fwrite( buffer , func_eval , strlen( func_eval ) , sizeof * func_eval ); + free( func_eval ); + update = true; + global_match = true; + } + + free( arg_content ); + stringlist_free( arg_list ); } - - if (!update) - buffer_fseek( buffer , match_pos + strlen( func_name ) , SEEK_SET); - } - } while (match); - } + } + if (!update) + buffer_fseek( buffer , match_pos + strlen( func_name ) , SEEK_SET); + } + } while (match); } if (subst_list->parent != NULL) - subst_list_eval_funcs____( subst_list->parent , parser , buffer ); + global_match = (subst_list_eval_funcs____( subst_list->parent , parser , buffer ) || global_match); + return global_match; } -static void subst_list_eval_funcs__(const subst_list_type * subst_list , buffer_type * buffer) { +static bool subst_list_eval_funcs__(const subst_list_type * subst_list , buffer_type * buffer) { parser_type * parser = parser_alloc( "," , "\"\'" , NULL , " \t" , NULL , NULL ); - - subst_list_eval_funcs____( subst_list , parser , buffer ); + bool match = subst_list_eval_funcs____( subst_list , parser , buffer ); parser_free( parser ); + return match; } @@ -578,12 +588,14 @@ static void subst_list_eval_funcs__(const subst_list_type * subst_list , buffer_ subst_list_replace_strings__() which is not recursive. */ -static void subst_list_replace_strings( const subst_list_type * subst_list , buffer_type * buffer ) { +static bool subst_list_replace_strings( const subst_list_type * subst_list , buffer_type * buffer ) { + bool match = false; if (subst_list->parent != NULL) - subst_list_replace_strings( subst_list->parent , buffer ); + match = subst_list_replace_strings( subst_list->parent , buffer ); /* The actual string replace */ - subst_list_replace_strings__( subst_list , buffer ); + match = (subst_list_replace_strings__( subst_list , buffer ) || match); + return match; } @@ -597,9 +609,10 @@ static void subst_list_replace_strings( const subst_list_type * subst_list , buf */ -void subst_list_update_buffer( const subst_list_type * subst_list , buffer_type * buffer ) { - subst_list_replace_strings( subst_list , buffer ); - subst_list_eval_funcs__( subst_list , buffer ); +bool subst_list_update_buffer( const subst_list_type * subst_list , buffer_type * buffer ) { + bool match1 = subst_list_replace_strings( subst_list , buffer ); + bool match2 = subst_list_eval_funcs__( subst_list , buffer ); + return (match1 || match2); // Funny construction to ensure to avoid fault short circuit. } @@ -616,7 +629,8 @@ void subst_list_update_buffer( const subst_list_type * subst_list , buffer_type */ -void subst_list_filter_file(const subst_list_type * subst_list , const char * src_file , const char * target_file) { +bool subst_list_filter_file(const subst_list_type * subst_list , const char * src_file , const char * target_file) { + bool match; char * backup_file = NULL; buffer_type * buffer = buffer_fread_alloc( src_file ); buffer_fseek( buffer , 0 , SEEK_END ); /* Ensure that the buffer is a \0 terminated string. */ @@ -630,6 +644,7 @@ void subst_list_filter_file(const subst_list_type * subst_list , const char * sr free(backup_prefix); } + /* Writing backup file */ if (backup_file != NULL) { FILE * stream = util_fopen(backup_file , "w"); @@ -639,7 +654,7 @@ void subst_list_filter_file(const subst_list_type * subst_list , const char * sr /* Doing the actual update */ - subst_list_update_buffer(subst_list , buffer); + match = subst_list_update_buffer(subst_list , buffer); /* Writing updated file */ @@ -655,13 +670,15 @@ void subst_list_filter_file(const subst_list_type * subst_list , const char * sr free( backup_file ); } free(buffer); + return match; } /** This function does search-replace on a file inplace. */ -void subst_list_update_file(const subst_list_type * subst_list , const char * file) { - subst_list_filter_file( subst_list , file , file ); + +bool subst_list_update_file(const subst_list_type * subst_list , const char * file) { + return subst_list_filter_file( subst_list , file , file ); } @@ -669,11 +686,13 @@ void subst_list_update_file(const subst_list_type * subst_list , const char * fi /** This function does search-replace on string instance inplace. */ -void subst_list_update_string(const subst_list_type * subst_list , char ** string) { +bool subst_list_update_string(const subst_list_type * subst_list , char ** string) { buffer_type * buffer = buffer_alloc_private_wrapper( *string , strlen( *string ) + 1); - subst_list_update_buffer(subst_list , buffer); + bool match = subst_list_update_buffer(subst_list , buffer); *string = buffer_get_data( buffer ); buffer_free_container( buffer ); + + return match; } @@ -806,6 +825,7 @@ const char * subst_list_iget_doc_string( const subst_list_type * subst_list , in } + void subst_list_fprintf(const subst_list_type * subst_list , FILE * stream) { int index; for (index=0; index < vector_get_size( subst_list->string_data ); index++) { diff --git a/ThirdParty/Ert/devel/libert_util/src/test_util.c b/ThirdParty/Ert/devel/libert_util/src/test_util.c index 89c442a8dd..ed8effe35a 100644 --- a/ThirdParty/Ert/devel/libert_util/src/test_util.c +++ b/ThirdParty/Ert/devel/libert_util/src/test_util.c @@ -76,6 +76,18 @@ void test_assert_int_not_equal__( int i1 , int i2 , const char * file , int line } +void test_assert_uint_equal__( unsigned int i1 , unsigned int i2 , const char * file , int line) { + if (i1 != i2) + test_error_exit( "%s:%d => Integers are different i1:[%d] i2:[%d]\n" , file , line , i1 , i2 ); +} + + +void test_assert_uint_not_equal__( unsigned int i1 , unsigned int i2 , const char * file , int line) { + if (i1 == i2) + test_error_exit( "%s:%d => Integers are equal i1:[%d] i2:[%d]\n" , file , line , i1 , i2 ); +} + + void test_assert_bool_equal__( bool b1 , bool b2 , const char * file , int line) { if (b1 != b2) test_error_exit( "%s:%d => Booleans are different b1:[%d] b2:[%d]\n" , file , line , b1 , b2 ); @@ -87,20 +99,22 @@ void test_assert_bool_equal__( bool b1 , bool b2 , const char * file , int line) void test_assert_time_t_equal__( time_t t1 , time_t t2 , const char * file , int line) { if (t1 != t2) - test_error_exit("%s:%d => time_t values are different t1:%d t2:[%d]" , file , line , t1 , t2); + test_error_exit("%s:%d => time_t values are different t1:%d t2:[%d]\n" , file , line , t1 , t2); } void test_assert_time_t_not_equal__( time_t t1 , time_t t2 , const char * file , int line) { if (t1 == t2) - test_error_exit("%s:%d => time_t values are different t1:%d t2:[%d]" , file , line , t1 , t2); + test_error_exit("%s:%d => time_t values are different t1:%d t2:[%d]\n" , file , line , t1 , t2); } + + /*****************************************************************/ void test_assert_true__( bool value, const char * file , int line) { if (!value) - test_error_exit("%s:%d => assert( true ) failed" , file , line); + test_error_exit("%s:%d => assert( true ) failed\n" , file , line); } @@ -119,6 +133,13 @@ void test_assert_ptr_equal__( const void * p1 , const void * p2 , const char * f } +void test_assert_ptr_not_equal__( const void * p1 , const void * p2 , const char * file , int line) { + bool equal = (p1 == p2); + if (equal) + test_error_exit( "%s:%d => Pointers are different p1:[%p] p2:[%p]\n" , file , line , p1 , p2 ); +} + + void test_assert_NULL__( const void * p , const char * file , int line) { if (p != NULL) test_error_exit( "%s:%d => Pointer is != NULL \n" , file , line , p); @@ -132,8 +153,16 @@ void test_assert_not_NULL__( const void * p , const char * file , int line) { void test_assert_mem_equal__( const void * p1 , const void * p2 , size_t byte_size , const char * file , int line) { - if (memcmp(p1 ,p2 , byte_size) != 0) - test_error_exit( "%s:%d => Memory regions have different content \n" , file , line); + if (memcmp(p1 ,p2 , byte_size) != 0) { + const char * char_ptr1 = (const char *) p1; + const char * char_ptr2 = (const char *) p2; + size_t offset = 0; + + while( char_ptr1[offset] == char_ptr2[offset]) + offset++; + + test_error_exit( "%s:%d => Memory regions have different content. First difference at offset:%ld\n" , file , line , offset); + } } @@ -141,3 +170,44 @@ void test_assert_mem_not_equal__( const void * p1 , const void * p2 , size_t byt if (memcmp(p1 ,p2 , byte_size) == 0) test_error_exit( "%s:%d => Memory regions have the same content \n" , file , line); } + + + +void test_assert_double_equal__( double d1 , double d2, const char * file , int line) { + if (!util_double_approx_equal(d1 , d2)) + test_error_exit( "%s:%d => double values:%g %g are not sufficiently similar\n" , file , line , d1 , d2); +} + + +void test_assert_double_not_equal__( double d1 , double d2, const char * file , int line) { + if (util_double_approx_equal(d1 , d2)) + test_error_exit( "%s:%d => double values:%15.12g %15.12g are equal.\n" , file , line , d1 , d2); +} + + + +/*****************************************************************/ + +#ifdef HAVE_UTIL_ABORT +#include + +void test_util_addr2line() { + const char * file = __FILE__; + const char * func = __func__; + int line; + const int max_bt = 50; + void *bt_addr[max_bt]; + int size; + char * func_name , * file_name; + int line_nr; + + line = __LINE__ + 2; + size = backtrace(bt_addr , max_bt); + test_assert_int_equal( size , 4 ); + test_assert_true( util_addr2line_lookup( bt_addr[0] , &func_name , &file_name , &line_nr)); + test_assert_string_equal( func_name , func ); + test_assert_int_equal( line , line_nr ); + test_assert_string_equal( file_name , file ); +} + +#endif diff --git a/ThirdParty/Ert/devel/libert_util/src/time_interval.c b/ThirdParty/Ert/devel/libert_util/src/time_interval.c new file mode 100644 index 0000000000..afd87fec6e --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/src/time_interval.c @@ -0,0 +1,174 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'time_interval.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include + +#define TIME_INTERVAL_EMPTY (time_t) -1 +#define TIME_T_MAX (time_t) ((1UL << (( sizeof(time_t) << 3) -1 )) -1 ) +#define TIME_T_MIN -TIME_T_MAX + + +struct time_interval_struct { + bool valid; + time_t start_time; + time_t end_time; +}; + + +/* + If you set something invalid - the whole interval is destroyed. +*/ + +bool time_interval_update( time_interval_type * ti , time_t start_time , time_t end_time) { + ti->start_time = start_time; + ti->end_time = end_time; + + ti->valid = (start_time <= end_time) ? true : false; + return ti->valid; +} + + +bool time_interval_update_start( time_interval_type * ti , time_t start_time ) { + return time_interval_update( ti , start_time , ti->end_time ); +} + + +bool time_interval_update_end( time_interval_type * ti , time_t end_time ) { + return time_interval_update( ti , ti->start_time , end_time ); +} + + +void time_interval_reopen( time_interval_type * time_interval) { + time_interval_update( time_interval , TIME_T_MIN , TIME_T_MAX); +} + + +time_interval_type * time_interval_alloc( time_t start_time , time_t end_time ) { + time_interval_type * ti = util_malloc( sizeof * ti ); + time_interval_update( ti , start_time , end_time ); + return ti; +} + + +time_interval_type * time_interval_alloc_open( ) { + return time_interval_alloc( TIME_T_MIN , TIME_T_MAX ); +} + +time_interval_type * time_interval_alloc_copy( const time_interval_type * src) { + return time_interval_alloc( src->start_time , src->end_time ); +} + + +void time_interval_free( time_interval_type * ti ) { + free( ti ); +} + + +bool time_interval_is_empty( time_interval_type * ti ) { + return (ti->end_time <= ti->start_time); +} + + +bool time_interval_contains( const time_interval_type * ti , time_t t) { + if (!ti->valid) + return false; + else { + if (t < ti->start_time) + return false; + else if (t >= ti->end_time) + return false; + else + return true; + } +} + + + +bool time_interval_has_overlap( const time_interval_type * t1 , const time_interval_type * t2) { + if (t1->valid && t2->valid) { + if (time_interval_contains(t1 , t2->start_time)) + return true; + + if (time_interval_contains(t1 , t2->end_time)) + return true; + + return false; + } else + return false; +} + +bool time_interval_is_adjacent( const time_interval_type * t1 , const time_interval_type * t2) { + if ((t1->end_time == t2->start_time) || (t1->start_time == t2->end_time)) + return true; + else + return false; +} + + +time_t time_interval_get_start( const time_interval_type * ti) { + return ti->start_time; +} + + + +time_t time_interval_get_end( const time_interval_type * ti) { + return ti->end_time; +} + + +bool time_interval_extend( time_interval_type * t1 , const time_interval_type * t2) { + if (time_interval_has_overlap(t1,t2) || time_interval_is_adjacent( t1 , t2)) { + time_t start_time = util_time_t_min( t1->start_time , t2->start_time ); + time_t end_time = util_time_t_max( t1->end_time , t2->end_time ); + + return time_interval_update(t1 , start_time , end_time); + } else + return false; +} + + +bool time_interval_intersect( time_interval_type * t1 , const time_interval_type * t2) { + if (time_interval_has_overlap(t1,t2) || time_interval_is_adjacent( t1 , t2)) { + time_t start_time = util_time_t_max( t1->start_time , t2->start_time ); + time_t end_time = util_time_t_min( t1->end_time , t2->end_time ); + + return time_interval_update(t1 , start_time , end_time); + } else + return false; +} + + +bool time_interval_equal( const time_interval_type * t1 , const time_interval_type * t2) { + if ((t1->start_time == t2->start_time) && (t1->end_time == t2->end_time)) + return true; + else + return false; +} + + +bool time_interval_arg_after( const time_interval_type * ti , time_t arg) { + return util_after( arg , ti->end_time ); +} + + +bool time_interval_arg_before( const time_interval_type * ti , time_t arg) { + return util_before( arg , ti->start_time ); +} diff --git a/ThirdParty/Ert/devel/libert_util/src/util.c b/ThirdParty/Ert/devel/libert_util/src/util.c index 1469eeb957..304a656b2d 100644 --- a/ThirdParty/Ert/devel/libert_util/src/util.c +++ b/ThirdParty/Ert/devel/libert_util/src/util.c @@ -34,6 +34,20 @@ #include #include + +#ifdef HAVE_FORK +#ifdef WITH_PTHREAD +#ifdef HAVE_EXECINFO +#define HAVE_UTIL_ABORT +#endif +#endif +#endif + +#ifdef HAVE_UTIL_ABORT +#define __USE_GNU // Must be defined to get access to the dladdr() function; Man page says the symbol should be: _GNU_SOURCE but that does not seem to work? +#define _GNU_SOURCE // Must be defined _before_ #include to get the symbol 'program_invocation_name'. +#include +#endif #include #include @@ -78,6 +92,7 @@ #include #endif + #include #if UINTPTR_MAX == 0xFFFFFFFF #define ARCH32 @@ -254,6 +269,10 @@ void util_endian_flip_vector_old(void *data, int element_size , int elements) { } } +#ifndef S_ISDIR +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif /*****************************************************************/ @@ -330,8 +349,20 @@ double util_kahan_sum(const double *data, size_t N) { } - - +bool util_double_approx_equal( double d1 , double d2) { + if (d1 == d2) + return true; + else { + double epsilon = 1e-6; + double diff = fabs(d1 - d2); + double sum = fabs(d1) + fabs(d2); + + if ((diff / sum) < epsilon) + return true; + else + return false; + } +} char * util_alloc_substring_copy(const char *src , int offset , int N) { @@ -720,6 +751,34 @@ char * util_alloc_cwd(void) { +bool util_is_cwd( const char * path ) { + bool is_cwd = false; + struct stat path_stat; + + if (stat(path , &path_stat) == 0) { + if (S_ISDIR( path_stat.st_mode )) { + char * cwd = util_alloc_cwd(); +#ifdef ERT_WINDOWS + /* + The windows stat structure has the inode element, but it is + not set. Actually - this is a property of the filesystem, and + not the operating system - the whole check is probably broken? + */ + util_abort("%s: Internal error - function not properly implmented on Windows \n",__func__); +#else + struct stat cwd_stat; + stat(cwd , &cwd_stat); + if (cwd_stat.st_ino == path_stat.st_ino) + is_cwd = true; +#endif + free( cwd ); + } + } + return is_cwd; +} + + + /* Homemade realpath() for not existing path or platforms without realpath(). @@ -739,6 +798,81 @@ static char * util_alloc_cwd_abs_path( const char * path ) { } + +/** + Manual realpath() implementation to be used on platforms without + realpath() support. Will remove /../, ./ and extra //. Will not + handle symlinks. +*/ + + +#define BACKREF ".." +#define CURRENT "." + +char * util_alloc_realpath__(const char * input_path) { + char * abs_path = util_alloc_cwd_abs_path( input_path ); + char * real_path = util_malloc( strlen(abs_path) + 1 ); + real_path[0] = '\0'; + + { + bool * mask; + char ** path_list; + int path_len; + + util_path_split( abs_path , &path_len , &path_list ); + mask = util_malloc( path_len * sizeof * mask ); + { + int i; + for (i=0; i < path_len; i++) + mask[i] = true; + } + + { + int path_index = 1; // Path can not start with .. + int prev_index = 0; + while (true) { + if (path_index == path_len) + break; + + if (strcmp(path_list[path_index] , BACKREF ) == 0) { + mask[path_index] = false; + mask[prev_index] = false; + prev_index--; + path_index++; + } else if (strcmp( path_list[path_index] , CURRENT) == 0) { + mask[path_index] = false; + path_index++; + } else { + path_index++; + prev_index++; + while (!mask[prev_index]) + prev_index++; + } + } + + /* Build up the new string. */ + { + int i; + for (i=0; i < path_len; i++) { + if (mask[i]) { + strcat( real_path , UTIL_PATH_SEP_STRING ); + strcat( real_path , path_list[i]); + } + } + } + } + free(mask); + util_free_stringlist( path_list , path_len ); + } + + return real_path; +} + +#undef BACKREF +#undef CURRENT + + + /** The util_alloc_realpath() will fail hard if the @input_path does not exist. If the path might-not-exist you should use @@ -762,10 +896,13 @@ char * util_alloc_realpath(const char * input_path) { /* We do not have the realpath() implementation. Must first check if the entry exists; and if not we abort. If the entry indeed exists we call the util_alloc_cwd_abs_path() function: */ +#ifdef HAVE_SYMLINK + ERROR - What the fuck; have symlinks and not realpath()?! +#endif if (!util_entry_exists( input_path )) - util_abort("%s: input_path:%s does not exist - realpath() failed.\n",__func__ , input_path); + util_abort("%s: input_path:%s does not exist - failed.\n",__func__ , input_path); - return util_alloc_cwd_abs_path( input_path ); + return util_alloc_realpath__( input_path ); #endif } @@ -782,17 +919,103 @@ char * util_alloc_realpath(const char * input_path) { 2. Else cwd is prepended to the path. - In the manual realpath() neither "/../" nor symlinks are resolved. + In the manual realpath() neither "/../" nor symlinks are resolved. If path == NULL the function will return cwd(). */ char * util_alloc_abs_path( const char * path ) { - if (util_entry_exists( path )) - return util_alloc_realpath( path ); - else - return util_alloc_cwd_abs_path( path ); + if (path == NULL) + return util_alloc_cwd(); + else { + if (util_entry_exists( path )) + return util_alloc_realpath( path ); + else + return util_alloc_cwd_abs_path( path ); + } } + +/** + Both path arguments must be absolute paths; if not a copy of the + input path will be returned. Neither of the input arguments can + have "/../" elements - that will just fuck things up. + + root_path can be NULL - in which case cwd is used. +*/ + +char * util_alloc_rel_path( const char * __root_path , const char * path) { + char * root_path; + if (__root_path == NULL) + root_path = util_alloc_cwd(); + else + root_path = util_alloc_string_copy( __root_path ); + + if (util_is_abs_path(root_path) && util_is_abs_path(path)) { + const char * back_path = ".."; + char * rel_path = util_alloc_string_copy(""); // In case strcmp(root_path , path) == 0 the empty string "" will be returned + char ** root_path_list; + char ** path_list; + int root_path_length , path_length , back_length; + + /* 1. Split both input paths into list of path elements. */ + util_path_split( root_path, &root_path_length , &root_path_list ); + util_path_split( path , &path_length , &path_list ); + + { + /* 2: Determine the number of common leading path elements. */ + int common_length = 0; + while (true) { + if (strcmp(root_path_list[common_length] , path_list[common_length]) == 0) + common_length++; + else + break; + + if (common_length == util_int_min( root_path_length , path_length)) + break; + } + + /* 3: Start building up the relative path with leading ../ elements. */ + back_length = root_path_length - common_length; + if (back_length > 0) { + int i; + for (i=0; i < back_length; i++) { + rel_path = util_strcat_realloc( rel_path , back_path ); + rel_path = util_strcat_realloc( rel_path , UTIL_PATH_SEP_STRING ); + } + } + + /* 4: Add the remaining elements from the input path. */ + { + int i; + for (i=common_length; i < path_length; i++) { + rel_path = util_strcat_realloc( rel_path , path_list[i] ); + if (i != (path_length - 1)) + rel_path = util_strcat_realloc( rel_path , UTIL_PATH_SEP_STRING ); + } + } + } + + util_free_stringlist( root_path_list , root_path_length ); + util_free_stringlist( path_list , path_length ); + free( root_path ); + + if (strlen(rel_path) == 0) { + free(rel_path); + rel_path = NULL; + } return rel_path; + } else { + /* + One or both the input arguments do not correspond to an + absolute path; just return a copy of the input back. + */ + free( root_path ); + return util_alloc_string_copy( path ); + } +} + + + + /** This function will allocate a string copy of the env_index'th occurence of an embedded environment variable from the input @@ -1794,6 +2017,11 @@ double util_scanf_double(const char * prompt , int prompt_len) { } + + + + + /** The limits are inclusive. */ @@ -2207,13 +2435,7 @@ bool util_entry_exists( const char * entry ) { */ -#ifdef HAVE_ISREG -#endif -#ifndef S_ISDIR -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif @@ -2279,6 +2501,13 @@ bool util_entry_readable( const char * entry ) { } +bool util_file_readable( const char * file ) { + if (util_entry_readable( file ) && util_is_file( file )) + return true; + else + return false; +} + bool util_entry_writable( const char * entry ) { struct stat buffer; if (stat( entry , &buffer ) == 0) @@ -2510,6 +2739,17 @@ void util_ftruncate(FILE * stream , long size) { +/* + The windows stat structure has the inode element, but it is not + set. Actually - this is a property of the filesystem, and not the + operating system - this check is probably broken on two levels: + + 1. One should really check the filesystem involved - whether it + supports inodes. + + 2. The code below will compile on windows, but for a windows + filesystem it will yield rubbish. +*/ bool util_same_file(const char * file1 , const char * file2) { struct stat buffer1 , buffer2; @@ -2518,7 +2758,7 @@ bool util_same_file(const char * file1 , const char * file2) { stat1 = stat(file1, &buffer1); // In the case of symlinks the stat call will stat the target file and not the link. stat2 = stat(file2, &buffer2); - if ((stat1 == 1) && (stat1 == stat2)) { + if ((stat1 == 0) && (stat1 == stat2)) { if (buffer1.st_ino == buffer2.st_ino) return true; else @@ -2666,6 +2906,22 @@ bool util_file_older( const char * file , time_t t0) { } +bool util_before( time_t t , time_t limit) { + if (difftime(limit , t) > 0) + return true; + else + return false; +} + + +bool util_after( time_t t , time_t limit) { + if (difftime(limit , t) < 0) + return true; + else + return false; +} + + /** This function will return a pointer to the newest of the two @@ -2732,6 +2988,16 @@ void util_set_date_values(time_t t , int * mday , int * month , int * year) { } +bool util_is_first_day_in_month( time_t t) { + int mday; + __util_set_timevalues(t , NULL , NULL , NULL , &mday ,NULL, NULL); + if (mday == 1) + return true; + else + return false; +} + + /** If the parsing fails the time_t pointer is set to -1; */ @@ -2870,6 +3136,11 @@ double util_difftime_days(time_t start_time , time_t end_time) { } +double util_difftime_seconds( time_t start_time , time_t end_time) { + double dt = difftime(end_time , start_time); + return dt; +} + /* Observe that this routine does the following transform before calling mktime: @@ -2906,6 +3177,12 @@ time_t util_make_date(int mday , int month , int year) { } +time_t util_make_pure_date(time_t t) { + int day,month,year; + util_set_date_values( t , &day , &month , &year); + return util_make_date( day , month , year ); +} + @@ -3189,29 +3466,53 @@ void util_free_stringlist(char **list , int N) { int i; if (list != NULL) { for (i=0; i < N; i++) { - if (list[i] != NULL) - free(list[i]); + util_safe_free( list[i] ); } free(list); } } +/** + Will free a list of strings where the last element is NULL. Will + go completely canacas if the list is not NULL terminated. +*/ + +void util_free_NULL_terminated_stringlist(char ** string_list) { + if (string_list != NULL) { + int i = 0; + while (true) { + if (string_list[i] == NULL) + break; + else + free( string_list[i] ); + i++; + } + free( string_list ); + } +} + /** This function will reallocate the string s1 to become the sum of s1 - and s2. If s1 == NULL it will just return a copy of s2. + and s2. If s1 == NULL it will just return a copy of s2. + + Observe that due to the use realloc() the s1 input argument MUST BE + the return value from a malloc() call; this is not intuitive and + the function should be discontinued. */ char * util_strcat_realloc(char *s1 , const char * s2) { if (s1 == NULL) s1 = util_alloc_string_copy(s2); else { - int new_length = strlen(s1) + strlen(s2) + 1; - s1 = util_realloc( s1 , new_length ); - strcat(s1 , s2); + if (s2 != NULL) { + int new_length = strlen(s1) + strlen(s2) + 1; + s1 = util_realloc( s1 , new_length ); + strcat(s1 , s2); + } } return s1; } @@ -3352,47 +3653,46 @@ void util_split_string(const char *line , const char *sep_set, int *_tokens, cha util_binary_split_string("A:B:C:D , ":" , false , ) => "A:B:C" & "D" - o Characters in the split_set at the front (or back if - split_on_first == false) are discarded _before_ the actual - splitting process. + o Characters in the split_set at the front and back are discarded + _BEFORE_ the actual splitting process. - util_binary_split_string(":::A:B:C:D" , ":" , true , ) => "A" & "B:C:D" + util_binary_split_string(":A:B:C:D:" , ":" , true , ) => "A" & "B:C:D" + util_binary_split_string(":A:B:C:D:" , ":" , false , ) => "A:B:C" & "D" o If no split is found the whole content is in first_part, and second_part is NULL. If the input string == NULL, both return - strings will be NULL. + strings will be NULL. Observe that because leading split + characters are removed before the splitting starts: + util_binary_split_string(":ABCD" , ":" , true , ) => "ABCD" & NULL + */ void util_binary_split_string(const char * __src , const char * sep_set, bool split_on_first , char ** __first_part , char ** __second_part) { char * first_part = NULL; char * second_part = NULL; - if (__src != NULL) { - char * src; - int pos; - if (split_on_first) { - /* Removing leading separators. */ - pos = 0; - while ((pos < strlen(__src)) && (strchr(sep_set , __src[pos]) != NULL)) - pos += 1; - if (pos == strlen(__src)) /* The string consisted ONLY of separators. */ - src = NULL; - else - src = util_alloc_string_copy(&__src[pos]); - } else { - /*Remove trailing separators. */ - pos = strlen(__src) - 1; - while ((pos >= 0) && (strchr(sep_set , __src[pos]) != NULL)) - pos -= 1; - if (pos < 0) - src = NULL; - else - src = util_alloc_substring_copy(__src , 0 , pos + 1); - } + char * src; + + if (__src != NULL) { + int offset = 0; + int len; + /* 1: Remove leading split characters. */ + while ((offset < strlen(__src)) && (strchr(sep_set , __src[offset]) != NULL)) + offset++; + len = strlen( __src ) - offset; + if (len > 0) { + int tail_pos = strlen( __src ) - 1; + /* 2: Remove trailing split characters. */ + while (strchr(sep_set , __src[tail_pos]) != NULL) + tail_pos--; + len = 1 + tail_pos - offset; + + src = util_alloc_substring_copy(__src , offset , len); + } else + src = NULL; - /* OK - we have removed all leading (or trailing) separators, and we have a valid string which we can continue with. @@ -4326,6 +4626,41 @@ char * util_alloc_sprintf(const char * fmt , ...) { } +char * util_alloc_sprintf_escape(const char * src , int max_escape) { + if (src == NULL) + return NULL; + + if (max_escape == 0) + max_escape = strlen( src ); + + { + const int src_len = strlen( src ); + char * target = util_calloc( max_escape + strlen(src) + 1 , sizeof * target); + + int escape_count = 0; + int src_offset = 0; + int target_offset = 0; + + while (true) { + if (src[src_offset] == '%') { + if (escape_count < max_escape) { + target[target_offset] = '%'; + target_offset++; + escape_count++; + } + } + target[target_offset] = src[src_offset]; + target_offset++; + src_offset++; + if (src_offset == src_len) + break; + } + target[target_offset] = '\0'; + target = util_realloc( target , (target_offset + 1) * sizeof * target); + return target; + } +} + /* char * util_realloc_sprintf(char * s , const char * fmt , ...) { @@ -4419,22 +4754,6 @@ int util_get_type( void * data ) { -static void __add_item__(int **_active_list , int * _current_length , int *_list_length , int value) { - int *active_list = *_active_list; - int current_length = *_current_length; - int list_length = *_list_length; - - active_list[current_length] = value; - current_length++; - if (current_length == list_length) { - list_length *= 2; - active_list = util_realloc( active_list , list_length * sizeof * active_list ); - - *_active_list = active_list; - *_list_length = list_length; - } - *_current_length = current_length; -} /** @@ -4464,191 +4783,6 @@ int util_get_current_linenr(FILE * stream) { -/* - This functions parses an input string 'range_string' of the type: - - "0,1,8, 10 - 20 , 15,17-21" - - I.e. integers separated by "," and "-". The integer values are - parsed out. The result can be returned in two different ways: - - - o If active != NULL the entries in active (corresponding to the - values in the range) are marked as true. All other entries are - marked as false. The active array must be allocated by the - calling scope, with length (at least) "max_value + 1". - - o If active == NULL - an (int *) pointer is allocated, filled with - the active indices and returned. - -*/ - -//#include -//#include -//static int * util_sscanf_active_range__NEW(const char * range_string , int max_value , bool * active , int * _list_length) { -// tokenizer_type * tokenizer = tokenizer_alloc( NULL , /* No ordinary split characters. */ -// NULL , /* No quoters. */ -// ",-" , /* Special split on ',' and '-' */ -// " \t" , /* Removing ' ' and '\t' */ -// NULL , /* No comment */ -// NULL ); -// stringlist_type * tokens; -// tokens = tokenize_buffer( tokenizer , range_string , true); -// -// stringlist_free( tokens ); -// tokenizer_free( tokenizer ); -//} - - - - -static int * util_sscanf_active_range__(const char * range_string , int max_value , bool * active , int * _list_length) { - int *active_list = NULL; - int current_length = 0; - int list_length; - int value,value1,value2; - char * start_ptr = (char *) range_string; - char * end_ptr; - bool didnt_work = false; - - if (active != NULL) { - for (value = 0; value <= max_value; value++) - active[value] = false; - } else { - list_length = 10; - active_list = util_calloc( list_length , sizeof * active_list ); - } - - - while (start_ptr != NULL) { - value1 = strtol(start_ptr , &end_ptr , 10); - if (active != NULL && value1 > max_value) - fprintf(stderr , "** Warning - value:%d is larger than the maximum value: %d \n",value1 , max_value); - - if (end_ptr == start_ptr){ - printf("Returning to menu: %s \n" , start_ptr); - didnt_work = true; - break; - } - /* OK - we have found the first integer, now there are three possibilities: - - 1. The string contains nothing more (except) possibly whitespace. - 2. The next characters are " , " - with more or less whitespace. - 3. The next characters are " - " - with more or less whitespace. - - Otherwise it is a an invalid string. - */ - - - /* Storing the value. */ - if (active != NULL) { - if (value1 <= max_value) active[value1] = true; - } else - __add_item__(&active_list , ¤t_length , &list_length , value1); - - - - /* Skipping trailing whitespace. */ - start_ptr = end_ptr; - while (start_ptr[0] != '\0' && isspace(start_ptr[0])) - start_ptr++; - - - if (start_ptr[0] == '\0') /* We have found the end */ - start_ptr = NULL; - else { - /* OK - now we can point at "," or "-" - else malformed string. */ - if (start_ptr[0] == ',' || start_ptr[0] == '-') { - if (start_ptr[0] == '-') { /* This is a range */ - start_ptr++; /* Skipping the "-" */ - while (start_ptr[0] != '\0' && isspace(start_ptr[0])) - start_ptr++; - - if (start_ptr[0] == '\0') { - /* The range just ended - without second value. */ - printf("%s[0]: malformed string: %s \n",__func__ , start_ptr); - didnt_work = true; - break; - } - value2 = strtol(start_ptr , &end_ptr , 10); - if (end_ptr == start_ptr) { - printf("%s[1]: failed to parse integer from: %s \n",__func__ , start_ptr); - didnt_work = true; - break; - } - if (active != NULL && value2 > max_value) - fprintf(stderr , "** Warning - value:%d is larger than the maximum value: %d \n",value2 , max_value); - - if (value2 < value1){ - printf("%s[2]: invalid interval - must have increasing range \n",__func__); - didnt_work = true; - break; - } - start_ptr = end_ptr; - { - int value; - for (value = value1 + 1; value <= value2; value++) { - if (active != NULL) { - if (value <= max_value) active[value] = true; - } else - __add_item__(&active_list , ¤t_length , &list_length , value); - } - } - - /* Skipping trailing whitespace. */ - while (start_ptr[0] != '\0' && isspace(start_ptr[0])) - start_ptr++; - - - if (start_ptr[0] == '\0') - start_ptr = NULL; /* We are done */ - else { - if (start_ptr[0] == ',') - start_ptr++; - else{ - printf("%s[3]: malformed string: %s \n",__func__ , start_ptr); - didnt_work = true; - break; - } - } - } else - start_ptr++; /* Skipping "," */ - - /** - When this loop is finished the start_ptr should point at a - valid integer. I.e. for instance for the following input - string: "1-3 , 78" - ^ - - The start_ptr should point at "78". - */ - - } else{ - printf("%s[4]: malformed string: %s \n",__func__ , start_ptr); - didnt_work = true; - break; - } - } - } - if (_list_length != NULL) - *_list_length = current_length; - - if (didnt_work){ - for (value = 0; value <= max_value; value++) - active[value] = false; - } - - return active_list; -} - - -void util_sscanf_active_range(const char * range_string , int max_value , bool * active) { - util_sscanf_active_range__(range_string , max_value , active , NULL); -} - -int * util_sscanf_alloc_active_list(const char * range_string , int * list_length) { - return util_sscanf_active_range__(range_string , 0 , NULL , list_length); -} const char * util_enum_iget( int index , int size , const util_enum_element_type * enum_defs , int * value) { @@ -4682,11 +4816,23 @@ void util_abort_free_version_info() { } -void util_abort_set_executable( const char * executable ) { - __current_executable = util_realloc_string_copy( __current_executable , executable ); +void util_abort_set_executable( const char * argv0 ) { + if (util_is_abs_path(argv0)) + __current_executable = util_realloc_string_copy( __current_executable , argv0 ); + else { + char * executable; + if (util_is_executable( argv0 )) + executable = util_alloc_realpath(argv0); + else + executable = util_alloc_PATH_executable( argv0 ); + + util_abort_set_executable( executable ); + free( executable ); + } } + /*****************************************************************/ /* @@ -4734,6 +4880,8 @@ CONTAINS(size_t) /*****************************************************************/ + + int util_fnmatch( const char * pattern , const char * string ) { #ifdef HAVE_FNMATCH return fnmatch( pattern , string , 0 ); @@ -4797,17 +4945,11 @@ char * util_alloc_link_target(const char * link) { } #endif -#ifdef HAVE_FORK -#ifdef WITH_PTHREAD -#ifdef HAVE_EXECINFO + + +#ifdef HAVE_UTIL_ABORT #include "util_abort_gnu.c" -#define HAVE_UTIL_ABORT -#endif -#endif -#endif - - -#ifndef HAVE_UTIL_ABORT +#else #include "util_abort_simple.c" #endif diff --git a/ThirdParty/Ert/devel/libert_util/src/util_abort_gnu.c b/ThirdParty/Ert/devel/libert_util/src/util_abort_gnu.c index 1195234dbd..9daba050da 100644 --- a/ThirdParty/Ert/devel/libert_util/src/util_abort_gnu.c +++ b/ThirdParty/Ert/devel/libert_util/src/util_abort_gnu.c @@ -2,90 +2,15 @@ This file implements the fully fledged util abort() function which assumes that the current build has the following features: - fork() : To support calling external program addr2line(). - pthread : To serialize the use of util abort() - not very important. - execinfo.h : The backtrace functions backtrace() and backtrace symbols(). + fork() : To support calling external program addr2line(). + pthread : To serialize the use of util abort() - not very important. + execinfo.h : The backtrace functions backtrace() and backtrace symbols(). + _GNU_SOURCE : To get the dladdr() function. If not all these features are availbale the simpler version in util abort_simple.c is built instead. */ - - -/** - This function uses the external program addr2line to convert the - hexadecimal adress given by the libc function backtrace() into a - function name and file:line. - - Observe that the function is quite involved, so if util_abort() is - called because something is seriously broken, it might very well fail. - - The executable should be found from one line in the backtrace with - the function util_bt_alloc_current_executable(), the argument - bt_symbol is the lines generated by the bt_symbols() function. - - This function is purely a helper function for util_abort(). -*/ - -static void util_addr2line_lookup(const char * executable , const char * bt_symbol , char ** func_name , char ** file_line) { - char *tmp_file = util_alloc_tmp_file("/tmp" , "addr2line" , true); - char * adress; - { - int start_pos = 0; - int end_pos; - while ( bt_symbol[start_pos] != '[') - start_pos++; - - end_pos = start_pos; - while ( bt_symbol[end_pos] != ']') - end_pos++; - - adress = util_alloc_substring_copy( bt_symbol , start_pos + 1 , end_pos - start_pos - 1 ); - } - - { - char ** argv; - - argv = util_calloc(3 , sizeof * argv ); - argv[0] = util_alloc_string_copy("--functions"); - argv[1] = util_alloc_sprintf("--exe=%s" , executable); - argv[2] = util_alloc_string_copy(adress); - - util_fork_exec("addr2line" , 3 , (const char **) argv , true , NULL , NULL , NULL , tmp_file , NULL); - util_free_stringlist(argv , 3); - } - - { - bool at_eof; - FILE * stream = util_fopen(tmp_file , "r"); - *func_name = util_fscanf_alloc_line(stream , &at_eof); - *file_line = util_fscanf_alloc_line(stream , &at_eof); - fclose(stream); - } - util_unlink_existing(tmp_file); - free(adress); - free(tmp_file); -} - - - -/** - This function prints a message to stderr and aborts. The function is - implemented with the help of a variable length argument list - just - like printf(fmt , arg1, arg2 , arg3 ...); - - Observe that it is __VERY__ important that the arguments and the - format string match up, otherwise the util_abort() routine will hang - indefinetely; without printing anything to stderr. - - A backtrace is also included, with the help of the exernal utility - addr2line, this backtrace is converted into usable - function/file/line information (provided the required debugging - information is compiled in). -*/ - -static pthread_mutex_t __abort_mutex = PTHREAD_MUTEX_INITIALIZER; /* Used purely to serialize the util_abort() routine. */ - /** If the variable __current_executable has been set, that value is returned as the executable, otherwise an attempt (which generally @@ -124,14 +49,178 @@ static char * util_bt_alloc_current_executable(const char * bt_symbol) { } + + +/** + This function uses the external program addr2line to convert the + hexadecimal adress given by the libc function backtrace() into a + function name and file:line. + + Observe that the function is quite involved, so if util_abort() is + called because something is seriously broken, it might very well fail. + + The executable should be found from one line in the backtrace with + the function util_bt_alloc_current_executable(), the argument + bt_symbol is the lines generated by the bt_symbols() function. + + This function is purely a helper function for util_abort(). +*/ + + + +#define UNDEFINED_FUNCTION "??" + +static bool util_addr2line_lookup__(const void * bt_addr , char ** func_name , char ** file_name , int * line_nr, bool subtract_base_adress) { + *func_name = NULL; // If dladdr() succeeds, but addr2line fails the func_name pointer will be set, but the function will return false anyway. + *file_name = NULL; + *line_nr = 0; + { + bool address_found = false; + Dl_info dl_info; + + if (dladdr(bt_addr , &dl_info)) { + const char * executable = dl_info.dli_fname; + *func_name = util_alloc_string_copy( dl_info.dli_sname ); + if (util_file_exists( executable )) { + char *stdout_file = util_alloc_tmp_file("/tmp" , "addr2line" , true); + /* 1: Run addr2line application */ + { + char ** argv = util_calloc(3 , sizeof * argv ); + argv[0] = util_alloc_string_copy("--functions"); + argv[1] = util_alloc_sprintf("--exe=%s" , executable ); + { + char * rel_address = (char *) bt_addr; + if (subtract_base_adress) + rel_address -= (size_t) dl_info.dli_fbase; + argv[2] = util_alloc_sprintf("%p" , (void *) rel_address); + } + util_fork_exec("addr2line" , 3 , (const char **) argv , true , NULL , NULL , NULL , stdout_file , NULL); + util_free_stringlist(argv , 3); + } + + /* 2: Parse stdout output */ + { + bool at_eof; + FILE * stream = util_fopen(stdout_file , "r"); + char * tmp_fname = util_fscanf_alloc_line(stream , &at_eof); + + if (strcmp(tmp_fname , UNDEFINED_FUNCTION) != 0) { + char * stdout_file_name = util_fscanf_alloc_line(stream , &at_eof); + char * line_string = NULL; + util_binary_split_string( stdout_file_name , ":" , false , file_name , &line_string); + if (line_string && util_sscanf_int( line_string , line_nr)) + address_found = true; + + free( stdout_file_name ); + util_safe_free( line_string ); + } + free( tmp_fname ); + fclose(stream); + } + util_unlink_existing(stdout_file); + free( stdout_file ); + } + } + return address_found; + } +} + + + +bool util_addr2line_lookup(const void * bt_addr , char ** func_name , char ** file_name , int * line_nr) { + if (util_addr2line_lookup__(bt_addr , func_name , file_name , line_nr , false)) + return true; + else + return util_addr2line_lookup__(bt_addr , func_name , file_name , line_nr , true); +} + + +/** + This function prints a message to stream and aborts. The function is + implemented with the help of a variable length argument list - just + like printf(fmt , arg1, arg2 , arg3 ...); + + Observe that it is __VERY__ important that the arguments and the + format string match up, otherwise the util_abort() routine will hang + indefinetely; without printing anything to stream. + + A backtrace is also included, with the help of the exernal utility + addr2line, this backtrace is converted into usable + function/file/line information (provided the required debugging + information is compiled in). +*/ + +static pthread_mutex_t __abort_mutex = PTHREAD_MUTEX_INITIALIZER; /* Used purely to serialize the util_abort() routine. */ + + +static char * realloc_padding(char * pad_ptr , int pad_length) { + int i; + pad_ptr = util_realloc( pad_ptr , (pad_length + 1) * sizeof * pad_ptr ); + for (i=0; i < pad_length; i++) + pad_ptr[i] = ' '; + pad_ptr[pad_length] = '\0'; + return pad_ptr; +} + + + +static void util_fprintf_backtrace(FILE * stream) { + const char * with_linenr_format = " #%02d %s(..) %s in %s:%d\n"; + const char * func_format = " #%02d %s(..) %s in ???\n"; + const char * unknown_format = " #%02d ???? \n"; + + const int max_bt = 50; + const int max_func_length = 45; + void *bt_addr[max_bt]; + int size,i; + + size = backtrace(bt_addr , max_bt); + + fprintf(stream , "--------------------------------------------------------------------------------\n"); + for (i=0; i < size; i++) { + int line_nr; + char * func_name; + char * file_name; + char * padding = NULL; + + if (util_addr2line_lookup(bt_addr[i] , &func_name , &file_name , &line_nr)) { + int pad_length; + char * function; + // Seems it can return true - but with func_name == NULL?! Static/inlinded functions? + if (func_name) + function = func_name; + else + function = "???"; + + pad_length = 2 + max_func_length - strlen(function); + padding = realloc_padding( padding , pad_length); + fprintf(stream , with_linenr_format , i , function , padding , file_name , line_nr); + } else { + if (func_name != NULL) { + int pad_length = 2 + max_func_length - strlen(func_name); + padding = realloc_padding( padding , pad_length); + fprintf(stream , func_format , i , func_name , padding); + } else { + padding = realloc_padding( padding , 2 + max_func_length ); + fprintf(stream , unknown_format , i , padding); + } + } + + util_safe_free( func_name ); + util_safe_free( file_name ); + util_safe_free( padding ); + } + fprintf(stream , "--------------------------------------------------------------------------------\n"); +} + void util_abort(const char * fmt , ...) { pthread_mutex_lock( &__abort_mutex ); /* Abort before unlock() */ { va_list ap; va_start(ap , fmt); - printf("\n\n"); - fprintf(stderr,"\n\n"); + fprintf(stderr , "\n\n"); + fprintf(stderr , "\n\n"); vfprintf(stderr , fmt , ap); va_end(ap); @@ -143,18 +232,10 @@ void util_abort(const char * fmt , ...) { const bool include_backtrace = true; if (include_backtrace) { - const int max_bt = 50; - char *executable; - void *array[max_bt]; - char **strings; - char ** func_list; - char ** file_line_list; - int max_func_length = 0; - int size,i; - if (__abort_program_message != NULL) { fprintf(stderr,"--------------------------------------------------------------------------------\n"); fprintf(stderr,"%s",__abort_program_message); + fprintf(stderr, "Current executable ..: %s\n" , program_invocation_name); fprintf(stderr,"--------------------------------------------------------------------------------\n"); } @@ -171,52 +252,17 @@ void util_abort(const char * fmt , ...) { fprintf(stderr,"** broken as well. **\n"); fprintf(stderr,"** **\n"); fprintf(stderr,"****************************************************************************\n"); - size = backtrace(array , max_bt); - strings = backtrace_symbols(array , size); - executable = util_bt_alloc_current_executable(strings[0]); - if (executable != NULL) { - fprintf(stderr,"Current executable : %s \n",executable); - - func_list = util_calloc(size , sizeof * func_list ); - file_line_list = util_calloc(size , sizeof * file_line_list ); - - for (i=0; i < size; i++) { - util_addr2line_lookup(executable , strings[i] , &func_list[i] , &file_line_list[i]); - max_func_length = util_int_max(max_func_length , strlen(func_list[i])); - } - - { - char string_fmt[64]; - sprintf(string_fmt, " #%s02d %s-%ds(..) in %ss \n" , "%" , "%" , max_func_length , "%"); - fprintf(stderr , "--------------------------------------------------------------------------------\n"); - for (i=0; i < size; i++) { - - int line_nr; - if (util_sscanf_int(file_line_list[i] , &line_nr)) - fprintf(stderr, string_fmt , i , func_list[i], file_line_list[i]); - else - fprintf(stderr, string_fmt , i , func_list[i], file_line_list[i]); - } - fprintf(stderr , "--------------------------------------------------------------------------------\n"); - util_free_stringlist(func_list , size); - util_free_stringlist(file_line_list , size); - } - } else - fprintf(stderr,"Could not determine executable file for:%s - no backtrace. \n",strings[0]); - - free(strings); - util_safe_free(executable); - } - if (getenv("UTIL_ABORT") != NULL) { - fprintf(stderr , "Aborting ... \n"); - abort(); - } else { - fprintf(stderr , "Exiting ... \n"); - exit(1); + util_fprintf_backtrace( stderr ); } - // Would have preferred abort() here - but that comes in conflict with the SIGABRT signal. } pthread_mutex_unlock( &__abort_mutex ); + + signal(SIGABRT , SIG_DFL); + fprintf(stderr , "Aborting ... \n"); + abort(); } + +/*****************************************************************/ + diff --git a/ThirdParty/Ert/devel/libert_util/src/util_abort_simple.c b/ThirdParty/Ert/devel/libert_util/src/util_abort_simple.c index ba1b466496..ffe4203004 100644 --- a/ThirdParty/Ert/devel/libert_util/src/util_abort_simple.c +++ b/ThirdParty/Ert/devel/libert_util/src/util_abort_simple.c @@ -2,7 +2,7 @@ This file implements a simpler version of the util_abort() function which does not present a backtrace. */ - +#include @@ -24,13 +24,9 @@ void util_abort(const char * fmt , ...) { } fprintf(stderr,"-----------------------------------------------------------------\n"); - if (getenv("UTIL_ABORT") != NULL) { - fprintf(stderr , "Aborting ... \n"); - abort(); - } else { - fprintf(stderr , "Exiting ... \n"); - exit(1); - } - // Would have preferred abort() here - but that comes in conflict with the SIGABRT signal. + signal(SIGABRT , SIG_DFL); + fprintf(stderr , "Aborting ... \n"); + assert(0); + abort(); } diff --git a/ThirdParty/Ert/devel/libert_util/src/util_env.c b/ThirdParty/Ert/devel/libert_util/src/util_env.c index 303ed7043e..934e3e75ae 100644 --- a/ThirdParty/Ert/devel/libert_util/src/util_env.c +++ b/ThirdParty/Ert/devel/libert_util/src/util_env.c @@ -46,6 +46,26 @@ void util_unsetenv( const char * variable ) { } #endif +/** + Will return a NULL terminated list char ** of the paths in the PATH + variable. +*/ + +char ** util_alloc_PATH_list() { + char ** path_list = NULL; + char * path_env = getenv("PATH"); + if (path_env != NULL) { + int path_size; + + util_split_string(path_env , PATHVAR_SPLIT , &path_size , &path_list); + path_list = util_realloc( path_list , (path_size + 1) * sizeof * path_list); + path_list[path_size] = NULL; + } else { + path_list = util_malloc( sizeof * path_list); + path_list[0] = NULL; + } + return path_list; +} /** This function searches through the content of the (currently set) @@ -81,29 +101,26 @@ char * util_alloc_PATH_executable(const char * executable) { return path; } else { - char * full_path = NULL; - char * path_env = getenv("PATH"); - if (path_env != NULL) { - bool cont = true; - char ** path_list; - int path_size , ipath; - - ipath = 0; - util_split_string(path_env , PATHVAR_SPLIT , &path_size , &path_list); - while ( cont ) { + char * full_path = NULL; + char ** path_list = util_alloc_PATH_list(); + int ipath = 0; + + while (true) { + if (path_list[ipath] != NULL) { char * current_attempt = util_alloc_filename(path_list[ipath] , executable , NULL); + if ( util_is_file( current_attempt ) && util_is_executable( current_attempt )) { full_path = current_attempt; - cont = false; + break; } else { free(current_attempt); ipath++; - if (ipath == path_size) - cont = false; } - } - util_free_stringlist(path_list , path_size); + } else + break; } + + util_free_NULL_terminated_stringlist(path_list); return full_path; } } diff --git a/ThirdParty/Ert/devel/libert_util/src/util_fork.c b/ThirdParty/Ert/devel/libert_util/src/util_fork.c index 13f71ea822..2eda0d2806 100644 --- a/ThirdParty/Ert/devel/libert_util/src/util_fork.c +++ b/ThirdParty/Ert/devel/libert_util/src/util_fork.c @@ -79,21 +79,14 @@ pid_t util_fork_exec(const char * executable , int argc , const char ** argv , util_abort("%s: failed to change to directory:%s %s \n",__func__ , run_path , strerror(errno)); } - if (stdout_file != NULL) { - /** This is just to invoke the "block on full disk behaviour" before the external program starts. */ - FILE * stream = util_fopen( stdout_file , "w"); - fclose(stream); + if (stdout_file != NULL) __util_redirect(1 , stdout_file , O_WRONLY | O_TRUNC | O_CREAT); - } - - if (stderr_file != NULL) { - /** This is just to invoke the "block on full disk behaviour" before the external program starts. */ - FILE * stream = util_fopen( stderr_file , "w"); - fclose(stream); + + if (stderr_file != NULL) __util_redirect(2 , stderr_file , O_WRONLY | O_TRUNC | O_CREAT); - } - if (stdin_file != NULL) __util_redirect(0 , stdin_file , O_RDONLY); - + + if (stdin_file != NULL) + __util_redirect(0 , stdin_file , O_RDONLY); __argv = util_malloc((argc + 2) * sizeof * __argv ); __argv[0] = executable; @@ -115,6 +108,7 @@ pid_t util_fork_exec(const char * executable , int argc , const char ** argv , } else { /* Parent */ + if (blocking) { waitpid(child_pid , NULL , 0); @@ -236,7 +230,32 @@ char * util_alloc_filename_from_stream( FILE * input_stream ) { return filename; } - + +/** + The ping program must(?) be setuid root, so implementing a simple + version based on sockets() proved to be nontrivial. + + The PING_CMD is passed as -D from the build system. +*/ + +bool util_ping(const char *hostname) { + pid_t ping_pid = util_fork_exec(PING_CMD , 4 , (const char *[4]) {"-c" , "3" , "-q", hostname} , false , NULL , NULL , NULL , NULL , NULL); + int wait_status; + pid_t wait_pid = waitpid(ping_pid , &wait_status , 0); + + if (wait_pid == -1) + return false; + else { + if (WIFEXITED( wait_status )) { + int ping_status = WEXITSTATUS( wait_status ); + if (ping_status == 0) + return true; + else + return false; + } else + return false; + } +} diff --git a/ThirdParty/Ert/devel/libert_util/src/util_path.c b/ThirdParty/Ert/devel/libert_util/src/util_path.c index 17ac011d8d..40e512aaff 100644 --- a/ThirdParty/Ert/devel/libert_util/src/util_path.c +++ b/ThirdParty/Ert/devel/libert_util/src/util_path.c @@ -205,7 +205,6 @@ int util_proc_mem_free(void) { - void util_path_split(const char *line , int *_tokens, char ***_token_list) { util_split_string( line , UTIL_PATH_SEP_STRING , _tokens , _token_list); } diff --git a/ThirdParty/Ert/devel/libert_util/src/vector.c b/ThirdParty/Ert/devel/libert_util/src/vector.c index b4fe3181ef..d84b67d6f4 100644 --- a/ThirdParty/Ert/devel/libert_util/src/vector.c +++ b/ThirdParty/Ert/devel/libert_util/src/vector.c @@ -449,7 +449,8 @@ const void * vector_get_last_const(const vector_type * vector) { This function removes the last element from the vector and returns it to the calling scope. Irrespective of whether the element _was_ inserted with a destructor: when calling vector_pop() the calling - scope takes responsability for freeing data. + scope takes responsability for freeing data; i.e. vector_pop will + NEVER call a destructor. */ @@ -577,6 +578,21 @@ void vector_sort(vector_type * vector , vector_cmp_ftype * cmp) { } +void vector_inplace_reverse(vector_type * vector) { + if (vector->size > 0) { + node_data_type ** new_data = util_calloc( vector->size , sizeof * new_data ); + int index; + for (index = 0; index < vector->size; index++) { + int rev_index = vector->size - 1 - index; + new_data[index] = vector->data[ rev_index ]; + } + free(vector->data); + vector->data = new_data; + } +} + + + /*****************************************************************/ diff --git a/ThirdParty/Ert/devel/libert_util/src/vector_template.c b/ThirdParty/Ert/devel/libert_util/src/vector_template.c index dd6fc5d667..65d48ad0c7 100644 --- a/ThirdParty/Ert/devel/libert_util/src/vector_template.c +++ b/ThirdParty/Ert/devel/libert_util/src/vector_template.c @@ -672,6 +672,11 @@ void @TYPE@_vector_reset(@TYPE@_vector_type * vector) { } +void @TYPE@_vector_free_container(@TYPE@_vector_type * vector) { + free( vector ); +} + + void @TYPE@_vector_free_data(@TYPE@_vector_type * vector) { @TYPE@_vector_reset(vector); @TYPE@_vector_realloc_data__(vector , 0); @@ -681,7 +686,7 @@ void @TYPE@_vector_free_data(@TYPE@_vector_type * vector) { void @TYPE@_vector_free(@TYPE@_vector_type * vector) { if (vector->data_owner) util_safe_free( vector->data ); - free( vector ); + @TYPE@_vector_free_container( vector ); } @@ -777,6 +782,20 @@ void @TYPE@_vector_set_all(@TYPE@_vector_type * vector , @TYPE@ value) { } } +bool @TYPE@_vector_init_range(@TYPE@_vector_type * vector , @TYPE@ min_value , @TYPE@ max_value , @TYPE@ delta) { + if (max_value >= min_value) { + @TYPE@ current_value = min_value; + @TYPE@_vector_reset( vector ); + while (current_value < max_value) { + @TYPE@_vector_append( vector , current_value ); + current_value += delta; + } + @TYPE@_vector_append( vector , max_value ); + return true; + } else + return false; +} + void @TYPE@_vector_append_many(@TYPE@_vector_type * vector , const @TYPE@ * data , int length) { @TYPE@_vector_set_many( vector , @TYPE@_vector_size( vector ) , data , length); diff --git a/ThirdParty/Ert/devel/libert_util/tests/CMakeLists.txt b/ThirdParty/Ert/devel/libert_util/tests/CMakeLists.txt index a376f74818..a33369c27d 100644 --- a/ThirdParty/Ert/devel/libert_util/tests/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libert_util/tests/CMakeLists.txt @@ -1,17 +1,100 @@ +# This should be a space separated list of up to three servers which +# will be tried out when testing the util_ping() functionality. The +# list of servers should behave like this: +# +# 1. First server - this should be an existing server which should return true. +# 2. This should be an invalid hostname - should return false. +# 3. This should be an valid host which does not answer ping - i.e currently off? +set(PING_SERVERS "localhost" CACHE STRING "List of LSF servers for testing") + + link_directories( ${ERT_BINARY_DIR}/libert_util/src ) add_executable( ert_util_type_vector_test ert_util_type_vector_test.c ) target_link_libraries( ert_util_type_vector_test ert_util ) add_test( ert_util_type_vector_test ${EXECUTABLE_OUTPUT_PATH}/ert_util_type_vector_test ) +add_executable( ert_util_string_util ert_util_string_util.c ) +target_link_libraries( ert_util_string_util ert_util ) +add_test( ert_util_string_util ${EXECUTABLE_OUTPUT_PATH}/ert_util_string_util ) + add_executable( ert_util_vector_test ert_util_vector_test.c ) target_link_libraries( ert_util_vector_test ert_util ) add_test( ert_util_vector_test ${EXECUTABLE_OUTPUT_PATH}/ert_util_vector_test ) +add_executable( ert_util_cwd_test ert_util_cwd_test.c ) +target_link_libraries( ert_util_cwd_test ert_util ) +add_test( ert_util_cwd_test ${EXECUTABLE_OUTPUT_PATH}/ert_util_cwd_test ${CMAKE_CURRENT_BINARY_DIR}) + +add_executable( ert_util_relpath_test ert_util_relpath_test.c ) +target_link_libraries( ert_util_relpath_test ert_util ) +add_test( ert_util_relpath_test ${EXECUTABLE_OUTPUT_PATH}/ert_util_relpath_test ) + +add_executable( ert_util_path_stack_test ert_util_path_stack_test.c ) +target_link_libraries( ert_util_path_stack_test ert_util ) +add_test( ert_util_path_stack_test ${EXECUTABLE_OUTPUT_PATH}/ert_util_path_stack_test ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) + +add_executable( ert_util_PATH_test ert_util_PATH_test.c ) +target_link_libraries( ert_util_PATH_test ert_util ) +add_test( ert_util_PATH_test ${EXECUTABLE_OUTPUT_PATH}/ert_util_PATH_test ) + +add_executable( ert_util_strcat_test ert_util_strcat_test.c ) +target_link_libraries( ert_util_strcat_test ert_util ) +add_test( ert_util_strcat_test ${EXECUTABLE_OUTPUT_PATH}/ert_util_strcat_test ) + +add_executable( ert_util_sprintf_escape ert_util_sprintf_escape.c ) +target_link_libraries( ert_util_sprintf_escape ert_util ) +add_test( ert_util_sprintf_escape ${EXECUTABLE_OUTPUT_PATH}/ert_util_sprintf_escape ) + + add_executable( ert_util_stringlist_test ert_util_stringlist_test.c ) target_link_libraries( ert_util_stringlist_test ert_util ) add_test( ert_util_stringlist_test ${EXECUTABLE_OUTPUT_PATH}/ert_util_stringlist_test ) +add_executable( ert_util_realpath ert_util_realpath.c ) +target_link_libraries( ert_util_realpath ert_util ) +add_test( ert_util_realpath ${EXECUTABLE_OUTPUT_PATH}/ert_util_realpath ) + +add_executable( ert_util_hash_test ert_util_hash_test.c ) +target_link_libraries( ert_util_hash_test ert_util ) +add_test( ert_util_hash_test ${EXECUTABLE_OUTPUT_PATH}/ert_util_hash_test ) + +add_executable( ert_util_binary_split ert_util_binary_split.c ) +target_link_libraries( ert_util_binary_split ert_util ) +add_test( ert_util_binary_split ${EXECUTABLE_OUTPUT_PATH}/ert_util_binary_split ) + +add_executable( ert_util_logh ert_util_logh.c ) +target_link_libraries( ert_util_logh ert_util ) +add_test( ert_util_logh ${EXECUTABLE_OUTPUT_PATH}/ert_util_logh ) + +add_executable( ert_util_rng ert_util_rng.c ) +target_link_libraries( ert_util_rng ert_util ) +add_test( ert_util_rng ${EXECUTABLE_OUTPUT_PATH}/ert_util_rng ) + +add_executable( ert_util_time_interval ert_util_time_interval.c ) +target_link_libraries( ert_util_time_interval ert_util ) +add_test( ert_util_time_interval ${EXECUTABLE_OUTPUT_PATH}/ert_util_time_interval ) + +add_executable( ert_util_before_after ert_util_before_after.c ) +target_link_libraries( ert_util_before_after ert_util ) +add_test( ert_util_before_after ${EXECUTABLE_OUTPUT_PATH}/ert_util_before_after ) + +add_executable( ert_util_approx_equal ert_util_approx_equal.c ) +target_link_libraries( ert_util_approx_equal ert_util ) +add_test( ert_util_approx_equal ${EXECUTABLE_OUTPUT_PATH}/ert_util_approx_equal ) + +add_executable( ert_util_ping ert_util_ping.c ) +target_link_libraries( ert_util_ping ert_util ) +add_test( ert_util_ping ${EXECUTABLE_OUTPUT_PATH}/ert_util_ping ${PING_SERVERS}) + +add_executable( ert_util_file_readable ert_util_file_readable.c ) +target_link_libraries( ert_util_file_readable ert_util ) +add_test( ert_util_file_readable ${EXECUTABLE_OUTPUT_PATH}/ert_util_file_readable ${FILE_READABLE_SERVERS}) + +add_executable( ert_util_addr2line ert_util_addr2line.c ) +target_link_libraries( ert_util_addr2line ert_util ) +add_test( ert_util_addr2line ${EXECUTABLE_OUTPUT_PATH}/ert_util_addr2line) + if (WITH_LATEX) add_executable( ert_util_latex_test ert_util_latex_test.c ) target_link_libraries(ert_util_latex_test ert_util ) diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_PATH_test.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_PATH_test.c new file mode 100644 index 0000000000..4eada494ec --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_PATH_test.c @@ -0,0 +1,59 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_PATH_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include +#include + + + +int main(int argc , char ** argv) { + unsetenv("PATH"); + { + char ** path_list = util_alloc_PATH_list(); + if (path_list[0] != NULL) + test_error_exit("Failed on empty PATH\n"); + + util_free_NULL_terminated_stringlist( path_list ); + } + + + setenv("PATH" , "/usr/bin:/bin:/usr/local/bin" , 1); + { + char ** path_list = util_alloc_PATH_list(); + if (strcmp(path_list[0] , "/usr/bin") != 0) + test_error_exit("Failed on first path element\n"); + + if (strcmp(path_list[1] , "/bin") != 0) + test_error_exit("Failed on second path element\n"); + + if (strcmp(path_list[2] , "/usr/local/bin") != 0) + test_error_exit("Failed on third path element\n"); + + if (path_list[3] != NULL) + test_error_exit("Failed termination \n"); + + util_free_NULL_terminated_stringlist( path_list ); + } + + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_addr2line.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_addr2line.c new file mode 100644 index 0000000000..754dda49b3 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_addr2line.c @@ -0,0 +1,108 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_addr2line.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include + + +void test_lookup(bool valid_address, bool change_cwd) { + const char * file = __FILE__; + const char * func = __func__; + int line; + const int max_bt = 50; + void *bt_addr[max_bt]; + int size; + char * func_name , * file_name; + int line_nr; + + line = __LINE__ + 2; + size = backtrace(bt_addr , max_bt); + test_assert_int_equal( size , 4 ); + + if (change_cwd) { + char * cwd = util_alloc_cwd(); + chdir("/tmp"); + if (valid_address) { + test_assert_false( util_addr2line_lookup( bt_addr[0] , &func_name , &file_name , &line_nr)); + test_assert_string_equal( func_name , func ); + test_assert_string_equal( file_name , NULL ); + test_assert_int_equal( 0 , line_nr); + } else { + test_assert_false( util_addr2line_lookup( NULL , &func_name , &file_name , &line_nr)); + test_assert_string_equal( func_name , NULL); + test_assert_string_equal( file_name , NULL); + test_assert_int_equal( 0 , line_nr ); + } + chdir(cwd); + free( cwd ); + } else { + if (valid_address) { + test_assert_true( util_addr2line_lookup( bt_addr[0] , &func_name , &file_name , &line_nr)); + test_assert_string_equal( func_name , func ); + test_assert_string_equal( file_name , file ); + test_assert_int_equal( line , line_nr ); + } else { + test_assert_false( util_addr2line_lookup( NULL , &func_name , &file_name , &line_nr)); + test_assert_string_equal( func_name , NULL); + test_assert_string_equal( file_name , NULL); + test_assert_int_equal( 0 , line_nr ); + } + } + + +} + + +int main( int argc , char ** argv) { + char * path = argv[0]; + if (util_is_abs_path(argv[0])) { + char * path; + char * name; + char * dot_name; + pid_t child_pid; + /* + This bisaaarre hoopsing is to be able to emulate the situation + where addr2line can not find the executable; this behavour is + invoked when change_cwd is set to true in the test_lookup() + call. + */ + util_alloc_file_components( argv[0] , &path , &name, NULL); + + chdir(path); + dot_name = util_alloc_sprintf("./%s" , name); + child_pid = util_fork_exec( dot_name , 0 , NULL , true , NULL , NULL , NULL , NULL , NULL); + exit(0); + } else { + printf("Testing internal lookup ....\n"); + test_lookup(true, false); + test_lookup(false , false); + + test_lookup(true, true); + test_lookup(false , true); + + printf("Testing external lookup ....\n"); + test_util_addr2line(); + + exit(0); + } +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_approx_equal.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_approx_equal.c new file mode 100644 index 0000000000..1dcc801cd9 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_approx_equal.c @@ -0,0 +1,41 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_approx_equal.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include + + + + +int main( int argc , char ** argv) { + + test_assert_double_not_equal( -1.0 , 1.0 ); + test_assert_double_not_equal( 0.00000000002 , 0.000000000001 ); + test_assert_double_not_equal( 0.00000000002 , 0.000000000001 ); + + test_assert_double_equal( 1.00000000002 , 1.000000000001 ); + test_assert_double_equal( 0.0 , 0.0 ); + test_assert_double_equal( 0.75 , asin( sin(0.75))); + test_assert_double_equal( 2.25 , exp( log(2.25))); + test_assert_double_equal( 2.25 , log( exp(2.25))); + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_before_after.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_before_after.c new file mode 100644 index 0000000000..7185674ec4 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_before_after.c @@ -0,0 +1,41 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_before_after.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include + + + +int main( int argc , char ** argv) { + time_t t1 = util_make_date(1,1,2000); + time_t t2 = util_make_date(1,1,2001); + + test_assert_true( util_before( t1 , t2 )); + test_assert_true( util_after( t2 , t1 )); + + test_assert_false( util_before( t2 , t1 )); + test_assert_false( util_after( t1 , t2 )); + + test_assert_false( util_before( t1 , t1 )); + test_assert_false( util_after( t1 , t1 )); + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_binary_split.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_binary_split.c new file mode 100644 index 0000000000..c5c01f625a --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_binary_split.c @@ -0,0 +1,55 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ert_util_binary_split.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include + +void test_split(const char * test_string , bool split_on_first , const char * true1, const char * true2) { + char * part1; + char * part2; + + + util_binary_split_string( test_string , ":" , split_on_first , &part1 , &part2 ); + test_assert_string_equal( true1 , part1 ); + test_assert_string_equal( true2 , part2 ); + + util_binary_split_string( test_string , ":;" , split_on_first , &part1 , &part2 ); + test_assert_string_equal( true1 , part1 ); + test_assert_string_equal( true2 , part2 ); + + util_binary_split_string( test_string , ";" , split_on_first , &part1 , &part2 ); + test_assert_string_equal( test_string , part1 ); + test_assert_string_equal( NULL , part2 ); +} + +int main(int argc , char ** argv) { + + test_split( "Hello:Hello" , true , "Hello" , "Hello"); + test_split( "ABC:DEF:GEH" , true , "ABC" , "DEF:GEH"); + test_split( "ABC:DEF:GEH" , false , "ABC:DEF" , "GEH"); + test_split( "ABC:DEF:GEH:" , false , "ABC:DEF" , "GEH"); + test_split( "ABC:DEF:GEH:" , true , "ABC", "DEF:GEH"); + test_split( "ABCDEFGEH" , false , "ABCDEFGEH" , NULL); + test_split( "ABCDEFGEH:" , false , "ABCDEFGEH" , NULL); + test_split( ":ABCDEFGEH" , false , "ABCDEFGEH" , NULL); + test_split( NULL , false , NULL , NULL); + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_cwd_test.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_cwd_test.c new file mode 100644 index 0000000000..d5c593fe5f --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_cwd_test.c @@ -0,0 +1,37 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_cwd_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include + +int main(int argc , char ** argv) { + char * cwd = argv[1]; + printf("cwd :%s\n",util_alloc_cwd()); + printf("argv[1]:%s\n",argv[1]); + + if (!util_is_cwd(cwd)) + test_error_exit("Hmmm did not recognize:%s as cwd\n",cwd); + + if (util_is_cwd("/some/path")) + test_error_exit("Took /whatver/ as CWD\n"); + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_file_readable.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_file_readable.c new file mode 100644 index 0000000000..35a5cdd250 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_file_readable.c @@ -0,0 +1,55 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ert_util_file_readable.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include +#include + +#include +#include + + +void assert_equal( bool equal ) { + if (!equal) + exit(1); +} + + + + +int main(int argc , char ** argv) { + test_assert_true( util_file_readable( argv[0] )); + { + char * path; + util_alloc_file_components( argv[0] , &path , NULL , NULL); + test_assert_false( util_file_readable( path )); + util_safe_free( path ); + } + { + const char * file = "/tmp/test_file.txt"; + mode_t mode = 0; + FILE * stream = util_fopen(file , "w"); + fclose( stream ); + + chmod(file , mode); + test_assert_false( util_file_readable( file)); + unlink( file ); + } + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_hash_test.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_hash_test.c new file mode 100644 index 0000000000..b7a5779e2c --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_hash_test.c @@ -0,0 +1,43 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_hash_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include + +int main(int argc , char ** argv) { + + hash_type * h = hash_alloc(); + + test_assert_bool_equal( hash_add_option( h , "Key" ) , false ); + test_assert_false( hash_add_option( h , "Key" ) ); + + test_assert_true( hash_add_option( h , "Key1:Value" ) ); + test_assert_true( hash_add_option( h , "Key2:Value1:Value2" ) ); + test_assert_true( hash_add_option( h , "Key3:Value1:value2:Value3" ) ); + + test_assert_string_equal( hash_get( h , "Key1" ) , "Value" ); + test_assert_string_equal( hash_get( h , "Key2" ) , "Value1:Value2" ); + test_assert_string_equal( hash_get( h , "Key3" ) , "Value1:value2:Value3" ); + + test_assert_false( hash_has_key( h , "Key" )); + + hash_free( h ); + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_latex_test.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_latex_test.c index ae87d99bdf..a3e8f6114c 100644 --- a/ThirdParty/Ert/devel/libert_util/tests/ert_util_latex_test.c +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_latex_test.c @@ -20,21 +20,77 @@ #include #include +#include +#include + +void make_file( const char * filename ) { + FILE * stream = util_fopen( filename , "w"); + + fclose(stream); +} + + +void test_link( const latex_type * latex , const char * link , const char * target) { + char * latex_link = util_alloc_filename( latex_get_runpath( latex ) , link , NULL); + char * latex_target = util_alloc_link_target( latex_link ); + + test_assert_true( util_same_file( target , latex_target)); + + free( latex_link ); + free( latex_target); +} + + + +void test_latex_link( latex_type * latex ) { + const char * path = "/tmp/linkFarm"; + const char * file1 = util_alloc_filename( path , "File1" , NULL ); + const char * file2 = util_alloc_filename( path , "File2" , NULL ); + const char * file3 = util_alloc_filename( path , "File3" , NULL ); + + + util_make_path( path ); + make_file( file1 ); + make_file( file2 ); + make_file( file3 ); + + latex_link_path( latex , path ); + latex_link_directory_content( latex , path ); + + test_link( latex , "File1" , file1); + test_link( latex , "File2" , file2); + test_link( latex , "File3" , file3); + test_link( latex , "linkFarm" , path); + + util_clear_directory( path , true , true ); +} + int main(int argc , char ** argv) { bool ok; + { + bool in_place = false; + latex_type * latex = latex_alloc( argv[1] , in_place); + ok = latex_compile( latex , true , true , true); + test_assert_true( in_place == latex_compile_in_place( latex )); + latex_free( latex ); + test_assert_true( ok ); + } + + { latex_type * latex = latex_alloc( argv[1] , false ); - printf("input:%s \n",argv[1]); - ok = latex_compile( latex , true , true ); - printf("OK: %d \n",ok); + test_latex_link( latex ); latex_free( latex ); } - if (ok) - exit(0); - else - exit(1); + { + bool in_place = true; + latex_type * latex = latex_alloc( argv[1] , in_place); + test_assert_true( in_place == latex_compile_in_place( latex )); + test_latex_link( latex ); + latex_free( latex ); + } } diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_logh.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_logh.c new file mode 100644 index 0000000000..3c8347b33e --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_logh.c @@ -0,0 +1,46 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ert_util_logh.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include + +#define LOG_FILE "/tmp/log.txt" + +int main(int argc , char ** argv) { + int log_level = 3; + + { + log_type * logh = log_open( NULL , 0 ); + + test_assert_false( log_is_open( logh )); + log_reopen( logh , LOG_FILE ); + test_assert_true( log_is_open( logh )); + + log_close( logh ); + } + + { + log_type * logh = log_open( LOG_FILE , 0 ); + test_assert_true( log_is_open( logh )); + log_close( logh ); + } + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_path_stack_test.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_path_stack_test.c new file mode 100644 index 0000000000..eecadb5a0c --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_path_stack_test.c @@ -0,0 +1,81 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_path_stack_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + + +#include +#include +#include +#include + + + + +int main(int argc , char ** argv) { + char * cwd = util_alloc_cwd( ); + char * path1 = argv[1]; + char * path2 = argv[2]; + { + path_stack_type * path_stack = path_stack_alloc(); + + path_stack_push_cwd( path_stack ); + + if (path_stack_push( path_stack , "NotExist-1111")) + test_error_exit("Pushed unexisting path\n"); + + if (!path_stack_push( path_stack, path1 )) + test_error_exit("Failed to push:%s \n",path1 ); + + chdir( path2 ); + if (util_is_cwd( path1 )) + test_error_exit("Failed to chdir(%s) \n",path2 ); + + { + if (path_stack_size( path_stack ) != 2) + test_error_exit("Wrong stack size"); + + if (strcmp( path1 , path_stack_peek( path_stack )) != 0) + test_error_exit("peek error"); + } + + path_stack_pop( path_stack ); + printf("After pop: cwd:%s path1:%s \n",util_alloc_cwd() , path1); + if (!util_is_cwd( path1 )) + test_error_exit("path_stack_pop failed \n"); + + path_stack_pop( path_stack ); + if (!util_is_cwd( cwd )) + test_error_exit("path_stack_pop failed \n"); + + if (path_stack_size( path_stack ) != 0) + test_error_exit("Wrong stack size"); + + if (!path_stack_push(path_stack , NULL)) + test_error_exit("Hmmm - push(NULL) failed \n"); + + if (path_stack_size( path_stack ) != 1) + test_error_exit("Wrong stack size"); + + path_stack_pop( path_stack ); + path_stack_free( path_stack); + } + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_ping.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_ping.c new file mode 100644 index 0000000000..5b0a31876b --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_ping.c @@ -0,0 +1,41 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_ping.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include + + + +int main( int argc , char ** argv) { + stringlist_type * server_list = stringlist_alloc_from_split( argv[1] , " "); + argc = stringlist_get_size( server_list ); + + if (argc >= 1) + test_assert_true( util_ping( stringlist_iget( server_list , 0 ))); + + if (argc >= 2) + test_assert_false( util_ping( stringlist_iget( server_list , 1 ))); + + if (argc >= 3) + test_assert_false( util_ping( stringlist_iget( server_list , 2 ))); + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_realpath.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_realpath.c new file mode 100644 index 0000000000..c42adf6108 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_realpath.c @@ -0,0 +1,52 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ert_util_realpath.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include + +void test_path(const char * input , const char * expected) { + char * rpath = util_alloc_realpath__( input ); + if (!test_string_equal( rpath , expected )) + test_error_exit("util_alloc_realpath__(%s) => %s expected:%s \n",input , rpath , expected); + else + printf("OK: %s -> %s \n",input , rpath); + + free( rpath ); +} + + + +int main( int argc , char ** argv) { +#ifdef ERT_LINUX + + test_path("/tmp/" , "/tmp" ); + test_path("/tmp/test/normal" , "/tmp/test/normal" ); + test_path("/tmp/test/../test/normal" , "/tmp/test/normal"); + test_path("/tmp/test/../../tmp/test/normal" , "/tmp/test/normal"); + test_path("/tmp/test/../../tmp//test/normal" , "/tmp/test/normal"); + test_path("/tmp/test/../../tmp/./test/normal" , "/tmp/test/normal"); + test_path("/tmp/test/../../tmp/./test/normal/" , "/tmp/test/normal"); + test_path("/tmp/test/../../tmp/other/XX/" , "/tmp/other/XX"); + +#endif + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_relpath_test.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_relpath_test.c new file mode 100644 index 0000000000..0eac93bf9a --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_relpath_test.c @@ -0,0 +1,88 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_relpath_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include +#include + + +void test_path(int nr , const char * root , const char * path , const char * true_path) { + char * rel_path = util_alloc_rel_path( root , path); + + if (!test_string_equal( rel_path , true_path)) + test_error_exit("Case:%d rel_path(%s,%s) -> %s failed - expected: %s\n" , nr , root , path , rel_path , true_path); + else + printf("Case:%d OK \n",nr); + + util_safe_free( rel_path ); +} + +int main(int argc , char ** argv) { +#ifdef ERT_LINUX + const char * root1 = "/tmp/root/path"; + const char * path1 = "/tmp/root/path/relative"; + const char * true1 = "relative"; + + const char * root2 = "/tmp/root/path/"; + const char * path2 = "/tmp/root/path/relative"; + const char * true2 = "relative"; + + const char * root3 = "/tmp/root/path"; + const char * path3 = "/tmp/root/"; + const char * true3 = "../"; + + const char * root4 = "/tmp/root/path"; + const char * path4 = "relative"; + const char * true4 = "relative"; + + const char * root5 = "/tmp/root/path"; + const char * path5 = "/tmp/root/pathX/relative"; + const char * true5 = "../pathX/relative"; + + const char * root6 = "/tmp/root/path"; + const char * path6 = "/tmpX/root/pathX/relative"; + const char * true6 = "../../../tmpX/root/pathX/relative"; + + const char * root7 = "/tmp/root/path"; + const char * path7 = "/tmp/root/path"; + const char * true7 = NULL; + + const char * root8 = "/tmp"; + const char * path8 = "root/path"; + const char * true8 = "root/path"; + +#endif + + test_path( 1 , root1 , path1 , true1 ); + test_path( 2 , root2 , path2 , true2 ); + test_path( 3 , root3 , path3 , true3 ); + test_path( 4 , root4 , path4 , true4 ); + test_path( 5 , root5 , path5 , true5 ); + test_path( 6 , root6 , path6 , true6 ); + test_path( 7 , root7 , path7 , true7 ); + { + chdir(root8); + test_path( 8 , NULL , path8 , true8 ); + } + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_rng.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_rng.c new file mode 100644 index 0000000000..8096c031e6 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_rng.c @@ -0,0 +1,71 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ert_util_rng.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include +#include + + +#define MAX_INT 666661 + +int main(int argc , char ** argv) { + rng_type * rng = rng_alloc( MZRAN , INIT_DEFAULT ); + { + int val1 = rng_get_int( rng , MAX_INT); + int val2 = rng_get_int( rng , MAX_INT); + + test_assert_int_not_equal( val1 , val2 ); + + rng_init( rng , INIT_DEFAULT ); + val2 = rng_get_int( rng , MAX_INT ); + test_assert_int_equal( val1 , val2 ); + } + { + int val2 , val1; + int state_size = rng_state_size( rng ); + char * buffer1 = util_calloc( state_size , sizeof * buffer1 ); + char * buffer2 = util_calloc( state_size , sizeof * buffer2 ); + test_assert_int_not_equal( state_size , 0 ); + test_assert_int_equal( state_size , MZRAN_STATE_SIZE ); + + rng_init( rng , INIT_DEFAULT ); + rng_get_state( rng , buffer1 ); + val1 = rng_get_int( rng , MAX_INT); + val2 = rng_get_int( rng , MAX_INT); + + test_assert_int_not_equal( val1 , val2 ); + rng_set_state( rng , buffer1 ); + val2 = rng_get_int( rng , MAX_INT); + test_assert_int_equal( val1 , val2 ); + + rng_init( rng , INIT_DEFAULT ); + rng_get_state( rng , buffer2 ); + test_assert_mem_equal( buffer1 , buffer2 , state_size ); + val2 = rng_get_int( rng , MAX_INT); + rng_get_state( rng , buffer2 ); + test_assert_mem_not_equal( buffer1 , buffer2 , state_size ); + + free( buffer1 ); + free( buffer2 ); + } + rng_free( rng ); + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_sprintf_escape.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_sprintf_escape.c new file mode 100644 index 0000000000..0496ea72d3 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_sprintf_escape.c @@ -0,0 +1,39 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_sprintf_escape.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include + + + +int main(int argc , char ** argv) { + test_assert_string_equal( NULL , util_alloc_sprintf_escape( NULL , 0)); + test_assert_string_equal( "String", util_alloc_sprintf_escape( "String" , 0)); + test_assert_string_equal( "String", util_alloc_sprintf_escape( "String" , 10)); + + test_assert_string_equal( "S%%tring%%", util_alloc_sprintf_escape( "S%tring%" , 0)); + test_assert_string_equal( "S%%tring%%", util_alloc_sprintf_escape( "S%tring%" , 2)); + test_assert_string_equal( "S%%tring%%", util_alloc_sprintf_escape( "S%tring%" , 10)); + test_assert_string_equal( "S%%tring%" , util_alloc_sprintf_escape( "S%tring%" , 1)); + test_assert_string_equal( "%%%%" , util_alloc_sprintf_escape( "%%" , 0)); + test_assert_string_equal( "%%%%" , util_alloc_sprintf_escape( "%%%" , 1)); + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_strcat_test.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_strcat_test.c new file mode 100644 index 0000000000..e022fc51d1 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_strcat_test.c @@ -0,0 +1,55 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_strcat_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include +#include + + +void test_strcat(char * s1 , const char *s2 , const char * expected) { + char * cat = util_strcat_realloc(s1 , s2 ); + if (test_string_equal( cat , expected )) + util_safe_free( cat ); + else + test_error_exit("util_strcat_realloc(%s,%s) Got:%s expected:%s \n",s1,s2,cat , expected); +} + + +int main(int argc , char ** argv) { + test_strcat(NULL , NULL , NULL); + + { + const char * s = "Hei"; + test_strcat(NULL, util_alloc_string_copy(s) , s); + } + { + const char * s = "Hei"; + test_strcat(util_alloc_string_copy(s) , NULL , s); + } + { + char * s1 = util_alloc_string_copy("hei"); + char * s2 = util_alloc_string_copy("-Hei"); + test_strcat(s1,s2 , "hei-Hei"); + } + + printf("Test OK\n"); + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_string_util.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_string_util.c new file mode 100644 index 0000000000..6700549b2e --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_string_util.c @@ -0,0 +1,106 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_string_util.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include +#include +#include +#include + + +static void test1( const int_vector_type * active_list ) { + test_assert_int_equal( int_vector_size( active_list ), 10 ); + test_assert_int_equal( int_vector_iget( active_list , 0 ) , 1 ); + test_assert_int_equal( int_vector_iget( active_list , 1 ) , 3); + test_assert_int_equal( int_vector_iget( active_list , 8 ) ,10 ); + test_assert_int_equal( int_vector_iget( active_list , 9 ) ,15 ); +} + + +void test_active_list() { + int_vector_type * active_list = string_util_alloc_active_list("1,3- 10,15"); + test_assert_true( string_util_init_active_list("1,3- 10,15" , active_list) ); + test1( active_list ); + + test_assert_true( string_util_update_active_list("1,3- 10,15,8" , active_list) ); + test1( active_list ); + test_assert_false( string_util_update_active_list("1,X" , active_list) ); + test1( active_list ); + + test_assert_true( string_util_update_active_list("14-16" , active_list) ); + test_assert_int_equal( int_vector_size( active_list ) , 12); + test_assert_int_equal( int_vector_iget( active_list , 9 ) ,14 ); + test_assert_int_equal( int_vector_iget( active_list , 11 ) ,16 ); + + test_assert_true( string_util_update_active_list("0" , active_list) ); + test_assert_int_equal( int_vector_size( active_list ) , 13); + test_assert_int_equal( int_vector_iget( active_list , 0 ) ,0 ); + test_assert_int_equal( int_vector_iget( active_list , 10 ) ,14 ); + test_assert_int_equal( int_vector_iget( active_list , 12 ) ,16 ); + + test_assert_true( string_util_update_active_list("4-6" , active_list) ); + test_assert_int_equal( int_vector_size( active_list ) , 13); + test_assert_int_equal( int_vector_iget( active_list , 0 ) ,0 ); + test_assert_int_equal( int_vector_iget( active_list , 10 ) ,14 ); + test_assert_int_equal( int_vector_iget( active_list , 12 ) ,16 ); +} + + +static void test2( const bool_vector_type * active_mask ) { + test_assert_int_equal( bool_vector_size( active_mask ), 16 ); + + test_assert_true( bool_vector_iget( active_mask , 1 )); + test_assert_true( bool_vector_iget( active_mask , 3 )); + test_assert_true( bool_vector_iget( active_mask , 4 ) ); + test_assert_true( bool_vector_iget( active_mask , 9 )); + test_assert_true( bool_vector_iget( active_mask , 10 )); + test_assert_true( bool_vector_iget( active_mask , 15 )); + + test_assert_false( bool_vector_iget( active_mask , 0 )); + test_assert_false( bool_vector_iget( active_mask , 2 )); + test_assert_false( bool_vector_iget( active_mask , 11 )); + test_assert_false( bool_vector_iget( active_mask , 14 )); +} + + + +void test_active_mask() { + bool_vector_type * active_mask = string_util_alloc_active_mask("1,3 -6,6- 10, 15"); + + test2( active_mask ); + test_assert_true( string_util_init_active_mask("1,3- 10,15" , active_mask)); + test2( active_mask ); + + test_assert_false( string_util_update_active_mask("11,X" , active_mask)); + test2( active_mask ); + + bool_vector_free( active_mask ); + + + +} + + + + +int main(int argc , char ** argv) { + test_active_list(); + test_active_mask(); + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_stringlist_test.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_stringlist_test.c index a7b4624100..c56706e9f7 100644 --- a/ThirdParty/Ert/devel/libert_util/tests/ert_util_stringlist_test.c +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_stringlist_test.c @@ -18,7 +18,7 @@ #include #include -//#include +#include #include void test_char() { @@ -48,7 +48,57 @@ void test_char() { +void test_reverse() { + const char *s0 = "AAA"; + const char *s1 = "BBB"; + const char *s2 = "CCC"; + + stringlist_type * s = stringlist_alloc_new(); + stringlist_append_ref( s , s0 ); + stringlist_append_ref( s , s1 ); + stringlist_append_ref( s , s2 ); + + stringlist_reverse(s); + + test_assert_string_equal( s2 , stringlist_iget(s , 0 )); + test_assert_string_equal( s1 , stringlist_iget(s , 1 )); + test_assert_string_equal( s0 , stringlist_iget(s , 2 )); +} + + +void test_iget_as_int() { + stringlist_type * s = stringlist_alloc_new(); + stringlist_append_ref(s , "1000" ); + stringlist_append_ref(s , "1000X" ); + stringlist_append_ref(s , "XXXX" ); + + { + int value; + bool valid; + + value = stringlist_iget_as_int( s , 0 , &valid); + test_assert_int_equal( value , 1000); + test_assert_true( valid ); + + value = stringlist_iget_as_int( s , 1 , &valid); + test_assert_int_equal( value , -1); + test_assert_false( valid ); + + value = stringlist_iget_as_int( s , 2 , NULL); + test_assert_int_equal( value , -1); + } +} + +void test_empty() { + stringlist_type * s = stringlist_alloc_new(); + stringlist_fprintf( s , "\n" , stdout ); +} + + int main( int argc , char ** argv) { + test_empty(); test_char(); + test_reverse(); + test_iget_as_int(); exit(0); } diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_time_interval.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_time_interval.c new file mode 100644 index 0000000000..0a733466f0 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_time_interval.c @@ -0,0 +1,245 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_time_interval.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include +#include + + + +int main( int argc , char ** argv) { + time_t start_time = util_make_date(1,1,2000); + time_t end_time = util_make_date(1,1,2010); + time_t in = util_make_date( 1,1,2005); + time_t before = util_make_date( 1,1,1995); + time_t after = util_make_date( 1,1,2015); + + { + time_interval_type * ti = time_interval_alloc( start_time , end_time ); + test_assert_not_NULL( ti ); + test_assert_false( time_interval_is_empty( ti )); + + test_assert_true( time_interval_contains( ti , start_time )); + test_assert_true( time_interval_contains( ti , in )); + test_assert_false( time_interval_contains( ti , before )); + test_assert_false( time_interval_contains( ti , end_time )); + test_assert_false( time_interval_contains( ti , after )); + + test_assert_false( time_interval_update( ti , end_time , start_time )); + test_assert_true( time_interval_is_empty( ti )); + + test_assert_false( time_interval_contains( ti , start_time )); + test_assert_false( time_interval_contains( ti , in )); + test_assert_false( time_interval_contains( ti , before )); + test_assert_false( time_interval_contains( ti , end_time )); + test_assert_false( time_interval_contains( ti , after )); + + test_assert_true( time_interval_update( ti , start_time , end_time )); + test_assert_false( time_interval_is_empty( ti )); + + time_interval_free( ti ); + } + + { + time_interval_type * ti = time_interval_alloc( end_time , start_time ); + test_assert_not_NULL( ti ); + test_assert_true( time_interval_is_empty( ti )); + test_assert_true( time_interval_update( ti , start_time , end_time )); + test_assert_false( time_interval_is_empty( ti )); + time_interval_free( ti ); + } + + { + time_interval_type * t1 = time_interval_alloc( start_time , end_time ); + time_interval_type * t2 = time_interval_alloc( in , after ); + time_interval_type * t3 = time_interval_alloc( end_time , start_time ); + time_interval_type * t4 = time_interval_alloc( before , start_time ); + time_interval_type * t5 = time_interval_alloc( end_time , after ); + + test_assert_true( time_interval_has_overlap( t1 , t2 )); + + test_assert_true( time_interval_is_empty( t3 )); + test_assert_false( time_interval_has_overlap( t1 , t3 )); + test_assert_false( time_interval_has_overlap( t3 , t1 )); + test_assert_false( time_interval_has_overlap( t3 , t3 )); + test_assert_false( time_interval_has_overlap( t4 , t5 )); + test_assert_false( time_interval_has_overlap( t1 , t5 )); + + + time_interval_free( t1 ); + time_interval_free( t2 ); + } + + { + time_interval_type * ti = time_interval_alloc_open(); + + test_assert_false( time_interval_is_empty( ti )); + + test_assert_true( time_interval_contains( ti , start_time )); + test_assert_true( time_interval_contains( ti , in )); + test_assert_true( time_interval_contains( ti , before )); + test_assert_true( time_interval_contains( ti , end_time )); + test_assert_true( time_interval_contains( ti , after )); + + test_assert_true( time_interval_update_start( ti , start_time )); + test_assert_true( time_interval_contains( ti , start_time )); + test_assert_true( time_interval_update_start( ti , in )); + test_assert_false( time_interval_contains( ti , start_time )); + test_assert_false( time_interval_is_empty( ti )); + + test_assert_false( time_interval_update_end( ti , start_time )); + test_assert_true( time_interval_is_empty( ti )); + test_assert_true( time_interval_update_end( ti , end_time )); + test_assert_false( time_interval_is_empty( ti )); + test_assert_false( time_interval_contains( ti , start_time )); + + time_interval_free( ti ); + } + + { + time_interval_type * t1 = time_interval_alloc( start_time , end_time ); + + test_assert_time_t_equal( start_time , time_interval_get_start( t1 )); + test_assert_time_t_equal( end_time , time_interval_get_end( t1 )); + test_assert_false( time_interval_is_empty( t1 )); + + test_assert_false( time_interval_update_end( t1 , before )); + test_assert_true( time_interval_is_empty( t1 )); + test_assert_time_t_equal( start_time , time_interval_get_start( t1 )); + test_assert_time_t_equal( before , time_interval_get_end( t1 )); + + test_assert_true( time_interval_update_end( t1 , in )); + test_assert_false( time_interval_is_empty( t1 )); + test_assert_time_t_equal( start_time , time_interval_get_start( t1 )); + test_assert_time_t_equal( in , time_interval_get_end( t1 )); + + time_interval_free( t1 ); + } + + { + time_interval_type * t1 = time_interval_alloc( start_time , in ); + time_interval_type * t2 = time_interval_alloc( in , end_time ); + time_interval_type * t3 = time_interval_alloc( start_time , end_time); + + test_assert_true( time_interval_is_adjacent( t1 , t2 )); + test_assert_true( time_interval_is_adjacent( t2 , t1 )); + + test_assert_false( time_interval_is_adjacent( t1 , t3 )); + test_assert_false( time_interval_is_adjacent( t3 , t1 )); + test_assert_false( time_interval_is_adjacent( t2 , t3 )); + test_assert_false( time_interval_is_adjacent( t3 , t2 )); + + time_interval_free( t1 ); + time_interval_free( t2 ); + time_interval_free( t3 ); + } + + + + { + time_interval_type * t1 = time_interval_alloc( start_time , end_time ); + time_interval_type * t2 = time_interval_alloc( in , end_time ); + time_interval_type * t3 = time_interval_alloc( end_time , after ); + time_interval_type * t4 = time_interval_alloc( before , start_time ); + + test_assert_true( time_interval_extend(t1 , t2 )); + test_assert_time_t_equal( start_time , time_interval_get_start( t1 )); + test_assert_time_t_equal( end_time , time_interval_get_end( t1 )); + + test_assert_true( time_interval_extend(t1 , t3 )); + test_assert_time_t_equal( start_time , time_interval_get_start( t1 )); + test_assert_time_t_equal( after , time_interval_get_end( t1 )); + + test_assert_true( time_interval_update_start(t1 , in )); + test_assert_time_t_equal( in , time_interval_get_start( t1 )); + + + test_assert_false( time_interval_extend(t1 , t4 )); + test_assert_time_t_equal( in , time_interval_get_start( t1 )); + test_assert_time_t_equal( after , time_interval_get_end( t1 )); + + + test_assert_true( time_interval_update_end(t4 , in )); + test_assert_true( time_interval_extend(t1 , t4 )); + test_assert_time_t_equal( before , time_interval_get_start( t1 )); + test_assert_time_t_equal( after , time_interval_get_end( t1 )); + + + time_interval_free( t1 ); + time_interval_free( t2 ); + time_interval_free( t3 ); + time_interval_free( t4 ); + } + + { + time_interval_type * t1 = time_interval_alloc( start_time , end_time ); + time_interval_type * t2 = time_interval_alloc( in , end_time ); + time_interval_type * t3 = time_interval_alloc( end_time , after ); + time_interval_type * t4 = time_interval_alloc( before , start_time ); + + test_assert_true( time_interval_intersect(t1 , t2 )); + test_assert_time_t_equal( in , time_interval_get_start( t1 )); + test_assert_time_t_equal( end_time , time_interval_get_end( t1 )); + + time_interval_free( t1 ); + time_interval_free( t2 ); + time_interval_free( t3 ); + time_interval_free( t4 ); + } + + { + time_interval_type * t1 = time_interval_alloc( start_time , end_time ); + time_interval_type * t2 = time_interval_alloc( start_time , end_time ); + time_interval_type * t3 = time_interval_alloc( end_time , after ); + time_interval_type * t4 = time_interval_alloc_copy( t1 ); + + test_assert_true( time_interval_equal( t1 , t2 )); + test_assert_false( time_interval_equal( t1 , t3 )); + + test_assert_true( time_interval_equal( t4 , t2 )); + test_assert_false( time_interval_equal( t4 , t3 )); + + test_assert_ptr_not_equal( t4 , t1 ); + time_interval_free( t1 ); + time_interval_free( t2 ); + time_interval_free( t3 ); + time_interval_free( t4 ); + } + + { + time_interval_type * t1 = time_interval_alloc( start_time , end_time ); + + test_assert_true( time_interval_arg_before( t1 , before )); + test_assert_true( time_interval_arg_after( t1 , after)); + + test_assert_false( time_interval_arg_before( t1 , start_time )); + test_assert_false( time_interval_arg_before( t1 , in )); + test_assert_false( time_interval_arg_before( t1 , after )); + + test_assert_false( time_interval_arg_after( t1 , start_time)); + test_assert_false( time_interval_arg_after( t1 , in)); + test_assert_true( time_interval_arg_after( t1 , after)); + + time_interval_free( t1 ); + } + + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_type_vector_test.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_type_vector_test.c index e9e2447909..a231320461 100644 --- a/ThirdParty/Ert/devel/libert_util/tests/ert_util_type_vector_test.c +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_type_vector_test.c @@ -19,6 +19,7 @@ #include #include +#include void assert_equal( bool equal ) { if (!equal) @@ -42,6 +43,37 @@ int main(int argc , char ** argv) { assert_equal( int_vector_iget(int_vector , 4 ) == 99 ); assert_equal( int_vector_iget(int_vector , 5 ) == -10 ); + { + int N1 = 100000; + int N2 = 10*N1; + int_vector_type * v1 = int_vector_alloc( N1 , 0 ); + int_vector_type * v2; + int * data1 = int_vector_get_ptr( v1 ); + int_vector_iset( v1 , N1 - 1, 99); + + int_vector_free_container( v1 ); + v2 = int_vector_alloc( N2 , 0 ); + int_vector_iset(v2 , N2 - 1, 77 ); + + test_assert_int_equal( data1[N1-1] , 99); + int_vector_free( v2 ); + free( data1 ); + } + + + test_assert_true( int_vector_init_range( int_vector , 100 , 1000 , 115 ) ); + test_assert_int_equal( int_vector_iget( int_vector , 0 ) , 100); + test_assert_int_equal( int_vector_iget( int_vector , 1 ) , 215); + test_assert_int_equal( int_vector_iget( int_vector , 2 ) , 330); + test_assert_int_equal( int_vector_iget( int_vector , 3 ) , 445); + test_assert_int_equal( int_vector_get_last( int_vector ) , 1000); + + test_assert_false( int_vector_init_range( int_vector , 100 , -1000 , 115 ) ); + test_assert_int_equal( int_vector_iget( int_vector , 0 ) , 100); + test_assert_int_equal( int_vector_iget( int_vector , 1 ) , 215); + test_assert_int_equal( int_vector_iget( int_vector , 2 ) , 330); + test_assert_int_equal( int_vector_iget( int_vector , 3 ) , 445); + test_assert_int_equal( int_vector_get_last( int_vector ) , 1000); exit(0); } diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_vector_test.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_vector_test.c index c68d64c911..29a22eeffb 100644 --- a/ThirdParty/Ert/devel/libert_util/tests/ert_util_vector_test.c +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_vector_test.c @@ -19,29 +19,61 @@ #include #include +#include -void assert_equal( bool equal ) { - if (!equal) - exit(1); -} int test_iset( ) { - vector_type * vector = vector_alloc_new( 0 ); + vector_type * vector = vector_alloc_new( ); vector_iset_ref( vector , 2 , vector ); + - assert_equal( vector_get_size( vector ) == 3 ); - assert_equal( vector_iget( vector , 0 ) == NULL ); - assert_equal( vector_iget( vector , 1 ) == NULL ); - assert_equal( vector_iget( vector , 2 ) == vector ); + test_assert_true( vector_get_size( vector ) == 3 ); + test_assert_true( vector_iget( vector , 0 ) == NULL ); + test_assert_true( vector_iget( vector , 1 ) == NULL ); + test_assert_true( vector_iget( vector , 2 ) == vector ); vector_free( vector ); return 0; } +void test_reverse() { + const char * val1 = "value1"; + const char * val2 = "value2"; + const char * val3 = "value3"; + const char * val4 = "value4"; + + vector_type * vector1 = vector_alloc_new( ); + vector_type * vector2 = vector_alloc_new( ); + + vector_append_ref( vector1 , val1 ); + vector_append_ref( vector1 , val2 ); + vector_append_ref( vector1 , val3 ); + vector_append_ref( vector1 , val4 ); + + vector_append_ref( vector2 , val1 ); + vector_append_ref( vector2 , val2 ); + vector_append_ref( vector2 , val3 ); + vector_append_ref( vector2 , val4 ); + + vector_inplace_reverse( vector1 ); + + { + int i; + int size = vector_get_size( vector1 ); + for (i=0; i < vector_get_size( vector1 ); i++) + test_assert_ptr_equal( vector_iget_const( vector2 , i ) , vector_iget_const( vector1 , size - 1 - i )); + } + vector_free( vector1 ); + vector_free( vector2 ); +} + + + + int main(int argc , char ** argv) { test_iset( ); - + test_reverse( ); exit(0); } diff --git a/ThirdParty/Ert/devel/libgeometry/src/CMakeLists.txt b/ThirdParty/Ert/devel/libgeometry/src/CMakeLists.txt index 223ca9976b..cc1391ab09 100644 --- a/ThirdParty/Ert/devel/libgeometry/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libgeometry/src/CMakeLists.txt @@ -7,9 +7,11 @@ target_link_libraries( ert_geometry ert_util ) #----------------------------------------------------------------- -install(TARGETS ert_geometry DESTINATION ${CMAKE_INSTALL_LIBDIR}) -foreach(header ${header_files}) - install(FILES ../include/ert/geometry/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/geometry) -endforeach() +if (INSTALL_ERT) + install(TARGETS ert_geometry DESTINATION ${CMAKE_INSTALL_LIBDIR}) + foreach(header ${header_files}) + install(FILES ../include/ert/geometry/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/geometry) + endforeach() +endif() diff --git a/ThirdParty/Ert/devel/libjob_queue/CMakeLists.txt b/ThirdParty/Ert/devel/libjob_queue/CMakeLists.txt index 22c9ef1cec..159c0c64e8 100644 --- a/ThirdParty/Ert/devel/libjob_queue/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libjob_queue/CMakeLists.txt @@ -1,4 +1,5 @@ if (USE_LSF) + set( HAVE_LSF_LIBRARY ON ) set( LSF_INCLUDE_PATH $ENV{LSF_INCLUDE_PATH} CACHE FILEPATH "Path to LSF header files") set( LSF_LIB_PATH $ENV{LSF_HOME}/lib CACHE FILEPATH "Path to LSF library files") @@ -7,20 +8,19 @@ if (USE_LSF) find_library( LSF_LIBRARY NAMES lsf PATHS ${LSF_LIB_PATH}) if (NOT DEFINED LSF_HEADER) - set( USE_LSF OFF) + set( HAVE_LSF_LIBRARY OFF) endif() if (NOT DEFINED LSF_LIBRARY) - set( USE_LSF OFF ) + set( HAVE_LSF_LIBRARY OFF ) + endif() + + if (HAVE_LSF_LIBRARY) + include_directories( ${LSF_INCLUDE_PATH} ) + add_definitions( -DHAVE_LSF_LIBRARY ) endif() endif() -if (USE_LSF) - set( HAVE_LSF ON ) - add_definitions( -DHAVE_LSF ) -endif() - -include_directories( ${LSF_INCLUDE_PATH} ) add_subdirectory( src ) if (BUILD_APPLICATONS) diff --git a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/ext_cmd.h b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/ext_cmd.h deleted file mode 100644 index 0414011e1e..0000000000 --- a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/ext_cmd.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ext_cmd.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT 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. - - ERT 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. -*/ - -#ifndef __EXT_CMD_H__ -#define __EXT_CMD_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - - - typedef struct ext_cmd_struct ext_cmd_type; - - bool ext_cmd_internal( const ext_cmd_type * ext_cmd ); - config_type * ext_cmd_alloc_config(); - ext_cmd_type * ext_cmd_alloc(bool internal); - void ext_cmd_free( ext_cmd_type * ext_cmd ); - void ext_cmd_free__( void * arg); - void ext_cmd_set_executable( ext_cmd_type * ext_cmd , const char * executable ); - ext_cmd_type * ext_cmd_config_alloc( config_type * config , const char * config_file); - - void ext_cmd_set_executable( ext_cmd_type * ext_cmd , const char * executable); - void ext_cmd_set_function( ext_cmd_type * ext_cmd , const char * function); - void ext_cmd_set_module( ext_cmd_type * ext_cmd , const char * module); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/lsb.h b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/lsb.h new file mode 100644 index 0000000000..0b42edf899 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/lsb.h @@ -0,0 +1,56 @@ +/* + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'lsb.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + + +#ifndef __LSB_H__ +#define __LSB_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +#include + + typedef struct lsb_struct lsb_type; + + + lsb_type * lsb_alloc(); + void lsb_free( lsb_type * lsb); + bool lsb_ready( const lsb_type * lsb); + + int lsb_initialize( const lsb_type * lsb); + int lsb_submitjob( const lsb_type * lsb , struct submit * , struct submitReply *); + int lsb_killjob( const lsb_type * lsb , int lsf_jobnr); + int lsb_openjob( const lsb_type * lsb , int lsf_jobnr); + struct jobInfoEnt * lsb_readjob( const lsb_type * lsb ); + int lsb_closejob( const lsb_type * lsb ); + char * lsb_sys_msg( const lsb_type * lsb ); + stringlist_type * lsb_get_error_list( const lsb_type * lsb ); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/lsf_driver.h b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/lsf_driver.h index 6362f6aa6c..5adf0c2b06 100644 --- a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/lsf_driver.h +++ b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/lsf_driver.h @@ -39,6 +39,8 @@ extern "C" { #define LSF_BKILL_CMD "BKILL_CMD" #define LOCAL_LSF_SERVER "LOCAL" +#define NULL_LSF_SERVER "NULL" + typedef enum { LSF_SUBMIT_INVALID = 0, diff --git a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/workflow.h b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/workflow.h new file mode 100644 index 0000000000..eb10d65bac --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/workflow.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'workflow.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + +#ifndef __WORKFLOW_H__ +#define __WORKFLOW_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +#include + + typedef struct workflow_struct workflow_type; + + const config_error_type * workflow_get_last_error( const workflow_type * workflow); + workflow_type * workflow_alloc( const char * src_file , workflow_joblist_type * joblist); + bool workflow_run( workflow_type * workflow , void * self , bool verbose , const subst_list_type * context); + void workflow_free( workflow_type * workflow ); + void workflow_free__( void * arg ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/workflow_job.h b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/workflow_job.h new file mode 100644 index 0000000000..f6b7442864 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/workflow_job.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'workflow_job.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + +#ifndef __WORKFLOW_JOB_H__ +#define __WORKFLOW_JOB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + + typedef void (workflow_job_ftype) (void * self , const stringlist_type * arg ); + typedef struct workflow_job_struct workflow_job_type; + + const char * workflow_job_get_name( const workflow_job_type * workflow_job ); + bool workflow_job_internal( const workflow_job_type * workflow_job ); + config_type * workflow_job_alloc_config(); + workflow_job_type * workflow_job_alloc(const char * name , bool internal); + void workflow_job_free( workflow_job_type * workflow_job ); + void workflow_job_free__( void * arg); + void workflow_job_set_executable( workflow_job_type * workflow_job , const char * executable ); + workflow_job_type * workflow_job_config_alloc( const char * name , config_type * config , const char * config_file); + + void workflow_job_update_config_compiler( const workflow_job_type * workflow_job , config_type * config_compiler ); + void workflow_job_set_executable( workflow_job_type * workflow_job , const char * executable); + void workflow_job_set_function( workflow_job_type * workflow_job , const char * function); + void workflow_job_set_module( workflow_job_type * workflow_job , const char * module); + void workflow_job_run( const workflow_job_type * job , void * self , bool verbose , const stringlist_type * arg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/workflow_joblist.h b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/workflow_joblist.h new file mode 100644 index 0000000000..3102d72c63 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/workflow_joblist.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'workflow_joblist.h' is part of ERT - Ensemble based + Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + + + +#ifndef __WORKFLOW_JOBLIST_H__ +#define __WORKFLOW_JOBLIST_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef struct workflow_joblist_struct workflow_joblist_type; + + workflow_joblist_type * workflow_joblist_alloc(); + void workflow_joblist_free( workflow_joblist_type * joblist); + const workflow_job_type * workflow_joblist_get_job( const workflow_joblist_type * joblist , const char * job_name); + void workflow_joblist_add_job( workflow_joblist_type * joblist , const workflow_job_type * job); + bool workflow_joblist_add_job_from_file( workflow_joblist_type * joblist , const char * job_name , const char * config_file ); + config_type * workflow_joblist_get_compiler( const workflow_joblist_type * joblist ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/devel/libjob_queue/src/CMakeLists.txt b/ThirdParty/Ert/devel/libjob_queue/src/CMakeLists.txt index 171a098633..76e70e7845 100644 --- a/ThirdParty/Ert/devel/libjob_queue/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libjob_queue/src/CMakeLists.txt @@ -1,22 +1,29 @@ #configure_file (${CMAKE_CURRENT_SOURCE_DIR}/CMake/include/libjob_queue_build_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/libjob_queue_build_config.h) -set(source_files forward_model.c queue_driver.c job_queue.c lsf_driver.c local_driver.c rsh_driver.c ext_job.c ext_joblist.c ext_cmd.c) -set(header_files job_queue.h queue_driver.h lsf_driver.h local_driver.h rsh_driver.h ext_job.h ext_joblist.h forward_model.h ext_cmd.h) +set(source_files forward_model.c queue_driver.c job_queue.c local_driver.c rsh_driver.c ext_job.c ext_joblist.c workflow_job.c workflow.c workflow_joblist.c) +set(header_files job_queue.h queue_driver.h local_driver.h rsh_driver.h ext_job.h ext_joblist.h forward_model.h workflow_job.h workflow.h workflow_joblist.h) -add_library( job_queue ${LIBRARY_TYPE} ${source_files} ) +if (USE_LSF) + list( APPEND source_files lsf_driver.c) + list( APPEND header_files lsf_driver.h) + + if (HAVE_LSF_LIBRARY) + list( APPEND source_files lsb.c) + list( APPEND header_files lsb.h) + endif() +endif() + +add_library( job_queue SHARED ${source_files} ) set_target_properties( job_queue PROPERTIES VERSION 1.0 SOVERSION 1.0 ) - target_link_libraries( job_queue config ert_util ) -if (HAVE_LSF) - target_link_libraries( job_queue bat ${LSF_LIBRARY} nsl) -endif() if (NEED_LIBDL) target_link_libraries( job_queue dl ) endif() - -install(TARGETS job_queue DESTINATION ${CMAKE_INSTALL_LIBDIR}) -foreach(header ${header_files}) - install(FILES ../include/ert/job_queue/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/job_queue) -endforeach() +if (INSTALL_ERT) + install(TARGETS job_queue DESTINATION ${CMAKE_INSTALL_LIBDIR}) + foreach(header ${header_files}) + install(FILES ../include/ert/job_queue/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/job_queue) + endforeach() +endif() diff --git a/ThirdParty/Ert/devel/libjob_queue/src/ext_cmd.c b/ThirdParty/Ert/devel/libjob_queue/src/ext_cmd.c deleted file mode 100644 index cec99560bb..0000000000 --- a/ThirdParty/Ert/devel/libjob_queue/src/ext_cmd.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ext_cmd.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT 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. - - ERT 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 -#include -#include - -#include -#include -#include - -#include - -#include - - -/* The default values are interepreted as no limit. */ -#define ARG_MIN_DEFAULT -1 -#define ARG_MAX_DEFAULT -1 -#define DEFAULT_INTERNAL false - - -#define MIN_ARG_KEY "MIN_ARG" -#define MAX_ARG_KEY "MAX_ARG" -#define ARG_TYPE_KEY "ARG_TYPE" -#define INTERNAL_KEY "INTERNAL" -#define MODULE_KEY "MODULE" -#define FUNCTION_KEY "FUNCTION" -#define EXECUTABLE_KEY "EXECUTABLE" - -#define NULL_STRING "NULL" -#define EXT_CMD_STRING_TYPE "STRING" -#define EXT_CMD_INT_TYPE "INT" -#define EXT_CMD_FLOAT_TYPE "FLOAT" - -#define EXT_CMD_TYPE_ID 614441 - -struct ext_cmd_struct { - UTIL_TYPE_ID_DECLARATION; - bool internal; - int min_arg; - int max_arg; - int_vector_type * arg_types; // Should contain values from the config_item_types enum in config.h. - char * executable; - char * module; - char * function; - void * lib_handle; - void * dl_func; - bool valid; -}; - - -bool ext_cmd_internal( const ext_cmd_type * ext_cmd ) { - return ext_cmd->internal; -} - - -config_type * ext_cmd_alloc_config() { - config_type * config = config_alloc(); - { - config_schema_item_type * item; - - item = config_add_schema_item( config , MIN_ARG_KEY , false , false); - config_schema_item_set_argc_minmax( item , 1 , 1 , 1 , (const config_item_types[1]) {CONFIG_INT}); - - item = config_add_schema_item( config , MAX_ARG_KEY , false , false); - config_schema_item_set_argc_minmax( item , 1 , 1 , 1 , (const config_item_types[1]) {CONFIG_INT}); - - item = config_add_schema_item( config , ARG_TYPE_KEY , false , true ); - config_schema_item_set_argc_minmax( item , 2 , 2 , 2 , (const config_item_types[2]) {CONFIG_INT , CONFIG_STRING}); - config_schema_item_set_indexed_selection_set( item , 1 , 3 , (const char *[3]) {EXT_CMD_STRING_TYPE , EXT_CMD_INT_TYPE , EXT_CMD_FLOAT_TYPE}); - - /*****************************************************************/ - item = config_add_schema_item( config , EXECUTABLE_KEY , false , false ); - config_schema_item_set_argc_minmax( item , 1 , 1 , 1 , (const config_item_types[1]) {CONFIG_EXECUTABLE}); - - /*---------------------------------------------------------------*/ - - item = config_add_schema_item( config , FUNCTION_KEY , false , false ); - config_schema_item_set_argc_minmax( item , 1 , 1 , 1 , (const config_item_types[1]) {CONFIG_STRING}); - - item = config_add_schema_item( config , MODULE_KEY , false , false ); - config_schema_item_set_argc_minmax( item , 1 , 1 , 1 , (const config_item_types[1]) {CONFIG_STRING}); - /*****************************************************************/ - - item = config_add_schema_item( config , INTERNAL_KEY , false , false); - config_schema_item_set_argc_minmax( item , 1 , 1 , 1 , (const config_item_types[1]) {CONFIG_BOOLEAN}); - - } - return config; -} - - - -static UTIL_SAFE_CAST_FUNCTION(ext_cmd , EXT_CMD_TYPE_ID ) - -ext_cmd_type * ext_cmd_alloc( bool internal ) { - ext_cmd_type * ext_cmd = util_malloc( sizeof * ext_cmd ); - UTIL_TYPE_ID_INIT( ext_cmd , EXT_CMD_TYPE_ID ); - ext_cmd->internal = internal; // This can NOT be changed run-time. - ext_cmd->min_arg = ARG_MIN_DEFAULT; - ext_cmd->max_arg = ARG_MAX_DEFAULT; - ext_cmd->arg_types = int_vector_alloc( 0 , CONFIG_STRING ); - - ext_cmd->executable = NULL; - ext_cmd->module = NULL; - ext_cmd->function = NULL; - ext_cmd->valid = false; - - return ext_cmd; -} - - -void ext_cmd_set_executable( ext_cmd_type * ext_cmd , const char * executable ) { - ext_cmd->executable = util_realloc_string_copy( ext_cmd->executable , executable ); -} - - -void ext_cmd_set_module( ext_cmd_type * ext_cmd , const char * module) { - if (strcmp(module ,NULL_STRING) == 0) - module = NULL; - - ext_cmd->module = util_realloc_string_copy( ext_cmd->module , module ); -} - - -void ext_cmd_set_function( ext_cmd_type * ext_cmd , const char * function) { - ext_cmd->function = util_realloc_string_copy( ext_cmd->function , function ); -} - - -void ext_cmd_iset_argtype( ext_cmd_type * ext_cmd , int iarg , config_item_types type) { - if (type == CONFIG_STRING || type == CONFIG_INT || type == CONFIG_FLOAT) - int_vector_iset( ext_cmd->arg_types , iarg , type ); -} - -void ext_cmd_set_min_arg( ext_cmd_type * ext_cmd , int min_arg) { - ext_cmd->min_arg = min_arg; -} - -void ext_cmd_set_max_arg( ext_cmd_type * ext_cmd , int max_arg) { - ext_cmd->max_arg = max_arg; -} - - -static void ext_cmd_iset_argtype_string( ext_cmd_type * ext_cmd , int iarg , const char * arg_type) { - config_item_types type = CONFIG_INVALID; - - if (strcmp( arg_type , EXT_CMD_STRING_TYPE) == 0) - type = CONFIG_STRING; - else if (strcmp( arg_type , EXT_CMD_INT_TYPE) == 0) - type = CONFIG_INT; - else if (strcmp( arg_type , EXT_CMD_FLOAT_TYPE) == 0) - type = CONFIG_FLOAT; - - if (type != CONFIG_INVALID) - ext_cmd_iset_argtype( ext_cmd , iarg , type ); - -} - - -static void ext_cmd_validate( ext_cmd_type * ext_cmd ) { - if (!ext_cmd->internal) { - if (ext_cmd->executable != NULL) { - if (util_is_executable( ext_cmd->executable ) && - (ext_cmd->module == ext_cmd->function) && - (ext_cmd == NULL)) - ext_cmd->valid = true; - } - } else { - if ((ext_cmd->executable == NULL) && (ext_cmd->function != NULL)) { - ext_cmd->lib_handle = dlopen( ext_cmd->module , RTLD_NOW ); - if (ext_cmd->lib_handle != NULL) { - ext_cmd->dl_func = dlsym( ext_cmd->lib_handle , ext_cmd->function ); - if (ext_cmd->dl_func != NULL) - ext_cmd->valid = true; - else - fprintf(stderr,"Failed to load symbol:%s Error:%s \n",ext_cmd->function , dlerror()); - } else { - if (ext_cmd->module != NULL) - fprintf(stderr,"Failed to load module:%s Error:%s \n",ext_cmd->module , dlerror()); - } - } - } -} - - - -ext_cmd_type * ext_cmd_config_alloc( config_type * config , const char * config_file) { - config_clear( config ); - config_parse( config , config_file , "--", NULL , NULL , true , true); - { - - bool internal = DEFAULT_INTERNAL; - if (config_item_set( config , INTERNAL_KEY)) - internal = config_iget_as_bool( config , INTERNAL_KEY , 0 , 0 ); - - { - ext_cmd_type * ext_cmd = ext_cmd_alloc( internal ); - - if (config_item_set( config , MIN_ARG_KEY)) - ext_cmd_set_min_arg( ext_cmd , config_iget_as_int( config , MIN_ARG_KEY , 0 , 0 )); - - if (config_item_set( config , MAX_ARG_KEY)) - ext_cmd_set_max_arg( ext_cmd , config_iget_as_int( config , MAX_ARG_KEY , 0 , 0 )); - - { - int i; - for (i=0; i < config_get_occurences( config , ARG_TYPE_KEY); i++) { - int iarg = config_iget_as_int( config , ARG_TYPE_KEY , i , 0 ); - const char * arg_type = config_iget( config , ARG_TYPE_KEY , i , 1 ); - - ext_cmd_iset_argtype_string( ext_cmd , iarg , arg_type ); - } - } - - if (config_item_set( config , MODULE_KEY)) - ext_cmd_set_module( ext_cmd , config_iget( config , MODULE_KEY , 0 , 0 )); - - if (config_item_set( config , FUNCTION_KEY)) - ext_cmd_set_function( ext_cmd , config_iget( config , FUNCTION_KEY , 0 , 0 )); - - if (config_item_set( config , EXECUTABLE_KEY)) - ext_cmd_set_executable( ext_cmd , config_iget( config , EXECUTABLE_KEY , 0 , 0 )); - - ext_cmd_validate( ext_cmd ); - - if (!ext_cmd->valid) { - ext_cmd_free( ext_cmd ); - ext_cmd = NULL; - } - - return ext_cmd; - } - } -} - - - -void ext_cmd_free( ext_cmd_type * ext_cmd ) { - util_safe_free( ext_cmd->module ); - util_safe_free( ext_cmd->function ); - util_safe_free( ext_cmd->executable ); - int_vector_free( ext_cmd->arg_types ); - free( ext_cmd ); -} - - -void ext_cmd_free__( void * arg) { - ext_cmd_type * ext_cmd = ext_cmd_safe_cast( arg ); - ext_cmd_free( ext_cmd ); -} diff --git a/ThirdParty/Ert/devel/libjob_queue/src/ext_job.c b/ThirdParty/Ert/devel/libjob_queue/src/ext_job.c index c4fa5e9971..c8db735d36 100644 --- a/ThirdParty/Ert/devel/libjob_queue/src/ext_job.c +++ b/ThirdParty/Ert/devel/libjob_queue/src/ext_job.c @@ -629,15 +629,26 @@ static void ext_job_fprintf_python_argList( const ext_job_type * ext_job , FILE } - -void ext_job_python_fprintf(const ext_job_type * ext_job, FILE * stream, const subst_list_type * global_args) { +static bool ext_job_check_executable( const ext_job_type * ext_job , const subst_list_type * global_args) { + bool OK = true; char * executable; executable = subst_list_alloc_filtered_string( ext_job->private_args , ext_job->executable ); if (global_args != NULL) subst_list_update_string( global_args , &executable ); - if (util_is_executable( executable )) { - fprintf(stream," {"); + if (!util_is_executable( executable )) + OK = false; + free( executable ); + return OK; +} + + +void ext_job_python_fprintf(const ext_job_type * ext_job, FILE * stream, const subst_list_type * global_args) { + if (!ext_job_check_executable( ext_job , global_args )) + fprintf(stderr," ** WARNING: The executable:%s could not be located on host computer - job will most probably fail.\n", ext_job->executable); + + fprintf(stream," {"); + { __indent(stream, 0); __fprintf_python_string(stream , "name" , ext_job->name , ext_job->private_args , NULL); __end_line(stream); __indent(stream, 2); __fprintf_python_string(stream , "executable" , ext_job->executable , ext_job->private_args, global_args); __end_line(stream); __indent(stream, 2); __fprintf_python_string(stream , "target_file" , ext_job->target_file , ext_job->private_args, global_args); __end_line(stream); @@ -651,11 +662,8 @@ void ext_job_python_fprintf(const ext_job_type * ext_job, FILE * stream, const s __indent(stream, 2); __fprintf_python_string(stream , "license_path" , ext_job->license_path , ext_job->private_args, global_args); __end_line(stream); __indent(stream, 2); __fprintf_python_int( stream , "max_running_minutes" , ext_job->max_running_minutes ); __end_line(stream); __indent(stream, 2); __fprintf_python_int( stream , "max_running" , ext_job->max_running ); __end_line(stream); - fprintf(stream,"}"); - } else - fprintf(stderr," ** WARNING: The executable:%s could not be located on host computer - job will most probably fail.\n", executable); - - free( executable ); + } + fprintf(stream,"}"); } @@ -753,22 +761,22 @@ ext_job_type * ext_job_fscanf_alloc(const char * name , const char * license_roo ext_job_set_config_file( ext_job , config_file ); { config_schema_item_type * item; - item = config_add_schema_item(config , "MAX_RUNNING" , false , false); config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_INT}); - item = config_add_schema_item(config , "STDIN" , false , false); config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); - item = config_add_schema_item(config , "STDOUT" , false , false); config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); - item = config_add_schema_item(config , "STDERR" , false , false); config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); - item = config_add_schema_item(config , "EXECUTABLE" , false , false); config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); - item = config_add_schema_item(config , "TARGET_FILE" , false , false); config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); - item = config_add_schema_item(config , "ERROR_FILE" , false , false); config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); - item = config_add_schema_item(config , "START_FILE" , false , false); config_schema_item_set_argc_minmax(item , 1 , 1 , 0 , NULL); - item = config_add_schema_item(config , "ENV" , false , true ); config_schema_item_set_argc_minmax(item , 2 , 2 , 0 , NULL); - item = config_add_schema_item(config , "DEFAULT" , false , true ); config_schema_item_set_argc_minmax(item , 2 , 2 , 0 , NULL); - item = config_add_schema_item(config , "ARGLIST" , false , true ); config_schema_item_set_argc_minmax(item , 1 ,-1 , 0 , NULL); - item = config_add_schema_item(config , "MAX_RUNNING_MINUTES" , false , false); config_schema_item_set_argc_minmax(item , 1 , 1 , 1 , (const config_item_types [1]) {CONFIG_INT}); + item = config_add_schema_item(config , "MAX_RUNNING" , false ); config_schema_item_set_argc_minmax(item , 1 , 1 ); config_schema_item_iset_type( item , 0 , CONFIG_INT ); + item = config_add_schema_item(config , "STDIN" , false ); config_schema_item_set_argc_minmax(item , 1 , 1 ); + item = config_add_schema_item(config , "STDOUT" , false ); config_schema_item_set_argc_minmax(item , 1 , 1 ); + item = config_add_schema_item(config , "STDERR" , false ); config_schema_item_set_argc_minmax(item , 1 , 1 ); + item = config_add_schema_item(config , "EXECUTABLE" , false ); config_schema_item_set_argc_minmax(item , 1 , 1 ); + item = config_add_schema_item(config , "TARGET_FILE" , false ); config_schema_item_set_argc_minmax(item , 1 , 1 ); + item = config_add_schema_item(config , "ERROR_FILE" , false ); config_schema_item_set_argc_minmax(item , 1 , 1 ); + item = config_add_schema_item(config , "START_FILE" , false ); config_schema_item_set_argc_minmax(item , 1 , 1 ); + item = config_add_schema_item(config , "ENV" , false ); config_schema_item_set_argc_minmax(item , 2 , 2 ); + item = config_add_schema_item(config , "DEFAULT" , false ); config_schema_item_set_argc_minmax(item , 2 , 2 ); + item = config_add_schema_item(config , "ARGLIST" , false ); config_schema_item_set_argc_minmax(item , 1 , CONFIG_DEFAULT_ARG_MAX ); + item = config_add_schema_item(config , "MAX_RUNNING_MINUTES" , false ); config_schema_item_set_argc_minmax(item , 1 , 1 ); config_schema_item_iset_type( item , 0 , CONFIG_INT ); } config_add_alias(config , "EXECUTABLE" , "PORTABLE_EXE"); - config_parse(config , config_file , "--" , NULL , NULL , true , true); - { + + if (config_parse(config , config_file , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_WARN , true)) { if (config_item_set(config , "STDIN")) ext_job_set_stdin_file(ext_job , config_iget(config , "STDIN" , 0,0)); if (config_item_set(config , "STDOUT")) ext_job_set_stdout_file(ext_job , config_iget(config , "STDOUT" , 0,0)); if (config_item_set(config , "STDERR")) ext_job_set_stderr_file(ext_job , config_iget(config , "STDERR" , 0,0)); @@ -781,36 +789,51 @@ ext_job_type * ext_job_fscanf_alloc(const char * name , const char * license_roo - if (config_item_set(config , "ARGLIST")) { - stringlist_type *argv = config_iget_stringlist_ref( config , "ARGLIST" , 0); - stringlist_deep_copy( ext_job->argv , argv ); + { + config_content_node_type * arg_node = config_get_value_node( config , "ARGLIST"); + if (arg_node != NULL) { + int i; + for (i=0; i < config_content_node_get_size( arg_node ); i++) + stringlist_append_copy( ext_job->argv , config_content_node_iget( arg_node , i )); + } } /** The code assumes that the hash tables are valid, can not be NULL: */ - if (config_item_set(config , "ENV")) { - for (int occ_nr = 0; occ_nr < config_get_occurences( config , "ENV"); occ_nr++) { - const stringlist_type *key_value = config_iget_stringlist_ref( config , "ENV" , occ_nr); - for (int i=0; i < stringlist_get_size( key_value ); i+= 2) - hash_insert_hash_owned_ref( ext_job->environment, - stringlist_iget( key_value , i ) , - util_alloc_string_copy( stringlist_iget( key_value , i + 1)) , free); + { + const config_content_item_type * env_item = config_get_content_item( config , "ENV" ); + if (env_item != NULL) { + for (int ivar = 0; ivar < config_content_item_get_size( env_item ); ivar++) { + const config_content_node_type * env_node = config_content_item_iget_node( env_item , ivar ); + for (int i=0; i < config_content_node_get_size( env_node ); i+= 2) { + const char * key = config_content_node_iget( env_node , i ); + const char * value = config_content_node_iget( env_node , i + 1); + hash_insert_hash_owned_ref( ext_job->environment, key , util_alloc_string_copy( value ) , free); + } + } } } /* Default mappings; these are used to set values in the argList which have not been supplied by the calling context. */ - if (config_item_set(config , "DEFAULT")) { - for (int occ_nr = 0; occ_nr < config_get_occurences( config , "DEFAULT"); occ_nr++) { - const stringlist_type *key_value = config_iget_stringlist_ref( config , "DEFAULT" , occ_nr); - for (int i=0; i < stringlist_get_size( key_value ); i+= 2) - hash_insert_hash_owned_ref( ext_job->default_mapping, - stringlist_iget( key_value , i ) , - util_alloc_string_copy( stringlist_iget( key_value , i + 1)) , free); + { + const config_content_item_type * default_item = config_get_content_item( config , "DEFAULT"); + if (default_item != NULL) { + for (int ivar = 0; ivar < config_content_item_get_size( default_item ); ivar++) { + const config_content_node_type * default_node = config_content_item_iget_node( default_item , ivar ); + for (int i=0; i < config_content_node_get_size( default_node ); i+= 2) { + const char * key = config_content_node_iget( default_node , i ); + const char * value = config_content_node_iget( default_node , i + 1); + hash_insert_hash_owned_ref( ext_job->default_mapping, key , util_alloc_string_copy( value ) , free); + } + } } } + } else { + config_fprintf_errors( config , true , stderr ); + exit(1); } config_free(config); diff --git a/ThirdParty/Ert/devel/libjob_queue/src/job_queue.c b/ThirdParty/Ert/devel/libjob_queue/src/job_queue.c index 4756dc3625..e9f4052104 100644 --- a/ThirdParty/Ert/devel/libjob_queue/src/job_queue.c +++ b/ThirdParty/Ert/devel/libjob_queue/src/job_queue.c @@ -1511,6 +1511,13 @@ void job_queue_set_driver(job_queue_type * queue , queue_driver_type * driver) { } +bool job_queue_has_driver(const job_queue_type * queue ) { + if (queue->driver == NULL) + return false; + else + return true; +} + /** Observe that if the max number of running jobs is decreased, diff --git a/ThirdParty/Ert/devel/libjob_queue/src/lsb.c b/ThirdParty/Ert/devel/libjob_queue/src/lsb.c new file mode 100644 index 0000000000..13dadd89bc --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/src/lsb.c @@ -0,0 +1,197 @@ +/* + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'lsb.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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. +*/ + +/* + This file implements a very small wrapper structure around the + lsb_xxxx() functions from the libbat.so shared library which are + used to submit, monitor and control simulations with LSF. + + Loading and initializing the lsf libraries is quite painful, in an + attempt to reduce unecessary dependencies the lsf libraries are + loaded with dlopen() in the lsb_alloc() function below. This means + that the libjob_queue.so shared library can be loaded without access + to the lsf libraries. +*/ + +#include +#include + +#include + +#include +#include + +#include + + + +typedef int (lsb_submit_ftype) ( struct submit * , struct submitReply *); +typedef int (lsb_openjobinfo_ftype) (int , char * , char * , char * , char * , int); +typedef struct jobInfoEnt * (lsb_readjobinfo_ftype) (int * ); +typedef int (lsb_closejobinfo_ftype) ( ); +typedef int (lsb_forcekilljob_ftype) ( int ); +typedef int (lsb_init_ftype) ( char * ); +typedef char * (lsb_sysmsg_ftype) ( ); + + + +struct lsb_struct { + lsb_submit_ftype * submit; + lsb_openjobinfo_ftype * open_job; + lsb_readjobinfo_ftype * read_job; + lsb_closejobinfo_ftype * close_job; + lsb_forcekilljob_ftype * kill_job; + lsb_init_ftype * lsb_init; + lsb_sysmsg_ftype * sys_msg; + + stringlist_type * error_list; + void * lib_handle; + bool ready; +}; + + + +static void * lsb_dlsym( lsb_type * lsb , const char * function_name ) { + void * function = dlsym( lsb->lib_handle , function_name ); + if (!function) { + lsb->ready = false; + stringlist_append_owned_ref( lsb->error_list , util_alloc_sprintf( "Failed to locate symbol:%s dlerror:%s" , function_name , dlerror())); + } + + return function; +} + + +void * lsb_dlopen( lsb_type * lsb , const char * lib_name) { + void * lib_handle = dlopen( lib_name , RTLD_NOW | RTLD_GLOBAL); + if (!lib_handle) { + lsb->ready = false; + stringlist_append_owned_ref( lsb->error_list , util_alloc_sprintf("dlopen(%s) - failed:%s \n" , lib_name , dlerror())); + } + return lib_handle; +} + +/* + The following environment variables must be set (at some stage) before + LSF will work properly: + + LSF_BINDIR $LSF_HOME/bin + LSF_LIBDIR $LSF_HOME/lib + XLSF_UIDDIR $LSF_HOME/lib/uid + LSF_SERVERDIR $LSF_HOME/etc + LSF_ENVDIR /prog/LSF/conf + + The runtime linker must locate the libnsl, libbat and liblsf + libraries using whatever method it usually does. If the loading + fails the lsb object will get the ->ready flag set to false, and the + lsf_driver will discard the lsb instance (and hopefully use shell + commands to perform job management). +*/ + +lsb_type * lsb_alloc() { + lsb_type * lsb = util_malloc( sizeof * lsb ); + lsb->ready = true; + lsb->error_list = stringlist_alloc_new(); + + lsb_dlopen(lsb , "libnsl.so" ); + lsb_dlopen(lsb , "liblsf.so" ); + lsb->lib_handle = lsb_dlopen(lsb , "libbat.so"); + + if (lsb->lib_handle) { + lsb->submit = (lsb_submit_ftype *) lsb_dlsym( lsb , "lsb_submit"); + lsb->open_job = (lsb_openjobinfo_ftype *) lsb_dlsym( lsb , "lsb_openjobinfo"); + lsb->read_job = (lsb_readjobinfo_ftype *) lsb_dlsym( lsb , "lsb_readjobinfo"); + lsb->close_job = (lsb_closejobinfo_ftype *) lsb_dlsym( lsb , "lsb_closejobinfo"); + lsb->kill_job = (lsb_forcekilljob_ftype *) lsb_dlsym( lsb , "lsb_forcekilljob"); + lsb->lsb_init = (lsb_init_ftype *) lsb_dlsym( lsb , "lsb_init"); + lsb->sys_msg = (lsb_sysmsg_ftype *) lsb_dlsym( lsb , "lsb_sysmsg"); + } + + return lsb; +} + + + +void lsb_free( lsb_type * lsb) { + stringlist_free( lsb->error_list ); + if (lsb->lib_handle) + dlclose( lsb->lib_handle ); + free( lsb ); +} + + + +bool lsb_ready( const lsb_type * lsb) { + return lsb->ready; +} + +stringlist_type * lsb_get_error_list( const lsb_type * lsb ) { + return lsb->error_list; +} + + +/*****************************************************************/ + +int lsb_initialize( const lsb_type * lsb) { + /* + The environment variable LSF_ENVDIR must be set to point the + directory containing LSF configuration information, the whole + thing will crash and burn if this is not properly set. + */ + printf("Calling initialize ... \n"); + if ( lsb->lsb_init(NULL) != 0 ) { + fprintf(stderr,"LSF_ENVDIR: "); + if (getenv("LSF_ENVDIR") != NULL) + fprintf(stderr,"%s\n", getenv("LSF_ENVDIR")); + else + fprintf(stderr, "not set\n"); + + util_abort("%s failed to initialize LSF environment : %s \n",__func__ , lsb->sys_msg() ); + } + return 0; +} + + +int lsb_submitjob( const lsb_type * lsb , struct submit * submit_data, struct submitReply * reply_data) { + return lsb->submit( submit_data , reply_data ); +} + + +int lsb_killjob( const lsb_type * lsb , int lsf_jobnr) { + return lsb->kill_job(lsf_jobnr); +} + + +int lsb_openjob( const lsb_type * lsb , int lsf_jobnr) { + return lsb->open_job(lsf_jobnr , NULL , NULL , NULL , NULL , ALL_JOB); +} + + +int lsb_closejob( const lsb_type * lsb) { + return lsb->close_job(); +} + +char * lsb_sys_msg( const lsb_type * lsb) { + return lsb->sys_msg(); +} + + +struct jobInfoEnt * lsb_readjob( const lsb_type * lsb ) { + struct jobInfoEnt * job_info = lsb->read_job( NULL ); + return job_info; +} diff --git a/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver.c b/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver.c index 2f9d7d4377..e5a26cdc5c 100644 --- a/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver.c +++ b/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver.c @@ -1,7 +1,7 @@ /* Copyright (C) 2011 Statoil ASA, Norway. - The file 'lsf_driver.c' is part of ERT - Ensemble based Reservoir Tool. + The file 'lsf_driver_impl.c' is part of ERT - Ensemble based Reservoir Tool. ERT 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 +16,937 @@ for more details. */ -/** - If the symbol INCLUDE_LSF is not defined a dummy LSF driver will be - compiled. This driver has stubs for all the driver related - functions, and a dummy driver can be created with the - queue_driver_alloc_LSF() function. +#include +#include +#include +#include +#include - If one of the queue_driver function pointers pointing down to one - of the lsf_driver_xxx() functions is actually invoked (e.g. through - the queue layer) the program will exit with an error message. This - is only a utility to avoid changing the source when the library is - built and used on a platform without LSF inst1alled. - - When compiling with proper LSF support the preprocessor symbol - INCLUDE_LSF must be set (to an arbitrary value), in addition the - libraries liblsf, libbat and libnsl must be linked in when creating - the final executable. +#include +#include +#include + +#include +#include + +#include +#ifdef HAVE_LSF_LIBRARY +#include +#endif + + + + + +/** + Documentation/examples of programming towards the lsf libraries can + be found in /prog/LSF/7.0/misc/examples */ -#ifdef HAVE_LSF -#include "lsf_driver_impl.c" -#else -#include "lsf_driver_dummy.c" + +/* + How to call the lsf commands bsub/bjobs/bkill: + ---------------------------------------------- + + The commands to submit, monitor and modify LSF jobs are available + through library calls through the lsf library. This is a good + solution which works well. + + Unfortunately only quite few of the workstations in Statoil are + "designated LSF machines", meaning that they are allowed to talk to + the LIM servers, to be able to use the low-level lsb_xxx() function + calls the host making the calls must configured (by an LSF + administrator) to be a LSF client. + + The lsf_driver can either make use of the proper lsf library calls + (lsb_submit(), lsb_openjobinfo(), ...) or alternatively it can issue + ssh calls to an external LSF_SERVER and call up the bsub/bkill/bjob + executables on the remote server. + + All the functions with 'library' in the name are based on library + calls, and the functions with 'shell' in the name are based on + external functions (the actual calls are through the + util_fork_exec() function). + + By default the driver will use the library, but if a value is + provided with the LSF_SERVER option, the shell based functions will + be used. Internally this is goverened by the boolean flag + 'use_library_calls'. + + Even though you only intend to submit through the shell commands + bsub / bjobs / bkill the build process still requires access to the + lsf headers and the lsf library; that is probably not optimal. + + + Remote login shell + ------------------ + + When submitting with LSF the job will inherit the current + environment on the submitting host, and not read the users login + files on the remote host where the job is actually executed. E.g. in + situations where submitting host and executing host are + e.g. different operating system versions this might be + unfortunate. The '-L @shell' switch can used with bsub to force lsf + to source schell specific input files prior to executing your + job. This can be achieved with the LSF_LOGIN_SHELL option: + + lsf_driver_set_option( driver , LSF_LOGIN_SHELL , "/bin/csh" ); + +*/ + + + + + +#define LSF_DRIVER_TYPE_ID 10078365 +#define LSF_JOB_TYPE_ID 9963900 +#define BJOBS_REFRESH_TIME 10 +#define DEFAULT_RSH_CMD "/usr/bin/ssh" +#define DEFAULT_BSUB_CMD "bsub" +#define DEFAULT_BJOBS_CMD "bjobs" +#define DEFAULT_BKILL_CMD "bkill" + + + +struct lsf_job_struct { + UTIL_TYPE_ID_DECLARATION; + long int lsf_jobnr; + int num_exec_host; + char **exec_host; + char * lsf_jobnr_char; /* Used to look up the job status in the bjobs_cache hash table */ +}; + + + +struct lsf_driver_struct { + UTIL_TYPE_ID_DECLARATION; + char * queue_name; + char * resource_request; + char * login_shell; + pthread_mutex_t submit_lock; + + lsf_submit_method_enum submit_method; + + /*-----------------------------------------------------------------*/ + /* Fields used by the lsf library functions */ +#ifdef HAVE_LSF_LIBRARY + struct submit lsf_request; + struct submitReply lsf_reply; + lsb_type * lsb; #endif + + /*-----------------------------------------------------------------*/ + /* Fields used by the shell based functions */ + + int bjobs_refresh_interval; + time_t last_bjobs_update; + hash_type * my_jobs; /* A hash table of all jobs submitted by this ERT instance - + to ensure that we do not check status of old jobs in e.g. ZOMBIE status. */ + hash_type * status_map; + hash_type * bjobs_cache; /* The output of calling bjobs is cached in this table. */ + pthread_mutex_t bjobs_mutex; /* Only one thread should update the bjobs_chache table. */ + char * remote_lsf_server; + char * rsh_cmd; + char * bsub_cmd; + char * bjobs_cmd; + char * bkill_cmd; +}; + + + + +/*****************************************************************/ + +UTIL_SAFE_CAST_FUNCTION( lsf_driver , LSF_DRIVER_TYPE_ID) +static UTIL_SAFE_CAST_FUNCTION_CONST( lsf_driver , LSF_DRIVER_TYPE_ID) +static UTIL_SAFE_CAST_FUNCTION( lsf_job , LSF_JOB_TYPE_ID) + +lsf_job_type * lsf_job_alloc() { + lsf_job_type * job; + job = util_malloc(sizeof * job); + job->num_exec_host = 0; + job->exec_host = NULL; + + job->lsf_jobnr_char = NULL; + UTIL_TYPE_ID_INIT( job , LSF_JOB_TYPE_ID); + return job; +} + + + +void lsf_job_free(lsf_job_type * job) { + util_safe_free(job->lsf_jobnr_char); + util_free_stringlist(job->exec_host , job->num_exec_host); + free(job); +} + + +static int lsf_job_parse_bsub_stdout(const lsf_driver_type * driver , const char * stdout_file) { + int jobid = -1; + FILE * stream = util_fopen(stdout_file , "r"); + if (util_fseek_string(stream , "<" , true , true)) { + char * jobid_string = util_fscanf_alloc_upto(stream , ">" , false); + if (jobid_string != NULL) { + jobid = atoi( jobid_string ); + free( jobid_string ); + } + } + fclose( stream ); + + if (jobid == -1) { + char * file_content = util_fread_alloc_file_content( stdout_file , NULL ); + fprintf(stderr,"Failed to get lsf job id from file: %s \n",stdout_file ); + fprintf(stderr,"bsub command : %s \n",driver->bsub_cmd ); + fprintf(stderr,"%s\n", file_content); + free( file_content ); + util_exit("%s: \n",__func__); + } + return jobid; +} + + + +static void lsf_driver_internal_error( const lsf_driver_type * driver ) { + fprintf(stderr , "\n\n"); + fprintf(stderr , "*****************************************************************\n"); + fprintf(stderr , "** The LSF driver can be configured and used in many different **\n"); + fprintf(stderr , "** ways. The important point is how we choose to submit: **\n"); + fprintf(stderr , "** **\n"); + fprintf(stderr , "** 1. Using the lsf library calls **\n"); + fprintf(stderr , "** 2. Using the bsub/bjobs/bkill commands locally **\n"); + fprintf(stderr , "** 3. Using the bsub/bjobs/bkill commands through ssh **\n"); + fprintf(stderr , "** **\n"); + fprintf(stderr , "** To chose between these three alternatives you set the remote**\n"); + fprintf(stderr , "** server with the lsf_driver_set_option() function. Passing **\n"); + fprintf(stderr , "** the value NULL will give alternative 1, passing the special **\n"); + fprintf(stderr , "** string \'%s\' will give alternative 2, and any other **\n",LOCAL_LSF_SERVER); + fprintf(stderr , "** value will submit through that host using ssh. **\n"); + fprintf(stderr , "** **\n"); + fprintf(stderr , "** The ability to submit thorugh lsf library calls must be **\n"); + fprintf(stderr , "** compiled in by defining the symbol \'HAVE_LSF_LIBRARY\' when **\n"); + fprintf(stderr , "** compiling. **\n"); + fprintf(stderr , "** **\n"); +#ifdef HAVE_LSF_LIBRARY + fprintf(stderr , "** This lsf driver has support for using lsf library calls. **\n"); +#else + fprintf(stderr , "** This lsf driver does NOT have support for using lsf **\n"); + fprintf(stderr , "** library calls; but you have tried to submit without setting **\n"); + fprintf(stderr , "** a value for LSF_SERVER. Set this and try again. **\n"); +#endif + fprintf(stderr , "*****************************************************************\n\n"); + exit(1); +} + + + +static void lsf_driver_assert_submit_method( const lsf_driver_type * driver ) { + if (driver->submit_method == LSF_SUBMIT_INVALID) { + lsf_driver_internal_error(driver); + } +} + + + + + +stringlist_type * lsf_driver_alloc_cmd(lsf_driver_type * driver , + const char * lsf_stdout , + const char * job_name , + const char * submit_cmd , + int num_cpu , + int job_argc, + const char ** job_argv) { + + stringlist_type * argv = stringlist_alloc_new(); + char * num_cpu_string = util_alloc_sprintf("%d" , num_cpu); + char * quoted_resource_request = NULL; + + /* + The resource request string contains spaces, and when passed + through the shell it must be protected with \"..\"; this applies + when submitting to a remote lsf server with ssh. However when + submitting to the local workstation using a bsub command the + command will be invoked with the util_fork_exec() command - and no + shell is involved. In this latter case we must avoid the \"...\" + quoting. + */ + + if (driver->resource_request != NULL) { + if (driver->submit_method == LSF_SUBMIT_REMOTE_SHELL) + quoted_resource_request =util_alloc_sprintf("\"%s\"" , driver->resource_request); + else + quoted_resource_request = util_alloc_string_copy( driver->resource_request ); + } + + if (driver->submit_method == LSF_SUBMIT_REMOTE_SHELL) + stringlist_append_ref( argv , driver->bsub_cmd); + + stringlist_append_ref( argv , "-o" ); + stringlist_append_copy( argv , lsf_stdout ); + if (driver->queue_name != NULL) { + stringlist_append_ref( argv , "-q" ); + stringlist_append_ref( argv , driver->queue_name ); + } + stringlist_append_ref( argv , "-J" ); + stringlist_append_ref( argv , job_name ); + stringlist_append_ref( argv , "-n" ); + stringlist_append_copy( argv , num_cpu_string ); + + if (quoted_resource_request != NULL) { + stringlist_append_ref( argv , "-R"); + stringlist_append_copy( argv , quoted_resource_request ); + } + + if (driver->login_shell != NULL) { + stringlist_append_ref( argv , "-L"); + stringlist_append_ref( argv , driver->login_shell ); + } + + stringlist_append_ref( argv , submit_cmd); + { + int iarg; + for (iarg = 0; iarg < job_argc; iarg++) + stringlist_append_ref( argv , job_argv[ iarg ]); + } + free( num_cpu_string ); + util_safe_free( quoted_resource_request ); + return argv; +} + + +static int lsf_driver_submit_internal_job( lsf_driver_type * driver , + const char * lsf_stdout , + const char * job_name , + const char * submit_cmd , + int num_cpu , + int argc, + const char ** argv) { + +#ifdef HAVE_LSF_LIBRARY + char * command; + { + buffer_type * command_buffer = buffer_alloc( 256 ); + buffer_fwrite_char_ptr( command_buffer , submit_cmd ); + for (int iarg = 0; iarg < argc; iarg++) { + buffer_fwrite_char( command_buffer , ' '); + buffer_fwrite_char_ptr( command_buffer , argv[ iarg ]); + } + buffer_terminate_char_ptr( command_buffer ); + command = buffer_get_data( command_buffer ); + buffer_free_container( command_buffer ); + } + + { + int options = SUB_JOB_NAME + SUB_OUT_FILE; + + if (driver->queue_name != NULL) + options += SUB_QUEUE; + + if (driver->resource_request != NULL) + options += SUB_RES_REQ; + + if (driver->login_shell != NULL) + options += SUB_LOGIN_SHELL; + + driver->lsf_request.options = options; + } + + driver->lsf_request.resReq = driver->resource_request; + driver->lsf_request.loginShell = driver->login_shell; + driver->lsf_request.queue = driver->queue_name; + driver->lsf_request.jobName = (char *) job_name; + driver->lsf_request.outFile = (char *) lsf_stdout; + driver->lsf_request.command = command; + driver->lsf_request.numProcessors = num_cpu; + + { + int lsf_jobnr = lsb_submitjob( driver->lsb , &driver->lsf_request , &driver->lsf_reply ); + free( command ); /* I trust the lsf layer is finished with the command? */ + if (lsf_jobnr <= 0) + fprintf(stderr,"%s: ** Warning: lsb_submit() failed: %s \n",__func__ , lsb_sys_msg( driver->lsb )); + + return lsf_jobnr; + } +#else + lsf_driver_internal_error( driver ); +#endif +} + + + +static int lsf_driver_submit_shell_job(lsf_driver_type * driver , + const char * lsf_stdout , + const char * job_name , + const char * submit_cmd , + int num_cpu , + int job_argc, + const char ** job_argv) { + int job_id; + char * tmp_file = util_alloc_tmp_file("/tmp" , "enkf-submit" , true); + + if (driver->remote_lsf_server != NULL) { + stringlist_type * remote_argv = lsf_driver_alloc_cmd( driver , lsf_stdout , job_name , submit_cmd , num_cpu , job_argc , job_argv); + + if (driver->submit_method == LSF_SUBMIT_REMOTE_SHELL) { + char ** argv = util_calloc( 2 , sizeof * argv ); + argv[0] = driver->remote_lsf_server; + argv[1] = stringlist_alloc_joined_string( remote_argv , " "); + util_fork_exec(driver->rsh_cmd , 2 , (const char **) argv , true , NULL , NULL , NULL , tmp_file , NULL); + free( argv[1] ); + free( argv ); + } else if (driver->submit_method == LSF_SUBMIT_LOCAL_SHELL) { + char ** argv = stringlist_alloc_char_ref( remote_argv ); + util_fork_exec(driver->bsub_cmd , stringlist_get_size( remote_argv) , (const char **) argv , true , NULL , NULL , NULL , tmp_file , tmp_file); + free( argv ); + } + + stringlist_free( remote_argv ); + } + + job_id = lsf_job_parse_bsub_stdout(driver , tmp_file); + util_unlink_existing( tmp_file ); + free(tmp_file); + return job_id; +} + + + +static int lsf_driver_get_status__(lsf_driver_type * driver , const char * status, const char * job_id) { + if (hash_has_key( driver->status_map , status)) + return hash_get_int( driver->status_map , status); + else { + util_exit("The lsf_status:%s for job:%s is not recognized; call your LSF administrator - sorry :-( \n", status , job_id); + return -1; + } +} + + + +static void lsf_driver_update_bjobs_table(lsf_driver_type * driver) { + char * tmp_file = util_alloc_tmp_file("/tmp" , "enkf-bjobs" , true); + + if (driver->submit_method == LSF_SUBMIT_REMOTE_SHELL) { + char ** argv = util_calloc( 2 , sizeof * argv); + argv[0] = driver->remote_lsf_server; + argv[1] = util_alloc_sprintf("%s -a" , driver->bjobs_cmd); + util_fork_exec(driver->rsh_cmd , 2 , (const char **) argv , true , NULL , NULL , NULL , tmp_file , NULL); + free( argv[1] ); + free( argv ); + } else if (driver->submit_method == LSF_SUBMIT_LOCAL_SHELL) { + char ** argv = util_calloc( 1 , sizeof * argv); + argv[0] = "-a"; + util_fork_exec(driver->bjobs_cmd , 1 , (const char **) argv , true , NULL , NULL , NULL , tmp_file , NULL); + free( argv ); + } + + { + char user[32]; + char status[16]; + FILE *stream = util_fopen(tmp_file , "r");; + bool at_eof = false; + hash_clear(driver->bjobs_cache); + util_fskip_lines(stream , 1); + while (!at_eof) { + char * line = util_fscanf_alloc_line(stream , &at_eof); + if (line != NULL) { + int job_id_int; + + if (sscanf(line , "%d %s %s", &job_id_int , user , status) == 3) { + char * job_id = util_alloc_sprintf("%d" , job_id_int); + + if (hash_has_key( driver->my_jobs , job_id )) /* Consider only jobs submitted by this ERT instance - not old jobs lying around from the same user. */ + hash_insert_int(driver->bjobs_cache , job_id , lsf_driver_get_status__( driver , status , job_id)); + + free(job_id); + } + free(line); + } + } + fclose(stream); + } + util_unlink_existing(tmp_file); + free(tmp_file); +} + + + +static int lsf_driver_get_job_status_libary(void * __driver , void * __job) { + if (__job == NULL) + /* the job has not been registered at all ... */ + return JOB_QUEUE_NOT_ACTIVE; + else { + int status; + lsf_driver_type * driver = lsf_driver_safe_cast( __driver ); +#ifdef HAVE_LSF_LIBRARY + lsf_job_type * job = lsf_job_safe_cast( __job ); + if (lsb_openjob( driver->lsb , job->lsf_jobnr) != 1) { + /* + Failed to get information about the job - we boldly assume + the following situation has occured: + + 1. The job is running happily along. + 2. The lsf deamon is not responding for a long time. + 3. The job finishes, and is eventually expired from the LSF job database. + 4. The lsf deamon answers again - but can not find the job... + + */ + fprintf(stderr,"Warning: failed to get status information for job:%ld - assuming it is finished. \n", job->lsf_jobnr); + status = JOB_QUEUE_DONE; + } else { + struct jobInfoEnt *job_info = lsb_readjob( driver->lsb ); + if (job->num_exec_host == 0) { + job->num_exec_host = job_info->numExHosts; + job->exec_host = util_alloc_stringlist_copy( (const char **) job_info->exHosts , job->num_exec_host); + } + status = job_info->status; + lsb_closejob(driver->lsb); + } +#else + lsf_driver_internal_error( driver ); +#endif + + return status; + } +} + + + + +static int lsf_driver_get_job_status_shell(void * __driver , void * __job) { + int status = JOB_STAT_NULL; + + if (__job != NULL) { + lsf_job_type * job = lsf_job_safe_cast( __job ); + lsf_driver_type * driver = lsf_driver_safe_cast( __driver ); + + { + /** + Updating the bjobs_table of the driver involves a significant change in + the internal state of the driver; that is semantically a bit + unfortunate because this is clearly a get() function; to protect + against concurrent updates of this table we use a mutex. + */ + pthread_mutex_lock( &driver->bjobs_mutex ); + { + if (difftime(time(NULL) , driver->last_bjobs_update) > driver->bjobs_refresh_interval) { + lsf_driver_update_bjobs_table(driver); + driver->last_bjobs_update = time( NULL ); + } + } + pthread_mutex_unlock( &driver->bjobs_mutex ); + + + if (hash_has_key( driver->bjobs_cache , job->lsf_jobnr_char) ) + status = hash_get_int(driver->bjobs_cache , job->lsf_jobnr_char); + else + /* + It might be running - but since job != NULL it is at least in the queue system. + */ + status = JOB_STAT_PEND; + + } + } + + return status; +} + + +job_status_type lsf_driver_convert_status( int lsf_status ) { + job_status_type job_status; + switch (lsf_status) { + case JOB_STAT_NULL: + job_status = JOB_QUEUE_NOT_ACTIVE; + break; + case JOB_STAT_PEND: + job_status = JOB_QUEUE_PENDING; + break; + case JOB_STAT_SSUSP: + job_status = JOB_QUEUE_RUNNING; + break; + case JOB_STAT_USUSP: + job_status = JOB_QUEUE_RUNNING; + break; + case JOB_STAT_PSUSP: + job_status = JOB_QUEUE_RUNNING; + break; + case JOB_STAT_RUN: + job_status = JOB_QUEUE_RUNNING; + break; + case JOB_STAT_DONE: + job_status = JOB_QUEUE_DONE; + break; + case JOB_STAT_EXIT: + job_status = JOB_QUEUE_EXIT; + break; + case JOB_STAT_UNKWN: // Have lost contact with one of the daemons. + job_status = JOB_QUEUE_EXIT; + break; + case 192: /* this 192 seems to pop up - where the fuck does it come frome ?? _pdone + _ususp ??? */ + job_status = JOB_QUEUE_DONE; + break; + default: + job_status = JOB_QUEUE_NOT_ACTIVE; + util_abort("%s: unrecognized lsf status code:%d \n",__func__ , lsf_status ); + } + return job_status; +} + + +int lsf_driver_get_job_status_lsf(void * __driver , void * __job) { + int lsf_status; + lsf_driver_type * driver = lsf_driver_safe_cast( __driver ); + + if (driver->submit_method == LSF_SUBMIT_INTERNAL) + lsf_status = lsf_driver_get_job_status_libary(__driver , __job); + else + lsf_status = lsf_driver_get_job_status_shell(__driver , __job); + + return lsf_status; +} + + + +job_status_type lsf_driver_get_job_status(void * __driver , void * __job) { + int lsf_status = lsf_driver_get_job_status_lsf( __driver , __job ); + return lsf_driver_convert_status( lsf_status ); +} + + + + +void lsf_driver_free_job(void * __job) { + lsf_job_type * job = lsf_job_safe_cast( __job ); + lsf_job_free(job); +} + + + +void lsf_driver_kill_job(void * __driver , void * __job) { + lsf_driver_type * driver = lsf_driver_safe_cast( __driver ); + lsf_job_type * job = lsf_job_safe_cast( __job ); + { + if (driver->submit_method == LSF_SUBMIT_INTERNAL) +#ifdef HAVE_LSF_LIBRARY + lsb_killjob( driver->lsb , job->lsf_jobnr); +#else + lsf_driver_internal_error( driver ); +#endif + else { + if (driver->submit_method == LSF_SUBMIT_REMOTE_SHELL) { + char ** argv = util_calloc( 2, sizeof * argv ); + argv[0] = driver->remote_lsf_server; + argv[1] = util_alloc_sprintf("%s %s" , driver->bkill_cmd , job->lsf_jobnr_char); + + util_fork_exec(driver->rsh_cmd , 2 , (const char **) argv , true , NULL , NULL , NULL , NULL , NULL); + + free( argv[1] ); + free( argv ); + } else if (driver->submit_method == LSF_SUBMIT_LOCAL_SHELL) + util_fork_exec(driver->bkill_cmd , 1 , (const char **) &job->lsf_jobnr_char , true , NULL , NULL , NULL , NULL , NULL); + } + } +} + + + + + +void * lsf_driver_submit_job(void * __driver , + const char * submit_cmd , + int num_cpu , + const char * run_path , + const char * job_name , + int argc, + const char ** argv ) { + lsf_driver_type * driver = lsf_driver_safe_cast( __driver ); + lsf_driver_assert_submit_method( driver ); + { + lsf_job_type * job = lsf_job_alloc(); + { + char * lsf_stdout = util_alloc_filename(run_path , job_name , "LSF-stdout"); + lsf_submit_method_enum submit_method = driver->submit_method; + pthread_mutex_lock( &driver->submit_lock ); + + if (submit_method == LSF_SUBMIT_INTERNAL) { + job->lsf_jobnr = lsf_driver_submit_internal_job( driver , run_path , job_name , submit_cmd , num_cpu , argc, argv); + } else { + job->lsf_jobnr = lsf_driver_submit_shell_job( driver , run_path , job_name , submit_cmd , num_cpu , argc, argv); + job->lsf_jobnr_char = util_alloc_sprintf("%ld" , job->lsf_jobnr); + hash_insert_ref( driver->my_jobs , job->lsf_jobnr_char , NULL ); + } + + pthread_mutex_unlock( &driver->submit_lock ); + free( lsf_stdout ); + } + + if (job->lsf_jobnr > 0) + return job; + else { + /* + The submit failed - the queue system shall handle + NULL return values. + */ + lsf_job_free(job); + return NULL; + } + } +} + + + +void lsf_driver_free(lsf_driver_type * driver ) { + util_safe_free(driver->login_shell); + util_safe_free(driver->queue_name); + util_safe_free(driver->resource_request ); + util_safe_free(driver->remote_lsf_server ); + util_safe_free(driver->rsh_cmd ); + free( driver->bkill_cmd ); + free( driver->bjobs_cmd ); + free( driver->bsub_cmd ); + + hash_free(driver->status_map); + hash_free(driver->bjobs_cache); + hash_free(driver->my_jobs); + +#ifdef HAVE_LSF_LIBRARY + if (driver->lsb != NULL) + lsb_free( driver->lsb ); +#endif + + free(driver); + driver = NULL; +} + +void lsf_driver_free__(void * __driver ) { + lsf_driver_type * driver = lsf_driver_safe_cast( __driver ); + lsf_driver_free( driver ); +} + + +static void lsf_driver_set_queue( lsf_driver_type * driver, const char * queue ) { + driver->queue_name = util_realloc_string_copy( driver->queue_name , queue); +} + + +static void lsf_driver_set_login_shell( lsf_driver_type * driver, const char * login_shell ) { + driver->login_shell = util_realloc_string_copy( driver->login_shell , login_shell); +} + +static void lsf_driver_set_rsh_cmd( lsf_driver_type * driver , const char * rsh_cmd) { + driver->rsh_cmd = util_realloc_string_copy( driver->rsh_cmd , rsh_cmd ); +} + +static void lsf_driver_set_bsub_cmd( lsf_driver_type * driver , const char * bsub_cmd) { + driver->bsub_cmd = util_realloc_string_copy( driver->bsub_cmd , bsub_cmd ); +} + +static void lsf_driver_set_bjobs_cmd( lsf_driver_type * driver , const char * bjobs_cmd) { + driver->bjobs_cmd = util_realloc_string_copy( driver->bjobs_cmd , bjobs_cmd ); +} + +static void lsf_driver_set_bkill_cmd( lsf_driver_type * driver , const char * bkill_cmd) { + driver->bkill_cmd = util_realloc_string_copy( driver->bkill_cmd , bkill_cmd ); +} + +static void lsf_driver_set_internal_submit( lsf_driver_type * driver) { + /* No remote server has been set - assuming we can issue proper library calls. */ + /* The BSUB_QUEUE variable must NOT be set when using the shell + function, because then stdout is redirected and read. */ + + util_setenv("BSUB_QUIET" , "yes"); + driver->submit_method = LSF_SUBMIT_INTERNAL; + util_safe_free( driver->remote_lsf_server ); + driver->remote_lsf_server = NULL; +} + + +static void lsf_driver_set_remote_server( lsf_driver_type * driver , const char * remote_server) { + if (remote_server == NULL) { +#ifdef HAVE_LSF_LIBRARY + if (driver->lsb) + lsf_driver_set_internal_submit( driver ); + else + lsf_driver_set_remote_server( driver , LOCAL_LSF_SERVER ); // If initializing the lsb layer failed we try the local shell commands. +#endif + } else { + driver->remote_lsf_server = util_realloc_string_copy( driver->remote_lsf_server , remote_server ); + util_unsetenv( "BSUB_QUIET" ); + { + char * tmp_server = util_alloc_strupr_copy( remote_server ); + + if (strcmp(tmp_server , LOCAL_LSF_SERVER) == 0) + driver->submit_method = LSF_SUBMIT_LOCAL_SHELL; + else if (strcmp(tmp_server , NULL_LSF_SERVER) == 0) // We trap the special string 'NULL' and call again with a true NULL pointer. + lsf_driver_set_remote_server( driver , NULL); + else + driver->submit_method = LSF_SUBMIT_REMOTE_SHELL; + + free( tmp_server ); + } + } +} + + + +lsf_submit_method_enum lsf_driver_get_submit_method( const lsf_driver_type * driver ) { + return driver->submit_method; +} + +/*****************************************************************/ +/* Generic functions for runtime manipulation of options. + + LSF_SERVER + LSF_QUEUE + LSF_RESOURCE +*/ + +bool lsf_driver_set_option( void * __driver , const char * option_key , const void * value) { + lsf_driver_type * driver = lsf_driver_safe_cast( __driver ); + bool has_option = true; + { + if (strcmp( LSF_RESOURCE , option_key ) == 0) + driver->resource_request = util_realloc_string_copy( driver->resource_request , value ); + else if (strcmp( LSF_SERVER , option_key) == 0) + lsf_driver_set_remote_server( driver , value ); + else if (strcmp( LSF_QUEUE , option_key) == 0) + lsf_driver_set_queue( driver , value ); + else if (strcmp( LSF_LOGIN_SHELL , option_key) == 0) + lsf_driver_set_login_shell( driver , value ); + else if (strcmp( LSF_RSH_CMD , option_key) == 0) + lsf_driver_set_rsh_cmd( driver , value ); + else if (strcmp( LSF_BSUB_CMD , option_key) == 0) + lsf_driver_set_bsub_cmd( driver , value ); + else if (strcmp( LSF_BJOBS_CMD , option_key) == 0) + lsf_driver_set_bjobs_cmd( driver , value ); + else if (strcmp( LSF_BKILL_CMD , option_key) == 0) + lsf_driver_set_bkill_cmd( driver , value ); + else + has_option = false; + } + return has_option; +} + + +const void * lsf_driver_get_option( const void * __driver , const char * option_key) { + const lsf_driver_type * driver = lsf_driver_safe_cast_const( __driver ); + { + if (strcmp( LSF_RESOURCE , option_key ) == 0) + return driver->resource_request; + else if (strcmp( LSF_SERVER , option_key ) == 0) + return driver->remote_lsf_server; + else if (strcmp( LSF_QUEUE , option_key ) == 0) + return driver->queue_name; + else if (strcmp( LSF_LOGIN_SHELL , option_key ) == 0) + return driver->login_shell; + else if (strcmp( LSF_RSH_CMD , option_key ) == 0) + return driver->rsh_cmd; + else if (strcmp( LSF_BJOBS_CMD , option_key ) == 0) + return driver->bjobs_cmd; + else if (strcmp( LSF_BSUB_CMD , option_key ) == 0) + return driver->bsub_cmd; + else if (strcmp( LSF_BKILL_CMD , option_key ) == 0) + return driver->bkill_cmd; + else { + util_abort("%s: option_id:%s not recognized for LSF driver \n",__func__ , option_key); + return NULL; + } + } +} + + + +bool lsf_driver_has_option( const void * __driver , const char * option_key) { + return false; +} + + + + +/*****************************************************************/ + +/* + Observe that this driver IS not properly initialized when returning + from this function, the option interface must be used to set the + keys: +*/ + +void lsf_driver_set_bjobs_refresh_interval( lsf_driver_type * driver , int refresh_interval) { + driver->bjobs_refresh_interval = refresh_interval; +} + + +static void lsf_driver_lib_init( lsf_driver_type * lsf_driver ) { +#ifdef HAVE_LSF_LIBRARY + memset(&lsf_driver->lsf_request , 0 , sizeof (lsf_driver->lsf_request)); + lsf_driver->lsf_request.beginTime = 0; + lsf_driver->lsf_request.termTime = 0; + lsf_driver->lsf_request.numProcessors = 1; + lsf_driver->lsf_request.maxNumProcessors = 1; + { + int i; + for (i=0; i < LSF_RLIM_NLIMITS; i++) + lsf_driver->lsf_request.rLimits[i] = DEFAULT_RLIMIT; + } + lsf_driver->lsf_request.options2 = 0; + + lsf_driver->lsb = lsb_alloc(); + if (lsb_ready(lsf_driver->lsb)) + lsb_initialize(lsf_driver->lsb); + else { + lsb_free( lsf_driver->lsb ); + lsf_driver->lsb = NULL; + } +#endif +} + + + +static void lsf_driver_shell_init( lsf_driver_type * lsf_driver ) { + lsf_driver->last_bjobs_update = time( NULL ); + lsf_driver->bjobs_cache = hash_alloc(); + lsf_driver->my_jobs = hash_alloc(); + lsf_driver->status_map = hash_alloc(); + lsf_driver->bsub_cmd = NULL; + lsf_driver->bjobs_cmd = NULL; + lsf_driver->bkill_cmd = NULL; + + + hash_insert_int(lsf_driver->status_map , "PEND" , JOB_STAT_PEND); + hash_insert_int(lsf_driver->status_map , "SSUSP" , JOB_STAT_SSUSP); + hash_insert_int(lsf_driver->status_map , "PSUSP" , JOB_STAT_PSUSP); + hash_insert_int(lsf_driver->status_map , "USUSP" , JOB_STAT_USUSP); + hash_insert_int(lsf_driver->status_map , "RUN" , JOB_STAT_RUN); + hash_insert_int(lsf_driver->status_map , "EXIT" , JOB_STAT_EXIT); + hash_insert_int(lsf_driver->status_map , "DONE" , JOB_STAT_DONE); + hash_insert_int(lsf_driver->status_map , "UNKWN" , JOB_STAT_UNKWN); /* Uncertain about this one */ + pthread_mutex_init( &lsf_driver->bjobs_mutex , NULL ); +} + + + +void * lsf_driver_alloc( ) { + lsf_driver_type * lsf_driver = util_malloc(sizeof * lsf_driver ); + UTIL_TYPE_ID_INIT( lsf_driver , LSF_DRIVER_TYPE_ID); + lsf_driver->submit_method = LSF_SUBMIT_INVALID; + lsf_driver->login_shell = NULL; + lsf_driver->queue_name = NULL; + lsf_driver->remote_lsf_server = NULL; + lsf_driver->rsh_cmd = NULL; + lsf_driver->resource_request = NULL; + lsf_driver_set_bjobs_refresh_interval( lsf_driver , BJOBS_REFRESH_TIME ); + pthread_mutex_init( &lsf_driver->submit_lock , NULL ); + + lsf_driver_lib_init( lsf_driver ); + lsf_driver_shell_init( lsf_driver ); + + lsf_driver_set_option( lsf_driver , LSF_SERVER , NULL ); + lsf_driver_set_option( lsf_driver , LSF_RSH_CMD , DEFAULT_RSH_CMD ); + lsf_driver_set_option( lsf_driver , LSF_BSUB_CMD , DEFAULT_BSUB_CMD ); + lsf_driver_set_option( lsf_driver , LSF_BJOBS_CMD , DEFAULT_BJOBS_CMD ); + lsf_driver_set_option( lsf_driver , LSF_BKILL_CMD , DEFAULT_BKILL_CMD ); + return lsf_driver; +} + + +/*****************************************************************/ + diff --git a/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver_dummy.c b/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver_dummy.c deleted file mode 100644 index b1e6917b9d..0000000000 --- a/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver_dummy.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'lsf_driver_dummy.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT 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. - - ERT 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 - - -static void lsf_driver_invalid_usage( const char * func) { - fprintf(stderr,"\n\n"); - fprintf(stderr,"-----------------------------------------------------------------\n"); - fprintf(stderr,"You have called the function %s() from the \n", func); - fprintf(stderr,"LSF driver. The current lsf_driver is only a dummy driver, \n"); - fprintf(stderr,"and not capable of actually doing proper things. You must \n"); - fprintf(stderr,"select another driver to run your simulations.\n"); - fprintf(stderr,"\n"); - fprintf(stderr,"If your computing site has access to LSF the current version \n"); - fprintf(stderr,"of the LSF driver must be recompiled: \n"); - fprintf(stderr,"\n"); - fprintf(stderr," 1. Rebuild the lsf_driver with the preprossor symbol \'INCLUDE_LSF\' defined.\n"); - fprintf(stderr," 2. Relink the whole application - with the libraries \'libbat\', \'libnsl\' and \'liblsf\'.\n"); - fprintf(stderr,"\n"); - fprintf(stderr,"-----------------------------------------------------------------\n"); - exit(1); -} - -job_status_type lsf_driver_get_job_status(void * driver , void * job) { - return 0; -} - - - -void lsf_driver_free_job(void * job) { - lsf_driver_invalid_usage( __func__ ); -} - - - -void lsf_driver_kill_job(void * driver , void * job) { - lsf_driver_invalid_usage( __func__ ); -} - - - - - -void * lsf_driver_submit_job(void * driver , - const char * submit_cmd , - int num_cpu , - const char * run_path , - const char * job_name , - int argc , - const char ** argv ) { - lsf_driver_invalid_usage( __func__ ); - return NULL; -} - - - -void lsf_driver_free(lsf_driver_type * driver ) { - /* No op */ -} - -void lsf_driver_free__(void * driver ) { - /* No op */ -} - - -bool lsf_driver_set_option( void * driver , const char * option_key , const void * value) { - return false; -} - - -const void * lsf_driver_get_option( const void * driver , const char * option_key) { - return NULL; -} - - - -bool lsf_driver_has_option( const void * driver , const char * option_key) { - return false; -} - -/*****************************************************************/ - - - -void * lsf_driver_alloc( ) { - fprintf(stderr,"** Warning - this is an unfunctional LSF driver ** \n"); - return NULL; -} - - -/*****************************************************************/ diff --git a/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver_impl.c b/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver_impl.c index 4dabc8d70e..cbfa8b9eb0 100644 --- a/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver_impl.c +++ b/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver_impl.c @@ -214,10 +214,24 @@ stringlist_type * lsf_driver_alloc_cmd(lsf_driver_type * driver , stringlist_type * argv = stringlist_alloc_new(); char * num_cpu_string = util_alloc_sprintf("%d" , num_cpu); char * quoted_resource_request = NULL; - - if (driver->resource_request != NULL) - quoted_resource_request = util_alloc_sprintf("\"%s\"" , driver->resource_request); + /* + The resource request string contains spaces, and when passed + through the shell it must be protected with \"..\"; this applies + when submitting to a remote lsf server with ssh. However when + submitting to the local workstation using a bsub command the + command will be invoked with the util_fork_exec() command - and no + shell is involved. In this latter case we must avoid the \"...\" + quoting. + */ + + if (driver->resource_request != NULL) { + if (driver->submit_method == LSF_SUBMIT_REMOTE_SHELL) + quoted_resource_request =util_alloc_sprintf("\"%s\"" , driver->resource_request); + else + quoted_resource_request = util_alloc_string_copy( driver->resource_request ); + } + if (driver->submit_method == LSF_SUBMIT_REMOTE_SHELL) stringlist_append_ref( argv , driver->bsub_cmd); @@ -317,6 +331,7 @@ static int lsf_driver_submit_shell_job(lsf_driver_type * driver , int job_id; char * tmp_file = util_alloc_tmp_file("/tmp" , "enkf-submit" , true); + printf("remote_lsf_server: %s \n",driver->remote_lsf_server); if (driver->remote_lsf_server != NULL) { stringlist_type * remote_argv = lsf_driver_alloc_cmd( driver , lsf_stdout , job_name , submit_cmd , num_cpu , job_argc , job_argv); if (driver->submit_method == LSF_SUBMIT_REMOTE_SHELL) { diff --git a/ThirdParty/Ert/devel/libjob_queue/src/rsh_driver.c b/ThirdParty/Ert/devel/libjob_queue/src/rsh_driver.c index a4df97372b..f7725f4d93 100644 --- a/ThirdParty/Ert/devel/libjob_queue/src/rsh_driver.c +++ b/ThirdParty/Ert/devel/libjob_queue/src/rsh_driver.c @@ -119,11 +119,15 @@ static bool rsh_host_available(rsh_host_type * rsh_host) { bool available; pthread_mutex_lock( &rsh_host->host_mutex ); - if ((rsh_host->max_running - rsh_host->running) > 0) { - available = true; - rsh_host->running++; - } else + { available = false; + if ((rsh_host->max_running - rsh_host->running) > 0) { // The host has free slots() + if (util_ping( rsh_host->host_name )) { // The host answers to ping() + available = true; + rsh_host->running++; + } + } + } pthread_mutex_unlock( &rsh_host->host_mutex ); return available; diff --git a/ThirdParty/Ert/devel/libjob_queue/src/workflow.c b/ThirdParty/Ert/devel/libjob_queue/src/workflow.c new file mode 100644 index 0000000000..1ea7a60c1e --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/src/workflow.c @@ -0,0 +1,229 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'workflow.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#define CMD_TYPE_ID 66153 +#define WORKFLOW_TYPE_ID 6762081 +#define WORKFLOW_COMMENT_STRING "--" +#define WORKFLOW_INCLUDE "INCLUDE" + +typedef struct cmd_struct cmd_type; + +struct cmd_struct { + UTIL_TYPE_ID_DECLARATION; + const workflow_job_type * workflow_job; + stringlist_type * arglist; +}; + + + + +struct workflow_struct { + UTIL_TYPE_ID_DECLARATION; + time_t compile_time; + bool compiled; + char * src_file; + vector_type * cmd_list; + workflow_joblist_type * joblist; + config_error_type * last_error; +}; + +/*****************************************************************/ + + +static cmd_type * cmd_alloc( const workflow_job_type * workflow_job , const stringlist_type * arglist) { + cmd_type * cmd = util_malloc( sizeof * cmd ); + UTIL_TYPE_ID_INIT(cmd , CMD_TYPE_ID ); + cmd->workflow_job = workflow_job; + cmd->arglist = stringlist_alloc_deep_copy( arglist ); + return cmd; +} + +static UTIL_SAFE_CAST_FUNCTION( cmd , CMD_TYPE_ID ); + +static void cmd_free( cmd_type * cmd ){ + stringlist_free( cmd->arglist ); + free( cmd ); +} + +static void cmd_free__( void * arg ) { + cmd_type * cmd = cmd_safe_cast( arg ); + cmd_free( cmd ); +} + +/*****************************************************************/ + +static void workflow_add_cmd( workflow_type * workflow , cmd_type * cmd ) { + vector_append_owned_ref( workflow->cmd_list , cmd , cmd_free__ ); +} + + +static void workflow_clear( workflow_type * workflow ) { + vector_clear( workflow->cmd_list ); +} + +static void workflow_store_error( workflow_type * workflow , const config_error_type * error) { + if (workflow->last_error) + config_error_free( workflow->last_error ); + + if (error) + workflow->last_error = config_error_alloc_copy( error ); + else + workflow->last_error = NULL; +} + + + + +static bool workflow_try_compile( workflow_type * script , const subst_list_type * context) { + if (util_file_exists( script->src_file )) { + const char * src_file = script->src_file; + char * tmp_file = NULL; + bool update = false; + if (context != NULL) { + tmp_file = util_alloc_tmp_file("/tmp" , "ert-workflow" , false ); + update = subst_list_filter_file( context , script->src_file , tmp_file ); + if (update) { + script->compiled = false; + src_file = tmp_file; + } else { + remove( tmp_file ); + free( tmp_file ); + tmp_file = NULL; + } + } + + { + time_t src_mtime = util_file_mtime( script->src_file ); + if (script->compiled) { + if (util_difftime_seconds( src_mtime , script->compile_time ) > 0 ) + return true; + else { + // Script has been compiled succesfully, but then changed afterwards. + // We try to recompile; if that fails we are left with 'nothing'. + } + } + } + + { + // Try to compile + config_type * config_compiler = workflow_joblist_get_compiler( script->joblist ); + script->compiled = false; + workflow_clear( script ); + config_clear( config_compiler ); + { + if (config_parse( config_compiler , src_file , WORKFLOW_COMMENT_STRING , WORKFLOW_INCLUDE , NULL , CONFIG_UNRECOGNIZED_ERROR , true )) { + int cmd_line; + for (cmd_line = 0; cmd_line < config_get_content_size(config_compiler); cmd_line++) { + const config_content_node_type * node = config_iget_content_node( config_compiler , cmd_line ); + const char * jobname = config_content_node_get_kw( node ); + const workflow_job_type * job = workflow_joblist_get_job( script->joblist , jobname ); + cmd_type * cmd = cmd_alloc( job , config_content_node_get_stringlist( node )); + + workflow_add_cmd( script , cmd ); + } + script->compiled = true; + } else + workflow_store_error( script , config_get_errors( config_compiler )); + } + } + + if (tmp_file != NULL) { + if (script->compiled) + remove( tmp_file ); + free( tmp_file ); + } + } + + // It is legal to remove the script after successfull compilation but + // then the context will not be applied at subsequent invocations. + return script->compiled; +} + + +bool workflow_run(workflow_type * workflow , void * self , bool verbose , const subst_list_type * context) { + workflow_try_compile( workflow , context); + + if (workflow->compiled) { + int icmd; + for (icmd = 0; icmd < vector_get_size( workflow->cmd_list ); icmd++) { + const cmd_type * cmd = vector_iget_const( workflow->cmd_list , icmd ); + workflow_job_run( cmd->workflow_job , self , verbose , cmd->arglist ); + } + return true; + } else + return false; +} + + + +workflow_type * workflow_alloc( const char * src_file , workflow_joblist_type * joblist) { + workflow_type * script = util_malloc( sizeof * script ); + UTIL_TYPE_ID_INIT( script , WORKFLOW_TYPE_ID ); + + script->src_file = util_alloc_string_copy( src_file ); + script->joblist = joblist; + script->cmd_list = vector_alloc_new(); + script->compiled = false; + script->last_error = NULL; + + workflow_try_compile( script , NULL ); + return script; +} + + +static UTIL_SAFE_CAST_FUNCTION( workflow , WORKFLOW_TYPE_ID ) + + +void workflow_free( workflow_type * workflow ) { + free( workflow->src_file ); + vector_free( workflow->cmd_list ); + + if (workflow->last_error) + config_error_free( workflow->last_error ); + + free( workflow ); +} + + +void workflow_free__( void * arg ) { + workflow_type * workflow = workflow_safe_cast( arg ); + workflow_free( workflow ); +} + + +const config_error_type * workflow_get_last_error( const workflow_type * workflow) { + return workflow->last_error; +} diff --git a/ThirdParty/Ert/devel/libjob_queue/src/workflow_job.c b/ThirdParty/Ert/devel/libjob_queue/src/workflow_job.c new file mode 100644 index 0000000000..7a25e7fc72 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/src/workflow_job.c @@ -0,0 +1,356 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'workflow_job.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include +#include + +#include + +#include + + +/* The default values are interepreted as no limit. */ +#define DEFAULT_INTERNAL false + + +#define MIN_ARG_KEY "MIN_ARG" +#define MAX_ARG_KEY "MAX_ARG" +#define ARG_TYPE_KEY "ARG_TYPE" +#define INTERNAL_KEY "INTERNAL" +#define MODULE_KEY "MODULE" +#define FUNCTION_KEY "FUNCTION" +#define EXECUTABLE_KEY "EXECUTABLE" + +#define NULL_STRING "NULL" +#define WORKFLOW_JOB_STRING_TYPE "STRING" +#define WORKFLOW_JOB_INT_TYPE "INT" +#define WORKFLOW_JOB_FLOAT_TYPE "FLOAT" + +#define WORKFLOW_JOB_TYPE_ID 614441 + + +struct workflow_job_struct { + UTIL_TYPE_ID_DECLARATION; + bool internal; + int min_arg; + int max_arg; + int_vector_type * arg_types; // Should contain values from the config_item_types enum in config.h. + char * executable; + char * module; + char * function; + char * name; + void * lib_handle; + workflow_job_ftype * dl_func; + bool valid; +}; + + +bool workflow_job_internal( const workflow_job_type * workflow_job ) { + return workflow_job->internal; +} + +const char * workflow_job_get_name( const workflow_job_type * workflow_job ) { + return workflow_job->name; +} + + +config_type * workflow_job_alloc_config() { + config_type * config = config_alloc(); + { + config_schema_item_type * item; + + item = config_add_schema_item( config , MIN_ARG_KEY , false ); + config_schema_item_set_argc_minmax( item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_INT ); + + item = config_add_schema_item( config , MAX_ARG_KEY , false ); + config_schema_item_set_argc_minmax( item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_INT ); + + item = config_add_schema_item( config , ARG_TYPE_KEY , false ); + config_schema_item_set_argc_minmax( item , 2 , 2 ); + config_schema_item_iset_type( item , 0 , CONFIG_INT ); + config_schema_item_set_indexed_selection_set( item , 1 , 3 , (const char *[3]) {WORKFLOW_JOB_STRING_TYPE , WORKFLOW_JOB_INT_TYPE , WORKFLOW_JOB_FLOAT_TYPE}); + + /*****************************************************************/ + item = config_add_schema_item( config , EXECUTABLE_KEY , false ); + config_schema_item_set_argc_minmax( item , 1 , 1 ); + config_schema_item_iset_type( item , 0 , CONFIG_PATH ); + + /*---------------------------------------------------------------*/ + + item = config_add_schema_item( config , FUNCTION_KEY , false ); + config_schema_item_set_argc_minmax( item , 1 , 1); + + item = config_add_schema_item( config , MODULE_KEY , false ); + config_schema_item_set_argc_minmax( item , 1 , 1); + /*****************************************************************/ + + item = config_add_schema_item( config , INTERNAL_KEY , false ); + config_schema_item_set_argc_minmax( item , 1 , 1); + config_schema_item_iset_type( item , 0 , CONFIG_BOOL); + } + return config; +} + + + +static UTIL_SAFE_CAST_FUNCTION(workflow_job , WORKFLOW_JOB_TYPE_ID ); + +void workflow_job_update_config_compiler( const workflow_job_type * workflow_job , config_type * config_compiler ) { + config_schema_item_type * item = config_add_schema_item( config_compiler , workflow_job->name , false ); + /* + Ensure that the arg_types mapping is at least as large as the + max_arg value. The arg_type vector will be left padded with + CONFIG_STRING values. + */ + { + int iarg; + config_schema_item_set_argc_minmax( item , workflow_job->min_arg , workflow_job->max_arg ); + for (iarg = 0; iarg < int_vector_size( workflow_job->arg_types ); iarg++) + config_schema_item_iset_type( item , iarg , int_vector_iget( workflow_job->arg_types , iarg )); + } +} + + +workflow_job_type * workflow_job_alloc( const char * name , bool internal ) { + workflow_job_type * workflow_job = util_malloc( sizeof * workflow_job ); + UTIL_TYPE_ID_INIT( workflow_job , WORKFLOW_JOB_TYPE_ID ); + workflow_job->internal = internal; // this can not be changed run-time. + workflow_job->min_arg = CONFIG_DEFAULT_ARG_MIN; + workflow_job->max_arg = CONFIG_DEFAULT_ARG_MAX; + workflow_job->arg_types = int_vector_alloc( 0 , CONFIG_STRING ); + + workflow_job->executable = NULL; + workflow_job->module = NULL; + workflow_job->function = NULL; + + if (name == NULL) + util_abort("%s: trying to create workflow_job with name == NULL - illegal\n",__func__); + else + workflow_job->name = util_alloc_string_copy( name ); + + workflow_job->valid = false; + + return workflow_job; +} + + +void workflow_job_set_executable( workflow_job_type * workflow_job , const char * executable ) { + workflow_job->executable = util_realloc_string_copy( workflow_job->executable , executable ); +} + + +void workflow_job_set_module( workflow_job_type * workflow_job , const char * module) { + if (strcmp(module ,NULL_STRING) == 0) + module = NULL; + + workflow_job->module = util_realloc_string_copy( workflow_job->module , module ); +} + + +void workflow_job_set_function( workflow_job_type * workflow_job , const char * function) { + workflow_job->function = util_realloc_string_copy( workflow_job->function , function ); +} + + +void workflow_job_iset_argtype( workflow_job_type * workflow_job , int iarg , config_item_types type) { + if (type == CONFIG_STRING || type == CONFIG_INT || type == CONFIG_FLOAT) + int_vector_iset( workflow_job->arg_types , iarg , type ); +} + +void workflow_job_set_min_arg( workflow_job_type * workflow_job , int min_arg) { + workflow_job->min_arg = min_arg; +} + +void workflow_job_set_max_arg( workflow_job_type * workflow_job , int max_arg) { + workflow_job->max_arg = max_arg; +} + +int workflow_job_get_min_arg( const workflow_job_type * workflow_job ) { + return workflow_job->min_arg; +} + +int workflow_job_get_max_arg( workflow_job_type * workflow_job ) { + return workflow_job->max_arg; +} + + + +static void workflow_job_iset_argtype_string( workflow_job_type * workflow_job , int iarg , const char * arg_type) { + config_item_types type = CONFIG_INVALID; + + if (strcmp( arg_type , WORKFLOW_JOB_STRING_TYPE) == 0) + type = CONFIG_STRING; + else if (strcmp( arg_type , WORKFLOW_JOB_INT_TYPE) == 0) + type = CONFIG_INT; + else if (strcmp( arg_type , WORKFLOW_JOB_FLOAT_TYPE) == 0) + type = CONFIG_FLOAT; + + if (type != CONFIG_INVALID) + workflow_job_iset_argtype( workflow_job , iarg , type ); + +} + + +static void workflow_job_validate_internal( workflow_job_type * workflow_job ) { + if ((workflow_job->executable == NULL) && (workflow_job->function != NULL)) { + workflow_job->lib_handle = dlopen( workflow_job->module , RTLD_NOW ); + if (workflow_job->lib_handle != NULL) { + workflow_job->dl_func = (workflow_job_ftype *) dlsym( workflow_job->lib_handle , workflow_job->function ); + if (workflow_job->dl_func != NULL) + workflow_job->valid = true; + else + fprintf(stderr,"Failed to load symbol:%s Error:%s \n",workflow_job->function , dlerror()); + } else { + if (workflow_job->module != NULL) + fprintf(stderr,"Failed to load module:%s Error:%s \n",workflow_job->module , dlerror()); + } + } else + fprintf(stderr,"Must have executable == NULL and function != NULL for internal jobs \n"); +} + + +static void workflow_job_validate_external( workflow_job_type * workflow_job ) { + if (workflow_job->executable != NULL) { + if (util_is_executable( workflow_job->executable ) && + (workflow_job->module == workflow_job->function) && + (workflow_job->module == NULL)) + workflow_job->valid = true; + } +} + + + +static void workflow_job_validate( workflow_job_type * workflow_job ) { + if (workflow_job->internal) + workflow_job_validate_internal( workflow_job ); + else + workflow_job_validate_external( workflow_job ); +} + + + + +workflow_job_type * workflow_job_config_alloc( const char * name , config_type * config , const char * config_file) { + config_clear( config ); + if (config_parse( config , config_file , "--", NULL , NULL , CONFIG_UNRECOGNIZED_WARN , true)) { + bool internal = DEFAULT_INTERNAL; + if (config_item_set( config , INTERNAL_KEY)) + internal = config_iget_as_bool( config , INTERNAL_KEY , 0 , 0 ); + + { + workflow_job_type * workflow_job = workflow_job_alloc( name , internal ); + + if (config_item_set( config , MIN_ARG_KEY)) + workflow_job_set_min_arg( workflow_job , config_iget_as_int( config , MIN_ARG_KEY , 0 , 0 )); + + if (config_item_set( config , MAX_ARG_KEY)) + workflow_job_set_max_arg( workflow_job , config_iget_as_int( config , MAX_ARG_KEY , 0 , 0 )); + + { + int i; + for (i=0; i < config_get_occurences( config , ARG_TYPE_KEY); i++) { + int iarg = config_iget_as_int( config , ARG_TYPE_KEY , i , 0 ); + const char * arg_type = config_iget( config , ARG_TYPE_KEY , i , 1 ); + + workflow_job_iset_argtype_string( workflow_job , iarg , arg_type ); + } + } + + if (config_item_set( config , MODULE_KEY)) + workflow_job_set_module( workflow_job , config_get_value( config , MODULE_KEY)); // Could be a pure so name; or a full path ..... Like executable + + if (config_item_set( config , FUNCTION_KEY)) + workflow_job_set_function( workflow_job , config_get_value( config , FUNCTION_KEY)); + + if (config_item_set( config , EXECUTABLE_KEY)) + workflow_job_set_executable( workflow_job , config_get_value_as_abspath( config , EXECUTABLE_KEY)); + + workflow_job_validate( workflow_job ); + + if (!workflow_job->valid) { + workflow_job_free( workflow_job ); + workflow_job = NULL; + } + + return workflow_job; + } + } else + return NULL; +} + + + + +void workflow_job_free( workflow_job_type * workflow_job ) { + util_safe_free( workflow_job->module ); + util_safe_free( workflow_job->function ); + util_safe_free( workflow_job->executable ); + int_vector_free( workflow_job->arg_types ); + free( workflow_job->name ); + free( workflow_job ); +} + + +void workflow_job_free__( void * arg) { + workflow_job_type * workflow_job = workflow_job_safe_cast( arg ); + workflow_job_free( workflow_job ); +} + + + +static void workflow_job_run_internal( const workflow_job_type * job , void * self , bool verbose , const stringlist_type * arg) { + job->dl_func( self , arg ); +} + + +static void workflow_job_run_external( const workflow_job_type * job , bool verbose , const stringlist_type * arg) { + char ** argv = stringlist_alloc_char_copy( arg ); + + util_fork_exec( job->executable , + stringlist_get_size( arg ), + (const char **) argv , + true , + NULL , + NULL , + NULL , + NULL , + NULL ); + + + if (argv != NULL) { + int i; + for (i=0; i < stringlist_get_size( arg ); i++) + free( argv[i] ); + free( argv ); + } +} + + +void workflow_job_run( const workflow_job_type * job , void * self , bool verbose , const stringlist_type * arg) { + if (job->internal) + workflow_job_run_internal( job , self , verbose , arg ); + else + workflow_job_run_external( job , verbose , arg ); +} diff --git a/ThirdParty/Ert/devel/libjob_queue/src/workflow_joblist.c b/ThirdParty/Ert/devel/libjob_queue/src/workflow_joblist.c new file mode 100644 index 0000000000..8d64d3de30 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/src/workflow_joblist.c @@ -0,0 +1,85 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'workflow_joblist.c' is part of ERT - Ensemble based + Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include + + +struct workflow_joblist_struct { + config_type * workflow_compiler; + config_type * job_config; + + hash_type * joblist; +}; + + +workflow_joblist_type * workflow_joblist_alloc( ) { + workflow_joblist_type * joblist = util_malloc( sizeof * joblist ); + + joblist->job_config = workflow_job_alloc_config(); + joblist->workflow_compiler = config_alloc(); + joblist->joblist = hash_alloc(); + + return joblist; +} + + +void workflow_joblist_free( workflow_joblist_type * joblist) { + config_free( joblist->job_config ); + config_free( joblist->workflow_compiler ); + hash_free( joblist->joblist ); + free( joblist ); +} + + +const workflow_job_type * workflow_joblist_get_job( const workflow_joblist_type * joblist , const char * job_name) { + return hash_get( joblist->joblist , job_name ); +} + + +void workflow_joblist_add_job( workflow_joblist_type * joblist , const workflow_job_type * job) { + hash_insert_hash_owned_ref( joblist->joblist , workflow_job_get_name( job ) , job , workflow_job_free__ ); + workflow_job_update_config_compiler( job , joblist->workflow_compiler ); +} + + +bool workflow_joblist_add_job_from_file( workflow_joblist_type * joblist , const char * job_name , const char * config_file ) { + workflow_job_type * job = workflow_job_config_alloc( job_name , joblist->job_config , config_file ); + if (job != NULL) { + workflow_joblist_add_job( joblist , job ); + return true; + } else + return false; +} + + +config_type * workflow_joblist_get_compiler( const workflow_joblist_type * joblist ) { + return joblist->workflow_compiler; +} diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/CMakeLists.txt b/ThirdParty/Ert/devel/libjob_queue/tests/CMakeLists.txt index e0087469e4..0b80bba663 100644 --- a/ThirdParty/Ert/devel/libjob_queue/tests/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libjob_queue/tests/CMakeLists.txt @@ -1,11 +1,37 @@ +add_executable( job_loadOK job_loadOK.c ) +add_executable( job_loadFail job_loadFail.c ) +add_executable( create_file create_file.c ) +add_executable( job_workflow_test job_workflow_test.c ) + + +target_link_libraries( job_workflow_test job_queue ) +target_link_libraries( create_file job_queue ) +target_link_libraries( job_loadOK job_queue ) +target_link_libraries( job_loadFail job_queue ) + + +add_test( job_workflow_test ${EXECUTABLE_OUTPUT_PATH}/job_workflow_test ${EXECUTABLE_OUTPUT_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/data/internal_job) + +add_test( job_loadOK1 ${EXECUTABLE_OUTPUT_PATH}/job_loadOK ${CMAKE_CURRENT_SOURCE_DIR}/data/internalOK) +add_test( job_loadOK2 ${EXECUTABLE_OUTPUT_PATH}/job_loadOK ${CMAKE_CURRENT_SOURCE_DIR}/data/externalOK) +add_test( job_loadOK3 ${EXECUTABLE_OUTPUT_PATH}/job_loadOK ${CMAKE_CURRENT_SOURCE_DIR}/data/internalOK ${CMAKE_CURRENT_SOURCE_DIR}/data/externalOK) + +add_test( job_loadFail1 ${EXECUTABLE_OUTPUT_PATH}/job_loadFail ${CMAKE_CURRENT_SOURCE_DIR}/data/internalFail) +add_test( job_loadFail2 ${EXECUTABLE_OUTPUT_PATH}/job_loadFail ${CMAKE_CURRENT_SOURCE_DIR}/data/externalFail) +add_test( job_loadFail3 ${EXECUTABLE_OUTPUT_PATH}/job_loadFail ${CMAKE_CURRENT_SOURCE_DIR}/data/internalFail ${CMAKE_CURRENT_SOURCE_DIR}/data/externalFail) + + +add_executable( job_queue_test job_queue_test.c ) +target_link_libraries( job_queue_test job_queue ) +add_test( job_queue_test ${EXECUTABLE_OUTPUT_PATH}/job_queue_test ) + + # This should be a space separated list of servers which will be # tried out when testing the LSF submit capability. The test program # will interpret the special string 'NULL' as submit with library # functions. set(LSF_SERVERS "LOCAL NULL" CACHE STRING "List of LSF servers for testing") -add_executable( loadOK loadOK.c ) -target_link_libraries( loadOK job_queue util ) add_executable( job_lsf_test job_lsf_test.c ) target_link_libraries( job_lsf_test job_queue util ) @@ -15,7 +41,13 @@ target_link_libraries( job_lsf_submit_test job_queue util ) add_executable( job_program job_program.c ) -add_test( loadOK ${EXECUTABLE_OUTPUT_PATH}/loadOK ${CMAKE_CURRENT_SOURCE_DIR}/data/internalOK) +if (HAVE_LSF_LIBRARY) + add_executable( job_lsb job_lsb.c ) + target_link_libraries( job_lsb job_queue util ) + add_test( job_lsb ${EXECUTABLE_OUTPUT_PATH}/job_lsb ) +endif() + + add_test( job_lsf_test ${EXECUTABLE_OUTPUT_PATH}/job_lsf_test ) if (LSF_SERVERS) add_test( job_lsf_submit_test ${EXECUTABLE_OUTPUT_PATH}/job_lsf_submit_test ${EXECUTABLE_OUTPUT_PATH}/job_program ${LSF_SERVERS}) diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/create_file.c b/ThirdParty/Ert/devel/libjob_queue/tests/create_file.c new file mode 100644 index 0000000000..fbba657756 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/create_file.c @@ -0,0 +1,28 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'create_file.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + + +int main( int argc , char ** argv) { + char * filename = argv[1]; + int value = atoi( argv[2] ); + FILE * stream = fopen( filename , "w"); + fprintf(stream , "%d\n", value ); + fclose( stream ); +} diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/data/externalFail b/ThirdParty/Ert/devel/libjob_queue/tests/data/externalFail new file mode 100644 index 0000000000..0f53d812c3 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/data/externalFail @@ -0,0 +1,5 @@ +INTERNAL False +MIN_ARG 1 +MAX_ARG 2 +ARG_TYPE 0 STRING +ARG_TYPE 1 INT diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/data/externalOK b/ThirdParty/Ert/devel/libjob_queue/tests/data/externalOK new file mode 100644 index 0000000000..67dec0bef2 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/data/externalOK @@ -0,0 +1,6 @@ +INTERNAL False +EXECUTABLE /usr/bin/python +MIN_ARG 1 +MAX_ARG 2 +ARG_TYPE 0 STRING +ARG_TYPE 1 INT diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/data/external_job b/ThirdParty/Ert/devel/libjob_queue/tests/data/external_job new file mode 100644 index 0000000000..5b39223101 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/data/external_job @@ -0,0 +1,5 @@ +EXECUTABLE /private/joaho/ERT/git/ert/build/bin/create_file +ARG_TYPE 0 STRING +ARG_TYPE 1 INT +MIN_ARG 2 +MAX_ARG 2 \ No newline at end of file diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/data/internalFail b/ThirdParty/Ert/devel/libjob_queue/tests/data/internalFail new file mode 100644 index 0000000000..40686fc1d5 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/data/internalFail @@ -0,0 +1,6 @@ +INTERNAL True +MODULE NULL +MIN_ARG 1 +MAX_ARG 2 +ARG_TYPE 0 STRING +ARG_TYPE 1 INT diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/data/internalOK b/ThirdParty/Ert/devel/libjob_queue/tests/data/internalOK index b88ef7dffa..6252998faa 100644 --- a/ThirdParty/Ert/devel/libjob_queue/tests/data/internalOK +++ b/ThirdParty/Ert/devel/libjob_queue/tests/data/internalOK @@ -1,6 +1,6 @@ INTERNAL True MODULE NULL -FUNCTION ext_cmd_alloc +FUNCTION workflow_job_alloc MIN_ARG 1 MAX_ARG 2 ARG_TYPE 0 STRING diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/data/internal_job b/ThirdParty/Ert/devel/libjob_queue/tests/data/internal_job new file mode 100644 index 0000000000..2c86544a44 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/data/internal_job @@ -0,0 +1,5 @@ +INTERNAL True +FUNCTION read_file +ARG_TYPE 0 STRING +MIN_ARG 1 +MAX_ARG 1 diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/job_loadFail.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_loadFail.c new file mode 100644 index 0000000000..6201572c36 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_loadFail.c @@ -0,0 +1,60 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'job_loadFail.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include + +#include + + + +bool loadConfig(config_type * config , const char * config_file, config_type * config_compiler) { + bool OK = false; + workflow_job_type * cmd = workflow_job_config_alloc( "NAME" , config , config_file); + + if (cmd != NULL) { + OK = true; + workflow_job_update_config_compiler( cmd , config_compiler ); + workflow_job_free( cmd ); + } + + return OK; +} + + + +int main( int argc , char ** argv) { + int status = 0; + { + config_type * config = workflow_job_alloc_config(); + config_type * config_compiler = config_alloc(); + int iarg; + bool OK = true; + + for (iarg = 1; iarg < argc; iarg++) + OK = OK && (loadConfig( config , argv[iarg] , config_compiler ) == false); + + if (!OK) + status = 1; + + config_free(config_compiler); + config_free(config); + } + exit( status ); +} diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/loadOK.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_loadOK.c similarity index 61% rename from ThirdParty/Ert/devel/libjob_queue/tests/loadOK.c rename to ThirdParty/Ert/devel/libjob_queue/tests/job_loadOK.c index 1f8920b01c..5b94f4e1f6 100644 --- a/ThirdParty/Ert/devel/libjob_queue/tests/loadOK.c +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_loadOK.c @@ -1,7 +1,7 @@ /* Copyright (C) 2012 Statoil ASA, Norway. - The file 'load_internal.c' is part of ERT - Ensemble based Reservoir Tool. + The file 'job_loadOK.c' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,17 +20,18 @@ #include -#include +#include -bool loadConfig(config_type * config , const char * config_file) { +bool loadConfig(config_type * config , const char * config_file , config_type * config_compiler) { bool OK = false; - ext_cmd_type * cmd = ext_cmd_config_alloc( config , config_file); + workflow_job_type * cmd = workflow_job_config_alloc( "NAME" , config , config_file); if (cmd != NULL) { OK = true; - ext_cmd_free( cmd ); + workflow_job_update_config_compiler( cmd , config_compiler ); + workflow_job_free( cmd ); } return OK; @@ -41,16 +42,18 @@ bool loadConfig(config_type * config , const char * config_file) { int main( int argc , char ** argv) { int status = 0; { - config_type * config = ext_cmd_alloc_config(); + config_type * config = workflow_job_alloc_config(); + config_type * config_compiler = config_alloc(); int iarg; bool OK = true; for (iarg = 1; iarg < argc; iarg++) - OK = OK && loadConfig( config , argv[iarg]); + OK = OK && loadConfig( config , argv[iarg] , config_compiler); if (!OK) status = 1; + config_free(config_compiler); config_free(config); } exit( status ); diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/job_lsb.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_lsb.c new file mode 100644 index 0000000000..efd340ce4a --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_lsb.c @@ -0,0 +1,47 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'job_lsb.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include + +#include + +#include + +/* + This test should ideally be run twice in two different environments; + with and without dlopen() access to the lsf libraries. +*/ + +int main( int argc , char ** argv) { + lsb_type * lsb = lsb_alloc(); + + test_assert_not_NULL( lsb ); + if (!lsb_ready(lsb)) { + const stringlist_type * error_list = lsb_get_error_list( lsb ); + stringlist_fprintf(error_list , "\n", stdout); + } + + if (dlopen( "libbat.so" , RTLD_NOW | RTLD_GLOBAL)) + test_assert_true( lsb_ready( lsb )); + else + test_assert_false( lsb_ready( lsb )); + + lsb_free( lsb ); + exit(0); +} diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/job_lsf_submit_test.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_lsf_submit_test.c index 143cb5be81..42ce02fcbe 100644 --- a/ThirdParty/Ert/devel/libjob_queue/tests/job_lsf_submit_test.c +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_lsf_submit_test.c @@ -21,15 +21,14 @@ #include #include -//#include +#include #include void test_submit(lsf_driver_type * driver , const char * server , const char * bsub_cmd , const char * bjobs_cmd , const char * bkill_cmd , const char * cmd) { - if (server != NULL) - lsf_driver_set_option(driver , LSF_SERVER , server ); + lsf_driver_set_option(driver , LSF_SERVER , server ); if (bsub_cmd != NULL) lsf_driver_set_option(driver , LSF_BSUB_CMD , server ); @@ -75,11 +74,7 @@ int main( int argc , char ** argv) { int iarg; for (iarg = 0; iarg < stringlist_get_size( server_list ); iarg++) { const char * server = stringlist_iget( server_list , iarg ); - - if (strcmp(server , "NULL") == 0) - test_submit(driver , NULL , NULL , NULL , NULL , argv[1]); - else - test_submit(driver , server , NULL , NULL , NULL , argv[1]); + test_submit(driver , server , NULL , NULL , NULL , argv[1]); } stringlist_free( server_list ); diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/job_lsf_test.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_lsf_test.c index b858590b8b..3972d671b1 100644 --- a/ThirdParty/Ert/devel/libjob_queue/tests/job_lsf_test.c +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_lsf_test.c @@ -18,36 +18,36 @@ #include #include -//#include #include +#include + #include +#include void test_option(lsf_driver_type * driver , const char * option , const char * value) { - if (!lsf_driver_set_option( driver , option , value)) - exit(1); - - if (strcmp( lsf_driver_get_option( driver , option) , value) != 0) - exit(1); + test_assert_true( lsf_driver_set_option( driver , option , value)); + test_assert_string_equal(lsf_driver_get_option( driver , option) , value); } void test_server(lsf_driver_type * driver , const char * server, lsf_submit_method_enum submit_method) { lsf_driver_set_option(driver , LSF_SERVER , server ); - if (lsf_driver_get_submit_method( driver ) != submit_method) - exit(1); + test_assert_true( lsf_driver_get_submit_method( driver ) == submit_method ); } void test_status(int lsf_status , job_status_type job_status) { - if (lsf_driver_convert_status( lsf_status ) != job_status) { - printf("Error converting integer status:%d \n",lsf_status); - exit(1); - } + test_assert_true( lsf_driver_convert_status( lsf_status ) == job_status); } +/* + This test should ideally be run twice in two different environments; + with and without dlopen() access to the lsf libraries. +*/ + int main( int argc , char ** argv) { lsf_driver_type * driver = lsf_driver_alloc(); @@ -59,14 +59,27 @@ int main( int argc , char ** argv) { test_option( driver , LSF_BSUB_CMD , "bsub"); printf("Options OK\n"); - test_server( driver , NULL , LSF_SUBMIT_INTERNAL ); - test_server( driver , "LoCaL" , LSF_SUBMIT_LOCAL_SHELL ); - test_server( driver , "LOCAL" , LSF_SUBMIT_LOCAL_SHELL ); - test_server( driver , "XLOCAL" , LSF_SUBMIT_REMOTE_SHELL ); - test_server( driver , NULL , LSF_SUBMIT_INTERNAL ); - test_server( driver , "be-grid01" , LSF_SUBMIT_REMOTE_SHELL ); - printf("Servers OK\n"); + { + + lsf_submit_method_enum submit_NULL; + lsb_type * lsb = lsb_alloc(); + if (lsb_ready(lsb)) + submit_NULL = LSF_SUBMIT_INTERNAL; + else + submit_NULL = LSF_SUBMIT_LOCAL_SHELL; + + test_server( driver , NULL , submit_NULL ); + test_server( driver , "LoCaL" , LSF_SUBMIT_LOCAL_SHELL ); + test_server( driver , "LOCAL" , LSF_SUBMIT_LOCAL_SHELL ); + test_server( driver , "XLOCAL" , LSF_SUBMIT_REMOTE_SHELL ); + test_server( driver , NULL , submit_NULL ); + test_server( driver , "NULL" , submit_NULL ); + test_server( driver , "be-grid01" , LSF_SUBMIT_REMOTE_SHELL ); + printf("Servers OK\n"); + + lsb_free( lsb ); + } test_status( JOB_STAT_PEND , JOB_QUEUE_PENDING ); test_status( JOB_STAT_PSUSP , JOB_QUEUE_RUNNING ); test_status( JOB_STAT_USUSP , JOB_QUEUE_RUNNING ); @@ -77,7 +90,7 @@ int main( int argc , char ** argv) { test_status( JOB_STAT_EXIT , JOB_QUEUE_EXIT ); test_status( JOB_STAT_UNKWN , JOB_QUEUE_EXIT ); test_status( 192 , JOB_QUEUE_DONE ); - printf("Status OK \n"); + exit(0); } diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/job_queue_test.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_queue_test.c new file mode 100644 index 0000000000..b49edd7d6b --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_queue_test.c @@ -0,0 +1,40 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'job_queue_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include + +#include + +#include +#include + +#include +#include +#include + + + +int main( int argc , char ** argv) { + job_queue_type * queue = job_queue_alloc( 10 , "OK" , "ERROR"); + queue_driver_type * driver = queue_driver_alloc( LSF_DRIVER ); + test_assert_false( job_queue_has_driver( queue )); + + job_queue_set_driver( queue , driver ); + test_assert_true( job_queue_has_driver( queue )); + exit(0); +} diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/job_workflow_test.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_workflow_test.c new file mode 100644 index 0000000000..a7b21a7bdb --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_workflow_test.c @@ -0,0 +1,116 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'job_workflow_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + + +void create_workflow( const char * workflow_file , const char * tmp_file , int value) { + FILE * stream = util_fopen( workflow_file , "w"); + fprintf(stream , "CREATE_FILE %s %d\n" , tmp_file , value); + fprintf(stream , "READ_FILE %s\n" , tmp_file ); + fclose( stream ); + + printf("Have created:%s \n",workflow_file ); +} + + +void read_file( void * self , const stringlist_type * args) { + printf("Running read_file \n"); + int * value = (int *) self; + FILE * stream = util_fopen(stringlist_iget(args , 0 ) , "r"); + fscanf(stream , "%d" , value ); + fclose( stream ); +} + + +static void create_exworkflow( const char * workflow , const char * bin_path) +{ + FILE * stream = util_fopen( workflow , "w"); + fprintf(stream , "EXECUTABLE %s/create_file\n" , bin_path); + fprintf(stream , "ARG_TYPE 1 INT\n"); + fprintf(stream , "MIN_ARG 2\n"); + fprintf(stream , "MAX_ARG 2\n"); + fclose(stream); +} + + +int main( int argc , char ** argv) { +#ifdef ERT_LINUX + const char * exworkflow = "/tmp/xflow"; +#endif + + const char * bin_path = argv[1]; + const char * internal_workflow = argv[2]; + create_exworkflow( exworkflow , bin_path ); + { + + int int_value = rand(); + int read_value = 100; + workflow_joblist_type * joblist = workflow_joblist_alloc(); + + if (!workflow_joblist_add_job_from_file( joblist , "CREATE_FILE" , exworkflow)) { + remove( exworkflow ); + test_error_exit("Loading job CREATE_FILE failed\n"); + } else + remove( exworkflow ); + + if (!workflow_joblist_add_job_from_file( joblist , "READ_FILE" , internal_workflow)) + test_error_exit("Loading job READ_FILE failed\n"); + + { + config_type * workflow_compiler = workflow_joblist_get_compiler( joblist ); + + if (config_get_schema_size( workflow_compiler ) != 2) + test_error_exit("Config compiler - wrong size \n"); + } + + + { + const char * workflow_file = "/tmp/workflow"; + const char * tmp_file = "/tmp/fileX"; + workflow_type * workflow; + + create_workflow( workflow_file , tmp_file , int_value ); + workflow = workflow_alloc(workflow_file , joblist ); + unlink( workflow_file ); + + if (!workflow_run( workflow , &read_value , false , NULL)) { + config_type * workflow_compiler = workflow_joblist_get_compiler( joblist ); + config_fprintf_errors( workflow_compiler , true ,stdout); + unlink( tmp_file ); + test_error_exit("Workflow did not run\n"); + } + unlink( tmp_file ); + } + workflow_joblist_free( joblist ); + if (int_value != read_value) + test_error_exit("Wrong numeric value read back \n"); + } + exit(0); +} diff --git a/ThirdParty/Ert/devel/libplot/include/ert/plot/plot_dataset.h b/ThirdParty/Ert/devel/libplot/include/ert/plot/plot_dataset.h index 98a47ebb3f..bd9447141a 100644 --- a/ThirdParty/Ert/devel/libplot/include/ert/plot/plot_dataset.h +++ b/ThirdParty/Ert/devel/libplot/include/ert/plot/plot_dataset.h @@ -112,6 +112,7 @@ double * plot_dataset_get_vector_x1(const plot_dataset_type * d); double * plot_dataset_get_vector_y1(const plot_dataset_type * d); double * plot_dataset_get_vector_x2(const plot_dataset_type * d); double * plot_dataset_get_vector_y2(const plot_dataset_type * d); +int plot_dataset_get_size( const plot_dataset_type * dataset ); /*****************************************************************/ /* Functions for actually adding data to the dataset. */ diff --git a/ThirdParty/Ert/devel/libplot/src/CMakeLists.txt b/ThirdParty/Ert/devel/libplot/src/CMakeLists.txt index 6d0bb9130c..cfa0e164a5 100644 --- a/ThirdParty/Ert/devel/libplot/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libplot/src/CMakeLists.txt @@ -7,8 +7,9 @@ add_library( plot ${LIBRARY_TYPE} ${source_files} ) target_link_libraries( plot ert_util ${PLPLOT_LIBRARY} ) set_target_properties( plot PROPERTIES VERSION 1.0 SOVERSION 1.0 ) #----------------------------------------------------------------- -install(TARGETS plot DESTINATION ${CMAKE_INSTALL_LIBDIR}) -foreach(header ${header_files}) - install(FILES ../include/ert/plot/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/plot) -endforeach() - +if (INSTALL_ERT) + install(TARGETS plot DESTINATION ${CMAKE_INSTALL_LIBDIR}) + foreach(header ${header_files}) + install(FILES ../include/ert/plot/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/plot) + endforeach() +endif() diff --git a/ThirdParty/Ert/devel/librms/applications/CMakeLists.txt b/ThirdParty/Ert/devel/librms/applications/CMakeLists.txt index 4172084d3c..8ed1bafa79 100644 --- a/ThirdParty/Ert/devel/librms/applications/CMakeLists.txt +++ b/ThirdParty/Ert/devel/librms/applications/CMakeLists.txt @@ -15,9 +15,11 @@ foreach(prog ${program_list}) set (destination bin) endif() - install(TARGETS ${prog} DESTINATION ${destination}) - if (INSTALL_GROUP) - install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/${prog})") - install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/${prog})") + if (INSTALL_ERT) + install(TARGETS ${prog} DESTINATION ${destination}) + if (INSTALL_GROUP) + install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/${prog})") + install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/${prog})") + endif() endif() endforeach() diff --git a/ThirdParty/Ert/devel/librms/src/CMakeLists.txt b/ThirdParty/Ert/devel/librms/src/CMakeLists.txt index 0eb80e4871..bba790f2d5 100644 --- a/ThirdParty/Ert/devel/librms/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/librms/src/CMakeLists.txt @@ -5,9 +5,10 @@ add_library( rms ${LIBRARY_TYPE} ${source_files} ) set_target_properties( rms PROPERTIES VERSION 1.0 SOVERSION 1.0 ) #----------------------------------------------------------------- -install(TARGETS rms DESTINATION ${CMAKE_INSTALL_LIBDIR}) -foreach(header ${header_files}) - install(FILES ../include/ert/rms/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/rms) -endforeach() - +if (INSTALL_ERT) + install(TARGETS rms DESTINATION ${CMAKE_INSTALL_LIBDIR}) + foreach(header ${header_files}) + install(FILES ../include/ert/rms/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/rms) + endforeach() +endif() diff --git a/ThirdParty/Ert/devel/libsched/applications/CMakeLists.txt b/ThirdParty/Ert/devel/libsched/applications/CMakeLists.txt index 7dc2c1b50d..3416f7625b 100644 --- a/ThirdParty/Ert/devel/libsched/applications/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libsched/applications/CMakeLists.txt @@ -17,9 +17,11 @@ foreach(prog ${program_list}) set (destination bin) endif() - install(TARGETS ${prog} DESTINATION ${destination}) - if (INSTALL_GROUP) - install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/${prog})") - install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/${prog})") + if (INSTALL_ERT) + install(TARGETS ${prog} DESTINATION ${destination}) + if (INSTALL_GROUP) + install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/${prog})") + install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/${prog})") + endif() endif() endforeach() diff --git a/ThirdParty/Ert/devel/libsched/src/CMakeLists.txt b/ThirdParty/Ert/devel/libsched/src/CMakeLists.txt index 2e0ad4c657..ab88ff6800 100644 --- a/ThirdParty/Ert/devel/libsched/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libsched/src/CMakeLists.txt @@ -12,10 +12,11 @@ set_target_properties( sched PROPERTIES VERSION 1.0 SOVERSION 1.0 ) target_link_libraries( sched ert_util ecl) #----------------------------------------------------------------- -install(TARGETS sched DESTINATION ${CMAKE_INSTALL_LIBDIR}) -foreach(header ${header_files}) - install(FILES ../include/ert/sched/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/sched) -endforeach() - +if (INSTALL_ERT) + install(TARGETS sched DESTINATION ${CMAKE_INSTALL_LIBDIR}) + foreach(header ${header_files}) + install(FILES ../include/ert/sched/${header} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ert/sched) + endforeach() +endif() diff --git a/ThirdParty/Ert/devel/libsched/src/history.c b/ThirdParty/Ert/devel/libsched/src/history.c index 2058691dd7..5c3f155b18 100644 --- a/ThirdParty/Ert/devel/libsched/src/history.c +++ b/ThirdParty/Ert/devel/libsched/src/history.c @@ -135,11 +135,10 @@ history_type * history_alloc_from_refcase(const ecl_sum_type * refcase , bool us -int history_get_last_restart(const history_type * history) -{ +int history_get_last_restart(const history_type * history) { if (history->refcase != NULL) return ecl_sum_get_last_report_step( history->refcase); - else + else return sched_history_get_last_history( history->sched_history ); } diff --git a/ThirdParty/Ert/devel/libsched/src/sched_kw_compdat.c b/ThirdParty/Ert/devel/libsched/src/sched_kw_compdat.c index 54341a4b26..f4bd8101cc 100644 --- a/ThirdParty/Ert/devel/libsched/src/sched_kw_compdat.c +++ b/ThirdParty/Ert/devel/libsched/src/sched_kw_compdat.c @@ -129,7 +129,7 @@ static well_dir_type comp_get_well_dir_from_string(const char * well_dir) { else if (strcmp(well_dir , WELL_DIR_Y_STRING) == 0) return Y; else if (strcmp(well_dir , WELL_DIR_Z_STRING) == 0) - return X; + return Z; else if (strcmp(well_dir , WELL_DIR_FX_STRING) == 0) return FX; else if (strcmp(well_dir , WELL_DIR_FY_STRING) == 0) diff --git a/ThirdParty/Ert/devel/python/ert/config/config_enums.py b/ThirdParty/Ert/devel/python/ert/config/config_enums.py new file mode 100644 index 0000000000..199c16dfd0 --- /dev/null +++ b/ThirdParty/Ert/devel/python/ert/config/config_enums.py @@ -0,0 +1,25 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'config.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import libconfig +from ert.cwrap.cenum import create_enum + + +# config_item_types from config_schema_item.h +create_enum( libconfig.lib , "config_schema_item_type_enum_iget" , "config_types_enum" , globals()) + +# config_item_types from config_schema_item.h +create_enum( libconfig.lib , "config_schema_item_unrecognized_enum_iget" , "config_unrecognized_enum" , name_space = globals()) diff --git a/ThirdParty/Ert/devel/python/ert/config/config_parser.py b/ThirdParty/Ert/devel/python/ert/config/config_parser.py new file mode 100644 index 0000000000..d3a7477b93 --- /dev/null +++ b/ThirdParty/Ert/devel/python/ert/config/config_parser.py @@ -0,0 +1,47 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'config_parser.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + + + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from config_enums import * + +class ConfigParser(CClass): + + def __init__(self): + c_ptr = cfunc.alloc() + self.init_cobj( c_ptr , cfunc.free ) + + + def parse(self , filename , comment_string = "--" , include_kw = "INCLUDE" , define_kw = None , unrecognized = CONFIG_UNRECOGNIZED_WARN , validate = True): + return cfunc.parse(self , filename , comment_string , include_kw , define_kw , unrecognized , validate) + + + def add(self , kw , required = False): + cfunc.add_schema_item( self , kw , required ) + + +################################################################# + +cwrapper = CWrapper( libconfig.lib ) +cwrapper.registerType( "config" , ConfigParser ) +cfunc = CWrapperNameSpace("config") +cfunc.alloc = cwrapper.prototype("c_void_p config_alloc()") +cfunc.free = cwrapper.prototype("void config_free( config )") +cfunc.parse = cwrapper.prototype("bool config_parse( config , char* , char* , char* , char*, int , bool)") +cfunc.add_schema_item = cwrapper.prototype("bool config_add_schema_item( config , char* , bool)") diff --git a/ThirdParty/Ert/devel/python/python/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/CMakeLists.txt index 5c2cc08914..5dbe86acad 100644 --- a/ThirdParty/Ert/devel/python/python/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/python/CMakeLists.txt @@ -1,2 +1,2 @@ -set(PYTHON_INSTALL_PREFIX "/python") +set(PYTHON_INSTALL_PREFIX "python") add_subdirectory( ert ) diff --git a/ThirdParty/Ert/devel/python/python/ert/config/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert/config/CMakeLists.txt index e1749d5f3e..50bca4e099 100644 --- a/ThirdParty/Ert/devel/python/python/ert/config/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/python/ert/config/CMakeLists.txt @@ -1 +1 @@ -add_python_target(python_config ${PYTHON_INSTALL_PREFIX}/ert/config "config;__init__;libconfig") +add_python_target(python_config ${PYTHON_INSTALL_PREFIX}/ert/config "config;__init__;libconfig;config_enums;config_parser") diff --git a/ThirdParty/Ert/devel/python/python/ert/config/config.py b/ThirdParty/Ert/devel/python/python/ert/config/config.py index 256bca20d6..cc5a0a1458 100644 --- a/ThirdParty/Ert/devel/python/python/ert/config/config.py +++ b/ThirdParty/Ert/devel/python/python/ert/config/config.py @@ -1 +1,20 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'config.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. import libconfig + +from config_enums import * +from config_parser import ConfigParser , SchemaItem , ContentItem , ContentNode + diff --git a/ThirdParty/Ert/devel/python/python/ert/config/config_enums.py b/ThirdParty/Ert/devel/python/python/ert/config/config_enums.py new file mode 100644 index 0000000000..da30d1cf9b --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/config/config_enums.py @@ -0,0 +1,21 @@ +# Copyright (C) 2013 Statoil ASA, Norway. +# +# The file 'config_enums.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. +from ert.cwrap.cenum import create_enum +import libconfig + +create_enum( libconfig.lib , "config_schema_item_type_enum_iget" , "content_type" , name_space = globals()) + +create_enum( libconfig.lib , "config_schema_item_unrecognized_enum_iget" , "unrecognized" , name_space = globals()) diff --git a/ThirdParty/Ert/devel/python/python/ert/config/config_parser.py b/ThirdParty/Ert/devel/python/python/ert/config/config_parser.py new file mode 100644 index 0000000000..3b03978494 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/config/config_parser.py @@ -0,0 +1,165 @@ +# Copyright (C) 2013 Statoil ASA, Norway. +# +# The file 'config_parser.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import os.path +import libconfig +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +import config_enums + + +class SchemaItem(CClass): + + def __init__(self , keyword , required = False): + c_ptr = cfunc.schema_alloc( keyword , required ) + self.init_cref( c_ptr , cfunc.schema_free) + + + @classmethod + def wrap(cls , c_ptr , parent): + obj = object.__new__( cls ) + obj.init_cref( c_ptr , parent ) + return obj + + + def iget_type( self , index ): + return cfunc.schema_iget_type( self , index ) + + def iset_type( self , index , type ): + cfunc.schema_iset_type( self , index , type ) + + def set_argc_minmax(self , min , max): + cfunc.schema_set_argc_minmax( self , min , max ) + +#----------------------------------------------------------------- + + +class ContentItem(CClass): + # Not possible to create new python instances of this class + + @classmethod + def wrap(cls , c_ptr , parent): + obj = object.__new__( cls ) + obj.init_cref( c_ptr , parent ) + return obj + + def __len__(self): + return cfunc.content_size( self ) + + + def __getitem__(self , index): + if isinstance(index , int): + if index >= 0 and index < self.__len__(): + c_ptr = cfunc.iget_content_node( self , index ) + return ContentNode.wrap( c_ptr , self ) + else: + raise IndexError + else: + raise ValueError("[] operator must have integer index") + + + + +#----------------------------------------------------------------- + + + +class ContentNode(CClass): + # Not possible to create new python instances of this class + + @classmethod + def wrap(cls , c_ptr , parent): + obj = object.__new__( cls ) + obj.init_cref( c_ptr , parent ) + return obj + + def __len__(self): + return cfunc.content_node_size( self ) + + def __getitem__(self , index): + if isinstance(index , int): + if index >= 0 and index < self.__len__(): + return cfunc.content_node_iget( self , index ) + else: + raise IndexError + else: + raise ValueError("[] operator must have integer index") + + def content(self , sep = " "): + return cfunc.content_full_string(self , sep) + + + +#----------------------------------------------------------------- + + +class ConfigParser(CClass): + + def __init__(self): + c_ptr = cfunc.config_alloc() + self.init_cobj(c_ptr , cfunc.config_free ) + + + def add(self , keyword , required = False): + c_ptr = cfunc.add( self , keyword , required ) + schema_item = SchemaItem.wrap(c_ptr , self) + return schema_item + + + def parse( self , config_file , comment_string = "--" , include_kw = "INCLUDE" , define_kw = "DEFINE" , unrecognized = config_enums.unrecognized.CONFIG_UNRECOGNIZED_WARN , validate = True): + if os.path.exists( config_file ): + return cfunc.parse( self , config_file , comment_string , include_kw , define_kw , unrecognized , validate ) + else: + raise IOError("File: %s does not exists") + + + def __getitem__(self , keyword): + if cfunc.has_content(self , keyword): + c_ptr = cfunc.get_content(self , keyword ) + return ContentItem.wrap( c_ptr , self ) + else: + return None + +#----------------------------------------------------------------- + + +cwrapper = CWrapper( libconfig.lib ) +cwrapper.registerType( "config_parser" , ConfigParser ) +cwrapper.registerType( "schema_item" , SchemaItem ) +cwrapper.registerType( "content_item" , ContentItem ) +cwrapper.registerType( "content_node" , ContentNode ) + +cfunc = CWrapperNameSpace("config") + +cfunc.add = cwrapper.prototype("c_void_p config_add_schema_item( config_parser , char* , bool)") +cfunc.config_alloc = cwrapper.prototype("c_void_p config_alloc( )") +cfunc.config_free = cwrapper.prototype("void config_free( config_parser )") +cfunc.parse = cwrapper.prototype("bool config_parse( config_parser , char* , char* , char* , char* , int , bool )") +cfunc.has_content = cwrapper.prototype("bool config_has_content_item( config_parser , char*) ") +cfunc.get_content = cwrapper.prototype("c_void_p config_get_content_item( config_parser , char*) ") + +cfunc.schema_alloc = cwrapper.prototype("c_void_p config_schema_item_alloc( char* , bool )") +cfunc.schema_free = cwrapper.prototype("void config_schema_item_free( schema_item )") +cfunc.schema_iget_type = cwrapper.prototype("int config_schema_item_iget_type( schema_item ,int)") +cfunc.schema_iset_type = cwrapper.prototype("void config_schema_item_iset_type( schema_item , int , int)") +cfunc.schema_set_argc_minmax = cwrapper.prototype("void config_schema_item_set_argc_minmax( schema_item , int , int)") + +cfunc.content_size = cwrapper.prototype("int config_content_item_get_size( content_item )") +cfunc.iget_content_node = cwrapper.prototype("int config_content_item_iget_node( content_item , int)") +cfunc.content_node_iget = cwrapper.prototype("char* config_content_node_iget( content_node , int)") +cfunc.content_node_size = cwrapper.prototype("int config_content_node_get_size( content_node )") +cfunc.content_full_string = cwrapper.prototype("char* config_content_node_get_full_string( content_node , char* )") + diff --git a/ThirdParty/Ert/devel/python/python/ert/cwrap/clib.py b/ThirdParty/Ert/devel/python/python/ert/cwrap/clib.py index ce3b36248e..f772ab6b11 100644 --- a/ThirdParty/Ert/devel/python/python/ert/cwrap/clib.py +++ b/ThirdParty/Ert/devel/python/python/ert/cwrap/clib.py @@ -93,7 +93,7 @@ def ert_load( *lib_list ): return __load__(lib_list , True ) except ImportError: # Try again - ignoring the ert_lib_path setting. - return load( lib_list ) + return load( *lib_list ) else: # The ert_lib_path variable has not been set; just try a normal load. - return load( lib_list ) + return load( *lib_list ) diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert/ecl/CMakeLists.txt index db209125ed..7966d30103 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/CMakeLists.txt @@ -1,2 +1,5 @@ -set(PYTHON_INSTALL_PREFIX "/python/ert/ecl/") -add_python_target(python_ecl ${PYTHON_INSTALL_PREFIX} "ecl_case;ecl_default;ecl_file;ecl_grav_calc;ecl_grav;ecl_grid;ecl_kw;ecl;ecl_queue;ecl_region;ecl_rft;ecl_subsidence;ecl_sum;ecl_util;fortio;__init__;libecl") +add_python_target(python_ecl ${PYTHON_INSTALL_PREFIX}/ert/ecl "ecl_case;ecl_default;ecl_file;ecl_grav_calc;ecl_grav;ecl_grid;ecl_kw;ecl;ecl_queue;ecl_region;ecl_rft;ecl_subsidence;ecl_sum;ecl_util;fortio;__init__;libecl") + +if (EXISTS "ecl_local.py") + add_python_target( python_ecl_local ${PYTHON_INSTALL_PREFIX}/ert/ecl "ecl_local") +endif() diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl.py index 55fbb6dc1d..8d4847e8c6 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl.py @@ -51,6 +51,7 @@ import ecl_default + diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_case.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_case.py index 747070cbb4..5c29c919ad 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_case.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_case.py @@ -26,7 +26,6 @@ import ecl_grid import ecl_rft import ecl_default import ecl_util -import ert.job_queue.driver as queue_driver import warnings class EclCase: @@ -137,10 +136,10 @@ class EclCase: def run( self , - ecl_cmd = ecl_default.default.ecl_cmd , - ecl_version = ecl_default.default.ecl_version , + ecl_cmd = None, + ecl_version = None, driver = None , - driver_type = ecl_default.default.driver_type, + driver_type = None, driver_options = None, blocking = False ): """ @@ -190,8 +189,20 @@ class EclCase: you might want use an EclQueue() and the submit() method instead, in particular if you are running locally. """ + import ert.job_queue.driver as queue_driver + num_cpu = ecl_util.get_num_cpu( self.datafile ) argv = [ecl_version , self.datafile , num_cpu] + + if ecl_cmd is None: + ecl_cmd = ecl_default.default.ecl_cmd + + if driver_type is None: + driver_type = ecl_default.default.driver_type + + if ecl_version is None: + ecl_version = ecl_default.default.ecl_version + if driver is None: if driver_options is None: driver_options = ecl_default.default.driver_options[ driver_type ] diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_file.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_file.py index 9b930b2e39..2853089e47 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_file.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_file.py @@ -36,10 +36,12 @@ implementation from the libecl library. RestartFile class, there is some specialized functionality. """ +import os.path import datetime import ctypes import types import libecl +import re from ert.cwrap.cwrap import * from ert.cwrap.cclass import CClass @@ -102,7 +104,7 @@ class EclFile(CClass): print "OK - file contains report step 20" else: print "File does not contain report step 20" - + If you have already loaded the file into an EclFile instance you should use the has_report_step() method instead. """ @@ -133,18 +135,39 @@ class EclFile(CClass): obj = EclFile( filename ) return obj.has_sim_time( dtime ) + @property + def report_list(self): + report_steps = [] + try: + seqnum_list = self["SEQNUM"] + for s in seqnum_list: + report_steps.append( s[0] ) + except KeyError: + # OK - we did not have seqnum; that might be because this + # a non-unified restart file; or because this is not a + # restart file at all. + fname = self.name + matchObj = re.search("\.[XF](\d{4})$" , fname) + if matchObj: + report_steps.append( int(matchObj.group(1)) ) + else: + raise TypeError("Tried get list of report steps from file:%s - which is not a restart file" % fname) + + + return report_steps + @classmethod - def file_report_steps( cls , filename ): + def file_report_list( cls , filename ): """ Will identify the available report_steps from @filename. """ - report_steps = [] + file = EclFile( filename ) - for s in file["SEQNUM"]: - report_steps.append( s[0] ) - return report_steps + return file.report_list + + def __str__(self): return "EclFile: %s" % self.name @@ -563,9 +586,20 @@ class EclFile(CClass): INTEHEAD keyword. """ dates = [] - for index in range( self.num_named_kw( 'SEQNUM' )): - dates.append( self.iget_restart_sim_time( index )) + if self.has_kw('SEQNUM'): + for index in range( self.num_named_kw( 'SEQNUM' )): + dates.append( self.iget_restart_sim_time( index )) + else: + # This is a uber-hack; should export the ecl_rsthead + # object as ctypes structure. + intehead = self["INTEHEAD"][0] + year = intehead[66] + month = intehead[65] + day = intehead[64] + date = datetime.datetime( year , month , day ) + dates = [ date ] return dates + @property def dates( self ): @@ -617,7 +651,7 @@ class EclFile(CClass): """ return len( self["SEQNUM"] ) - + def has_sim_time( self , dtime ): """ diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_grid.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_grid.py index 7fb7ab7104..61148c1c13 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_grid.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_grid.py @@ -680,7 +680,7 @@ class EclGrid(CClass): cfunc.fwrite_GRID( self , filename ) - def write_grdecl( self , ecl_kw , pyfile , default_value = 0): + def write_grdecl( self , ecl_kw , pyfile , special_header = None , default_value = 0): """ Writes an EclKW instance as an ECLIPSE grdecl formatted file. @@ -705,7 +705,7 @@ class EclGrid(CClass): if ecl_kw.size == self.nactive or ecl_kw.size == self.size: cfile = CFILE( pyfile ) - cfunc.fwrite_grdecl( self , ecl_kw , cfile , default_value ) + cfunc.fwrite_grdecl( self , ecl_kw , special_header , cfile , default_value ) else: raise ValueError("Keyword: %s has invalid size(%d), must be either nactive:%d or nx*ny*nz:%d" % (ecl_kw.name , ecl_kw.size , self.nactive , self.size)) @@ -760,7 +760,7 @@ cfunc.grid_value = cwrapper.prototype("double ecl_grid_get_pro cfunc.get_cell_volume = cwrapper.prototype("double ecl_grid_get_cell_volume1( ecl_grid , int )") cfunc.get_cell_thickness = cwrapper.prototype("double ecl_grid_get_cell_thickness1( ecl_grid , int )") cfunc.get_depth = cwrapper.prototype("double ecl_grid_get_cdepth1( ecl_grid , int )") -cfunc.fwrite_grdecl = cwrapper.prototype("void ecl_grid_grdecl_fprintf_kw( ecl_grid , ecl_kw , FILE , double)") +cfunc.fwrite_grdecl = cwrapper.prototype("void ecl_grid_grdecl_fprintf_kw( ecl_grid , ecl_kw , char* , FILE , double)") cfunc.load_column = cwrapper.prototype("void ecl_grid_get_column_property( ecl_grid , ecl_kw , int , int , double_vector)") cfunc.get_top = cwrapper.prototype("double ecl_grid_get_top2( ecl_grid , int , int )") cfunc.get_bottom = cwrapper.prototype("double ecl_grid_get_bottom2( ecl_grid , int , int )") diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_local.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_local.py new file mode 100644 index 0000000000..a2c6642432 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_local.py @@ -0,0 +1,72 @@ +import os +import socket +import sys +import ert.job_queue.driver as driver + +################################################################# +# Only a quite few of the Linux computers in Statoil are proper LSF +# nodes, in the sense that they can talk directly to the LSF +# demons. When using LSF from a computer which is not properly part of +# the LSF cluster you must first ssh to a node which can serve as LSF +# server, and then issue the LSF commands there. This is controlled by +# the LSF_SERVER option in the LSF driver. +# +# In this configuration file the LSF server to use is determined by +# using the two first characters from the name of the submitting host +# as a lookup key in the server_list dictionary. +# +# If your workstation has proper access to LSF you can set the +# environment variable LOCAL_LSF; in that case the lsf_server variable +# will be left at None and the LSF driver instance will issue the LSF +# commands directly at the calling host without going through ssh. +# +# Observe that the ssh-based scheme requires that you have +# passwordless login to the server used as lsf server. +################################################################# + +server_list = { "be" : "be-grid01.be.statoil.no", + "st" : "st-grid01.st.statoil.no", + "tr" : "tr-grid01.tr.statoil.no", + "stj" : "tr-grid01.tr.statoil.no", + "rio" : "rio-grid01.rio.statoil.no" } + + +def get_lsf_server(): + if os.getenv("LOCAL_LSF"): + # The user has set the LOCAL_LSF environment variable - + # signalling that she has access to a proper LSF node. + return None + else: + host = socket.gethostname() + host_prefix = host.split("-")[0] + lsf_server = server_list.get( host_prefix , None) + # This will silently return None if no appropriate LSF server + # is found. In that case things will blow up at a later stage + # if/when someone tries to use the invalid lsf server. + return lsf_server + + +# The command used to run ECLIPSE. The executable will be called with +# commandline arguments: version data_file num_cpu +ecl_cmd = "/project/res/etc/ERT/Scripts/run_eclipse.py" + +# The ECLIPSE version which will be used, by default. +ecl_version = "2010.2" + +# The resource request passed to the LSF server. In practice every god-damn compute node +# in Statoil will satisfy these needs, so it could just be left as None. +lsf_resource_request = "select[cs && x86_64Linux] rusage[ecl100v2000=1:duration=5]" + +lsf_queue = "normal" +rsh_command = "/usr/bin/ssh" + +driver_options = { driver.LSF_DRIVER : [("LSF_QUEUE" , lsf_queue), + ("LSF_RESOURCE" , lsf_resource_request), + ("LSF_SERVER" , get_lsf_server())], + driver.RSH_DRIVER : [("RSH_COMMAND" , rsh_command)], + driver.LOCAL_DRIVER : []} + +driver_type = driver.LSF_DRIVER + + + diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_queue.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_queue.py index 353ac148d2..3487dcd9a1 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_queue.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_queue.py @@ -45,10 +45,10 @@ import ecl_util class EclQueue( JobQueue ): def __init__(self , driver = None , - driver_type = default.driver_type, + driver_type = None, driver_options = None, - ecl_version = default.ecl_version , - ecl_cmd = default.ecl_cmd , + ecl_version = None, + ecl_cmd = None, max_running = 0, size = 0): @@ -145,6 +145,14 @@ class EclQueue( JobQueue ): the queue stay alive and continue managing jobs even after the main thread has exited - not yet :-( """ + if ecl_cmd is None: + ecl_cmd = ecl_default.default.ecl_cmd + + if driver_type is None: + driver_type = ecl_default.default.driver_type + + if ecl_version is None: + ecl_version = ecl_default.default.ecl_version self.ecl_version = ecl_version self.ecl_cmd = ecl_cmd diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_sum.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_sum.py index c3dff1fe0d..d687e329e2 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_sum.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_sum.py @@ -394,6 +394,117 @@ class EclSumVector: ################################################################# + +class EclSMSPECNode( CClass ): + """ + Small class with some meta information about a summary variable. + + The summary variables have different attributes, like if they + represent a total quantity, a rate or a historical quantity. These + quantities, in addition to the underlying values like WGNAMES, + KEYWORD and NUMS taken from the the SMSPEC file are stored in this + structure. + """ + def __new__(cls , c_ptr , parent): + if c_ptr: + obj = object.__new__( cls ) + obj.init_cref( c_ptr , parent ) + return obj + else: + return None + + @property + def is_total(self): + """ + Will check if the node corresponds to a total quantity. + + The question of whether a variable corresponds to a 'total' + quantity or not can be interesting for e.g. interpolation + purposes. The actual question whether a quantity is total or + not is based on a hardcoded list in smspec_node_set_flags() in + smspec_node.c; this list again is based on the tables 2.7 - + 2.11 in the ECLIPSE fileformat documentation. + """ + return cfunc.node_is_total( self ) + + @property + def is_rate(self): + """ + Will check if the variable in question is a rate variable. + + The conecpt of rate variabel is important (internally) when + interpolation values to arbitrary times. + """ + return cfunc.node_is_rate( self ) + + + @property + def is_historical(self): + """ + Checks if the key corresponds to a historical variable. + + The check is only based on the last character; all variables + ending with 'H' are considered historical. + """ + return cfunc.node_is_historical( self ) + + + @property + def unit(self): + """ + Returns the unit of this node as a string. + """ + return cfunc.node_unit( self ) + + @property + def wgname(self): + """ + Returns the WGNAME property for this node. + + Many variables do not have the WGNAME property, i.e. the field + related variables like FOPT and the block properties like + BPR:10,10,10. For these variables the function will return + None, and not the ECLIPSE dummy value: ":+:+:+:+". + """ + return cfunc.node_wgname(self) + + + @property + def keyword(self): + """ + Returns the KEYWORD property for this node. + + The KEYWORD property is the main classification property in + the ECLIPSE SMSPEC file. The properties of a variable can be + read from the KEWYORD value; see table 3.4 in the ECLIPSE file + format reference manual. + """ + return cfunc.node_keyword( self ) + + @property + def num(self): + """ + Returns the NUMS value for this keyword; or None. + + Many of the summary keywords have an integer stored in the + vector NUMS as an attribute, i.e. the block properties have + the global index of the cell in the nums vector. If the + variable in question makes use of the NUMS value this property + will return the value, otherwise it will return None: + + sum.smspec_node("FOPT").num => None + sum.smspec_node("BPR:1000").num => 1000 + """ + if cfunc.node_need_num( self ): + return cfunc.node_num(self) + else: + return None + + + + + + class EclSum( CClass ): def __new__( cls , load_case , join_string = ":" , include_restart = True): @@ -490,6 +601,7 @@ class EclSum( CClass ): return index_list + def wells( self , pattern = None ): """ Will return a list of all the well names in case. @@ -634,6 +746,13 @@ class EclSum( CClass ): """ return self.get_vector( key ) + + def check_sim_time( self , date): + """ + Will check if the input date is in the time span [sim_start , sim_end]. + """ + return cfunc.check_sim_time( self , ctime(date) ) + def get_interp( self , key , days = None , date = None): """ @@ -658,7 +777,7 @@ class EclSum( CClass ): else: raise ValueError("days:%s is outside range of simulation: [%g,%g]" % (days , self.first_day , self.sim_length)) elif date: - if cfunc.check_sim_time( self , ctime(date) ): + if self.check_sim_time( date ): return cfunc.get_general_var_from_sim_time( self , ctime(date) , key ) else: raise ValueError("date:%s is outside range of simulation data" % date) @@ -735,7 +854,6 @@ class EclSum( CClass ): raise ValueError("Must supply either days_list or date_list") return vector - def get_from_report( self , key , report_step ): """ @@ -751,11 +869,30 @@ class EclSum( CClass ): """ return cfunc.has_key( self, key ) + + def smspec_node( self , key ): + """ + Will return a EclSMSPECNode instance corresponding to @key. + + The returned EclSMPECNode instance can then be used to ask for + various properties of the variable; i.e. if it is a rate + variable, what is the unit, if it is a total variable and so + on. + """ + if self.has_key( key ): + c_ptr = cfunc.get_var_node( self , key ) + return EclSMSPECNode( c_ptr , self ) + else: + raise KeyError("Summary case does not have key:%s" % key) + + def unit(self , key): """ Will return the unit of @key. """ - return cfunc.get_unit( self , key ) + node = self.smspec_node( key ) + return node.unit + @property def case(self): @@ -1094,6 +1231,7 @@ class EclSum( CClass ): # registering the type map : ecl_kw <-> EclKW cwrapper = CWrapper( libecl.lib ) cwrapper.registerType( "ecl_sum" , EclSum ) +cwrapper.registerType( "smspec_node" , EclSMSPECNode ) # 3. Installing the c-functions used to manipulate ecl_kw instances. @@ -1142,3 +1280,16 @@ cfunc.get_report_time = cwrapper.prototype("time_t ecl_sum_get_r cfunc.fwrite_sum = cwrapper.prototype("void ecl_sum_fwrite(ecl_sum)") cfunc.set_case = cwrapper.prototype("void ecl_sum_set_case(ecl_sum, char*)") + +#----------------------------------------------------------------- +# smspec node related stuff + +cfunc.get_var_node = cwrapper.prototype("c_void_p ecl_sum_get_general_var_node(ecl_sum , char* )") +cfunc.node_is_total = cwrapper.prototype("bool smspec_node_is_total( smspec_node )") +cfunc.node_is_historical = cwrapper.prototype("bool smspec_node_is_historical( smspec_node )") +cfunc.node_is_rate = cwrapper.prototype("bool smspec_node_is_rate( smspec_node )") +cfunc.node_unit = cwrapper.prototype("char* smspec_node_get_unit( smspec_node )") +cfunc.node_wgname = cwrapper.prototype("char* smspec_node_get_wgname( smspec_node )") +cfunc.node_keyword = cwrapper.prototype("char* smspec_node_get_keyword( smspec_node )") +cfunc.node_num = cwrapper.prototype("int smspec_node_get_num( smspec_node )") +cfunc.node_need_num = cwrapper.prototype("bool smspec_node_need_nums( smspec_node )") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/analysis_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/analysis_config.py new file mode 100644 index 0000000000..8425919f67 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/analysis_config.py @@ -0,0 +1,65 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'analysis_config.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class AnalysisConfig(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "analysis_config" , AnalysisConfig ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("analysis_config") + + +cfunc.free = cwrapper.prototype("void analysis_config_free( analysis_config )") +cfunc.get_rerun = cwrapper.prototype("int analysis_config_get_rerun( analysis_config )") +cfunc.set_rerun = cwrapper.prototype("void analysis_config_set_rerun analysis_config, bool)") +cfunc.get_rerun_start = cwrapper.prototype("int analysis_config_get_rerun_start( analysis_config )") +cfunc.set_rerun_start = cwrapper.prototype("void analysis_config_set_rerun_start( analysis_config, int)") +cfunc.get_log_path = cwrapper.prototype("char* analysis_config_get_log_path( analysis_config)") +cfunc.set_log_path = cwrapper.prototype("void analysis_config_set_log_path( analysis_config, char*)") +cfunc.get_alpha = cwrapper.prototype("double analysis_config_get_alpha(analysis_config)") +cfunc.set_alpha = cwrapper.prototype("void analysis_config_set_alpha(analysis_config, double)") +cfunc.get_merge_observations = cwrapper.prototype("bool analysis_config_get_merge_observations(analysis_config)") +cfunc.set_merge_observations = cwrapper.prototype("void analysis_config_set_merge_observations(analysis_config, int)") +cfunc.get_enkf_mode = cwrapper.prototype("int analysis_config_get_enkf_mode(analysis_config)") +cfunc.set_enkf_mode = cwrapper.prototype("void analysis_config_set_enkf_mode(analysis_config, int)") +cfunc.get_truncation = cwrapper.prototype("double analysis_config_get_truncation(analysis_config)") +cfunc.get_truncation = cwrapper.prototype("void analysis_config_set_truncation(analysis_config, double)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/ecl_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/ecl_config.py new file mode 100644 index 0000000000..fffec1a3aa --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/ecl_config.py @@ -0,0 +1,65 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'ecl_config.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class EclConfig(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "ecl_config" , EclConfig ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("ecl_config") + + +cfunc.free = cwrapper.prototype("void ecl_config_free( ecl_config )") +cfunc.get_eclbase = cwrapper.prototype("char* ecl_config_get_eclbase( ecl_config )") +cfunc.get_data_file = cwrapper.prototype("char* ecl_config_get_data_file(ecl_config)") +cfunc.get_gridfile = cwrapper.prototype("char* ecl_config_get_gridfile(ecl_config)") +cfunc.set_gridfile = cwrapper.prototype("void ecl_config_set_grid(ecl_config, char*)") +cfunc.get_schedule = cwrapper.prototype("char* ecl_config_get_schedule_file(ecl_config)") +cfunc.set_schedule = cwrapper.prototype("void ecl_config_set_schedule_file(ecl_config, char*)") +cfunc.get_init_section = cwrapper.prototype("char* ecl_config_get_init_section(ecl_config)") +cfunc.set_init_section = cwrapper.prototype("void ecl_config_set_init_section(ecl_config, char*)") +cfunc.get_refcase_name = cwrapper.prototype("char* ecl_config_get_refcase_name(ecl_config)") +cfunc.set_refcase_name = cwrapper.prototype("void ecl_config_load_refcase(ecl_config, char*)") +cfunc.get_static_kw_list = cwrapper.prototype("c_void_p ecl_config_get_static_kw_list(ecl_config)") +cfunc.clear_static_kw = cwrapper.prototype("void ecl_config_clear_static_kw(ecl_config)") +cfunc.add_static_kw = cwrapper.prototype("void ecl_config_add_static_kw(ecl_config, char*)") +cfunc.get_grid = cwrapper.prototype("c_void_p ecl_config_get_grid(ecl_config)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_config_node.py b/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_config_node.py new file mode 100644 index 0000000000..0bca2c408b --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_config_node.py @@ -0,0 +1,62 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'enkf_config_node.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class EnkfConfigNode(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "enkf_config_node" , EnkfConfigNode ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("enkf_config_node") + + +cfunc.free = cwrapper.prototype("void enkf_config_node_free( enkf_config_node )") +cfunc.get_impl_type = cwrapper.prototype("c_void_p enkf_config_node_get_impl_type(enkf_config_node)") +cfunc.get_ref = cwrapper.prototype("c_void_p enkf_config_node_get_ref(enkf_config_node)") +cfunc.is_valid = cwrapper.prototype("bool enkf_config_node_is_valid(enkf_config_node)") +cfunc.get_min_std_file = cwrapper.prototype("char* enkf_config_node_get_min_std_file(enkf_config_node)") +cfunc.get_enkf_outfile = cwrapper.prototype("char* enkf_config_node_get_enkf_outfile(enkf_config_node)") +cfunc.get_enkf_infile = cwrapper.prototype("char* enkf_config_node_get_enkf_infile(enkf_config_node)") +cfunc.update_gen_kw = cwrapper.prototype("void enkf_config_node_update_gen_kw(enkf_config_node, char*, char*, char*, char*, char*)") +cfunc.update_state_field = cwrapper.prototype("void enkf_config_node_update_state_field(enkf_config_node, int, double, double)") +cfunc.update_parameter_field = cwrapper.prototype("void enkf_config_node_update_parameter_field(enkf_config_node, char*, char*, char*, int, double, double, char*, char*)") +cfunc.update_general_field = cwrapper.prototype("void enkf_config_node_update_general_field(enkf_config_node, char*, char*, char*, char*, int, double, double, char*, char*, char*)") +cfunc.update_gen_data = cwrapper.prototype("void enkf_config_node_update_gen_data(enkf_config_node, int, int, char*, char*, char*, char*, char*, char*)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_main.py b/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_main.py index c988054b85..57b4a319e5 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_main.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_main.py @@ -21,6 +21,17 @@ from ert.util.tvector import * from ert.job_queue.job_queue import JobQueue from enkf_enum import * import ens_config +import ecl_config +import analysis_config +import local_config +import model_config +import enkf_config_node +import gen_kw_config +import gen_data_config +import field_config +import enkf_obs +import plot_config +import site_config import libenkf import ert_local @@ -80,10 +91,39 @@ cwrapper.registerType( "enkf_main" , EnKFMain ) cfunc = CWrapperNameSpace("enkf_main") -cfunc.bootstrap = cwrapper.prototype("c_void_p enkf_main_bootstrap(char*, char*, bool)") -cfunc.free = cwrapper.prototype("void enkf_main_free( enkf_main )") -cfunc.run = cwrapper.prototype("void enkf_main_run( enkf_main , int , bool_vector , int , int , int)") -cfunc.ens_size = cwrapper.prototype("int enkf_main_get_ensemble_size( enkf_main )") -cfunc.get_ens_config = cwrapper.prototype("c_void_p enkf_main_get_ensemble_config( enkf_main )") -cfunc.set_verbose = cwrapper.prototype("void enkf_main_set_verbose( enkf_main , bool )") -cfunc.update = cwrapper.prototype("void enkf_main_UPDATE(enkf_main , int_vector)") +cfunc.bootstrap = cwrapper.prototype("c_void_p enkf_main_bootstrap(char*, char*, bool)") +cfunc.free = cwrapper.prototype("void enkf_main_free( enkf_main )") +cfunc.run = cwrapper.prototype("void enkf_main_run( enkf_main , int , bool_vector , int , int , int)") +cfunc.ens_size = cwrapper.prototype("int enkf_main_get_ensemble_size( enkf_main )") +cfunc.get_ens_config = cwrapper.prototype("c_void_p enkf_main_get_ensemble_config( enkf_main )") +cfunc.set_verbose = cwrapper.prototype("void enkf_main_set_verbose( enkf_main , bool )") +cfunc.update = cwrapper.prototype("void enkf_main_UPDATE(enkf_main , int_vector)") +cfunc.get_model_config = cwrapper.prototype("c_void_p enkf_main_get_model_config( enkf_main )") +cfunc.get_local_config = cwrapper.prototype("c_void_p enkf_main_get_local_config( enkf_main )") +cfunc.set_eclbase = cwrapper.prototype("void enkf_main_set_eclbase( enkf_main, char*)") +cfunc.set_datafile = cwrapper.prototype("void enkf_main_set_data_file( enkf_main, char*)") +cfunc.get_schedule_prediction_file = cwrapper.prototype("char* enkf_main_get_schedule_prediction_file( enkf_main )") +cfunc.set_schedule_prediction_file = cwrapper.prototype("void enkf_main_set_schedule_prediction_file( enkf_main , char*)") +cfunc.get_data_kw = cwrapper.prototype("c_void_p enkf_main_get_data_kw(enkf_main)") +cfunc.clear_data_kw = cwrapper.prototype("void enkf_main_clear_data_kw(enkf_main)") +cfunc.add_data_kw = cwrapper.prototype("void enkf_main_add_data_kw(enkf_main, char*, char*)") +cfunc.get_ensemble_size = cwrapper.prototype("int enkf_main_get_ensemble_size(enkf_main)") +cfunc.resize_ensemble = cwrapper.prototype("void enkf_main_resize_ensemble(int)") +cfunc.del_node = cwrapper.prototype("void enkf_main_del_node(enkf_main, char*)") +cfunc.get_obs = cwrapper.prototype("c_void_p enkf_main_get_obs(enkf_main)") +cfunc.load_obs = cwrapper.prototype("void enkf_main_load_obs(enkf_main, char*)") +cfunc.reload_obs = cwrapper.prototype("void enkf_main_reload_obs(enkf_main)") +cfunc.set_case_table = cwrapper.prototype("void enkf_main_set_case_table(enkf_main, char*)") +cfunc.get_pre_clear_runpath = cwrapper.prototype("bool enkf_main_get_pre_clear_runpath(enkf_main)"), +cfunc.set_pre_clear_runpath = cwrapper.prototype("void enkf_main_set_pre_clear_runpath(enkf_main, bool)") +cfunc.get_ensemble_size = cwrapper.prototype("int enkf_main_get_ensemble_size(enkf_main)"), +cfunc.iget_keep_runpath = cwrapper.prototype("int enkf_main_iget_keep_runpath(enkf_main, int)"), +cfunc.iset_keep_runpath = cwrapper.prototype("void enkf_main_iset_keep_runpath(enkf_main, int, keep_runpath)") +cfunc.get_templates = cwrapper.prototype("c_void_p enkf_main_get_templates(enkf_main)") +cfunc.get_site_config_file = cwrapper.prototype("char* enkf_main_get_site_config_file(enkf_main)") +cfunc.initialize_from_scratch = cwrapper.prototype("int enkf_main_initialize_from_scratch(enkf_main, stringlist, int, int)") +cfunc.get_ensemble_size = cwrapper.prototype("int enkf_main_get_ensemble_size(enkf_main)") +cfunc.get_fs = cwrapper.prototype("c_void_p enkf_main_get_fs(enkf_main)") +cfunc.get_history_length = cwrapper.prototype("int enkf_main_get_history_length(enkf_main)") +cfunc.initialize_from_existing__ = cwrapper.prototype("void enkf_main_initialize_from_existing__(enkf_main, char*, int, int, bool_vector, char*, stringlist)") +cfunc.copy_ensemble = cwrapper.prototype("void enkf_main_copy_ensemble(enkf_main, char*, int, int, char*, int, int, bool_vector, char*, stringlist)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_obs.py b/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_obs.py new file mode 100644 index 0000000000..2706af6419 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_obs.py @@ -0,0 +1,52 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'enkf_obs.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class EnkfObs(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "enkf_obs" , EnkfObs ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("enkf_obs") + + +cfunc.free = cwrapper.prototype("void enkf_obs_free( enkf_obs )") +cfunc.get_config_file = cwrapper.prototype("char* enkf_obs_get_config_file( enkf_obs )") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/ens_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/ens_config.py index 9e80e8982e..49860688ba 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/ens_config.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/ens_config.py @@ -20,8 +20,6 @@ from ert.cwrap.cclass import CClass from ert.util.tvector import * from enkf_enum import * import libenkf -import ert_local - class EnsConfig(CClass): def __init__(self , c_ptr = None): @@ -50,5 +48,12 @@ cwrapper.registerType( "ens_config" , EnsConfig ) cfunc = CWrapperNameSpace("ens_config") -cfunc.free = cwrapper.prototype("void ensemble_config_free( ens_config )") -cfunc.has_key = cwrapper.prototype("bool ensemble_config_has_key( ens_config , char* )") +cfunc.free = cwrapper.prototype("void ensemble_config_free( ens_config )") +cfunc.has_key = cwrapper.prototype("bool ensemble_config_has_key( ens_config , char* )") +cfunc.get_node = cwrapper.prototype("c_void_p ensemble_config_get_node( ens_config , char*)") +cfunc.alloc_keylist = cwrapper.prototype("c_void_p ensemble_config_alloc_keylist( ens_config )") +cfunc.add_summary = cwrapper.prototype("c_void_p ensemble_config_add_summary( ens_config, char*)") +cfunc.add_gen_kw = cwrapper.prototype("c_void_p ensemble_config_add_gen_kw( ens_config, char*)") +cfunc.add_gen_data = cwrapper.prototype("c_void_p ensemble_config_add_gen_data( ens_config, char*)") +cfunc.add_field = cwrapper.prototype("c_void_p ensemble_config_add_field( ens_config, char*, ecl_grid)") +cfunc.alloc_keylist_from_var_type = cwrapper.prototype("c_void_p ensemble_config_alloc_keylist_from_var_type(ens_config, int)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/ert_template.py b/ThirdParty/Ert/devel/python/python/ert/enkf/ert_template.py new file mode 100644 index 0000000000..dbb1ee5bd9 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/ert_template.py @@ -0,0 +1,58 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'ert_template.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class ErtTemplate(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "ert_template" , AnalysisConfig ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("ert_template") + + +cfunc.free = cwrapper.prototype("void ert_template_free( ert_template )") +cfunc.alloc_list = cwrapper.prototype("c_void_p ert_templates_alloc_list(long)"), +cfunc.get_template = cwrapper.prototype("c_void_p ert_templates_get_template(long, char*)"), +cfunc.get_template_file = cwrapper.prototype("char* ert_template_get_template_file(long)"), +cfunc.get_target_file = cwrapper.prototype("char* ert_template_get_target_file(long)"), +cfunc.get_args_as_string = cwrapper.prototype("char* ert_template_get_args_as_string(long)"), +cfunc.clear = cwrapper.prototype("void ert_templates_clear(long)"), +cfunc.add_template = cwrapper.prototype("void ert_templates_add_template(long, char*, char*, char*, char*)"),] diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/field_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/field_config.py new file mode 100644 index 0000000000..3ff7b3a1f5 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/field_config.py @@ -0,0 +1,58 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'field_config.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class GenDataConfig(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "field_config" , GenDataConfig ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("field_config") + + +cfunc.free = cwrapper.prototype("void field_config_free( field_config )") +cfunc.get_type = cwrapper.prototype("int field_config_get_type(field_config)") +cfunc.get_truncation_mode = cwrapper.prototype("int field_config_get_truncation_mode(field_config)") +cfunc.get_truncation_min = cwrapper.prototype("double field_config_get_truncation_min(field_config)") +cfunc.get_truncation_max = cwrapper.prototype("double field_config_get_truncation_max(field_config)") +cfunc.get_init_transform_name = cwrapper.prototype("char* field_config_get_init_transform_name(field_config)") +cfunc.get_output_transform_name = cwrapper.prototype("char* field_config_get_output_transform_name(field_config)") +cfunc.get_init_file_fmt = cwrapper.prototype("char* field_config_get_init_file_fmt(field_config)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/gen_data_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/gen_data_config.py new file mode 100644 index 0000000000..b5f9f4dd07 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/gen_data_config.py @@ -0,0 +1,56 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'gen_data_config.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class GenDataConfig(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "gen_data_config" , GenDataConfig ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("gen_data_config") + + +cfunc.free = cwrapper.prototype("void gen_data_config_free( gen_data_config )") +cfunc.get_output_format = cwrapper.prototype("c_void_p gen_data_config_get_output_format(gen_data_config)") +cfunc.get_input_format = cwrapper.prototype("c_void_p gen_data_config_get_input_format(gen_data_config)") +cfunc.get_template_file = cwrapper.prototype("char* gen_data_config_get_template_file(gen_data_config)") +cfunc.get_template_key = cwrapper.prototype("char* gen_data_config_get_template_key(gen_data_config)") +cfunc.get_init_file_fmt = cwrapper.prototype("char* gen_data_config_get_init_file_fmt(gen_data_config)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/gen_kw_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/gen_kw_config.py new file mode 100644 index 0000000000..66cdf2795b --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/gen_kw_config.py @@ -0,0 +1,54 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'gen_kw_config.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class GenKwConfig(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "gen_kw_config" , GenKwConfig ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("gen_kw_config") + + +cfunc.free = cwrapper.prototype("void gen_kw_config_free( gen_kw_config )") +cfunc.get_template_file = cwrapper.prototype("char* gen_kw_config_get_template_file(gen_kw_config)") +cfunc.get_init_file_fmt = cwrapper.prototype("char* gen_kw_config_get_init_file_fmt(gen_kw_config)") +cfunc.get_parameter_file = cwrapper.prototype("char* gen_kw_config_get_parameter_file(gen_kw_config)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/local_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/local_config.py new file mode 100644 index 0000000000..3b28a60050 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/local_config.py @@ -0,0 +1,55 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'local_config.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class LocalConfig(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "local_config" , LocalConfig ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("local_config") + + +cfunc.free = cwrapper.prototype("void local_config_free( local_config )") +cfunc.get_config_files = cwrapper.prototype("c_void_p local_config_get_config_files( local_config )") +cfunc.clear_config_files = cwrapper.prototype("void local_config_clear_config_files( local_config )") +cfunc.add_config_file = cwrapper.prototype("void local_config_add_config_file( local_config , char*)") + diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/model_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/model_config.py new file mode 100644 index 0000000000..ffb6fd8a11 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/model_config.py @@ -0,0 +1,62 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'model_config.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class ModelConfig(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "model_config" , ModelConfig ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("model_config") + + +cfunc.free = cwrapper.prototype("void model_config_free( model_config )") +cfunc.get_enkf_sched_file = cwrapper.prototype("char* model_config_get_enkf_sched_file( model_config )") +cfunc.set_enkf_sched_file = cwrapper.prototype("void model_config_set_enkf_sched_file( model_config, char*)") +cfunc.get_history_source = cwrapper.prototype("int model_config_get_history_source(model_config)") +cfunc.set_history_source = cwrapper.prototype("void model_config_set_history_source(model_config, int)") +cfunc.get_forward_model = cwrapper.prototype("c_void_p model_config_get_forward_model(model_config)") +cfunc.get_max_resample = cwrapper.prototype("int model_config_get_max_resample(model_config)") +cfunc.set_max_resample = cwrapper.prototype("void model_config_set_max_resample(model_config, int)") +cfunc.get_case_table_file = cwrapper.prototype("char* model_config_get_case_table_file(model_config)") +cfunc.get_runpath_as_char = cwrapper.prototype("char* model_config_get_runpath_as_char(model_config)") +cfunc.set_runpath_fmt = cwrapper.prototype("void model_config_set_runpath_fmt(model_config, char*)") + diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/plot_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/plot_config.py new file mode 100644 index 0000000000..33ea1c309e --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/plot_config.py @@ -0,0 +1,65 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'plot_config.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class PlotConfig(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "plot_config" , PlotConfig ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("plot_config") + + +cfunc.free = cwrapper.prototype("void plot_config_free( plot_config )") +cfunc.get_path = cwrapper.prototype("char* plot_config_get_path(plot_config)") +cfunc.set_path = cwrapper.prototype("void plot_config_set_path(plot_config, char*)") +cfunc.get_driver = cwrapper.prototype("char* plot_config_get_driver(plot_config)") +cfunc.set_driver = cwrapper.prototype("void plot_config_set_driver(plot_config, char*)") +cfunc.get_errorbar_max = cwrapper.prototype("int plot_config_get_errorbar_max(plot_config)") +cfunc.set_errorbar_max = cwrapper.prototype("void plot_config_set_errorbar_max(plot_config, int)") +cfunc.get_width = cwrapper.prototype("int plot_config_get_width(plot_config)") +cfunc.set_width = cwrapper.prototype("void plot_config_set_width(plot_config, int)") +cfunc.get_height = cwrapper.prototype("int plot_config_get_height(plot_config)") +cfunc.set_height = cwrapper.prototype("void plot_config_set_height(plot_config, int)") +cfunc.get_viewer = cwrapper.prototype("char* plot_config_get_viewer(plot_config)") +cfunc.set_viewer = cwrapper.prototype("void plot_config_set_viewer(plot_config, char*)") +cfunc.get_image_type = cwrapper.prototype("char* plot_config_get_image_type(plot_config)") +cfunc.set_image_type = cwrapper.prototype("void plot_config_set_image_type(plot_config, char*)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/site_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/site_config.py new file mode 100644 index 0000000000..a91da3a5b9 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/site_config.py @@ -0,0 +1,84 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'site_config.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class SiteConfig(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "site_config" , SiteConfig ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("site_config") + + +cfunc.free = cwrapper.prototype("void site_config_free( site_config )") +cfunc.get_queue_name = cwrapper.prototype("char* site_config_get_queue_name(site_config)") +cfunc.set_job_queue = cwrapper.prototype("void site_config_set_job_queue(site_config, char*)") +cfunc.get_lsf_queue = cwrapper.prototype("char* site_config_get_lsf_queue(site_config)") +cfunc.set_lsf_queue = cwrapper.prototype("void site_config_set_lsf_queue(site_config, char*)") +cfunc.get_max_running_lsf = cwrapper.prototype("int site_config_get_max_running_lsf(site_config)") +cfunc.set_max_running_lsf = cwrapper.prototype("void site_config_set_max_running_lsf(site_config, int)") +cfunc.get_lsf_request = cwrapper.prototype("char* site_config_get_lsf_request(site_config)") +cfunc.set_lsf_request = cwrapper.prototype("void site_config_set_lsf_request(site_config, char*)") +cfunc.get_rsh_command = cwrapper.prototype("char* site_config_get_rsh_command(site_config)") +cfunc.set_rsh_command = cwrapper.prototype("void site_config_set_rsh_command(site_config, char*)") +cfunc.get_max_running_rsh = cwrapper.prototype("int site_config_get_max_running_rsh(site_config)") +cfunc.set_max_running_rsh = cwrapper.prototype("void site_config_set_max_running_rsh(site_config, int)") +cfunc.get_rsh_host_list = cwrapper.prototype("c_void_p site_config_get_rsh_host_list(site_config)") +cfunc.clear_rsh_host_list = cwrapper.prototype("void site_config_clear_rsh_host_list(site_config)") +cfunc.add_rsh_host = cwrapper.prototype("void site_config_add_rsh_host(site_config, char*, int)") +cfunc.get_max_running_local = cwrapper.prototype("int site_config_get_max_running_local(site_config)") +cfunc.set_max_running_local = cwrapper.prototype("void site_config_set_max_running_local(site_config, int)") +cfunc.get_installed_jobs = cwrapper.prototype("c_void_p site_config_get_installed_jobs(site_config)") +cfunc.get_max_submit = cwrapper.prototype("int site_config_get_max_submit(site_config)") +cfunc.set_max_submit = cwrapper.prototype("void site_config_set_max_submit(site_config, int)") +cfunc.get_license_root_path = cwrapper.prototype("char* site_config_get_license_root_path(site_config)") +cfunc.set_license_root_path = cwrapper.prototype("void site_config_set_license_root_path(site_config, char*)") +cfunc.get_job_script = cwrapper.prototype("char* site_config_get_job_script(site_config)"), +cfunc.set_job_script = cwrapper.prototype("void site_config_set_job_script(site_config, char*)") +cfunc.get_env_hash = cwrapper.prototype("c_void_p site_config_get_env_hash(site_config)"), +cfunc.clear_env = cwrapper.prototype("void site_config_clear_env(site_config)"), +cfunc.setenv = cwrapper.prototype("void site_config_setenv(site_config, char*, char*)") +cfunc.get_path_variables = cwrapper.prototype("c_void_p site_config_get_path_variables(site_config)"), +cfunc.get_path_values = cwrapper.prototype("c_void_p site_config_get_path_values(site_config)"), +cfunc.clear_pathvar = cwrapper.prototype("void site_config_clear_pathvar(site_config)"), +cfunc.update_pathvar = cwrapper.prototype("void site_config_update_pathvar(site_config, char*, char*)") +cfunc.get_installed_jobs = cwrapper.prototype("c_void_p site_config_get_installed_jobs(site_config)"), +cfunc.get_license_root_path = cwrapper.prototype("char* site_config_get_license_root_path(site_config)") diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert/__init__.py b/ThirdParty/Ert/devel/python/python/ert/ert/__init__.py similarity index 100% rename from ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert/__init__.py rename to ThirdParty/Ert/devel/python/python/ert/ert/__init__.py diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert/enums.py b/ThirdParty/Ert/devel/python/python/ert/ert/enums.py similarity index 100% rename from ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert/enums.py rename to ThirdParty/Ert/devel/python/python/ert/ert/enums.py diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert/erttypes.py b/ThirdParty/Ert/devel/python/python/ert/ert/erttypes.py similarity index 100% rename from ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert/erttypes.py rename to ThirdParty/Ert/devel/python/python/ert/ert/erttypes.py diff --git a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert/ertwrapper.py b/ThirdParty/Ert/devel/python/python/ert/ert/ertwrapper.py similarity index 98% rename from ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert/ertwrapper.py rename to ThirdParty/Ert/devel/python/python/ert/ert/ertwrapper.py index bb3e2441b8..b6528e8349 100644 --- a/ThirdParty/Ert/devel/libenkf/applications/ert_gui/lib/ert/ertwrapper.py +++ b/ThirdParty/Ert/devel/python/python/ert/ert/ertwrapper.py @@ -84,7 +84,7 @@ class ErtWrapper: else: sys.exit("Need a value for environment variable LSF_HOME") - self.util = self.__loadLibrary( "libutil" ) + self.util = self.__loadLibrary( "libert_util" ) self.__loadLibrary( "libgeometry" ) self.ecl = self.__loadLibrary( "libecl" ) self.__loadLibrary( "libsched" ) @@ -95,7 +95,6 @@ class ErtWrapper: self.enkf = self.__loadLibrary( "libenkf" ) self.enkf.enkf_main_install_SIGNALS() - self.enkf.enkf_main_init_debug("/prog/sdpsoft/python2.4/bin/python") def __registerDefaultTypes(self): diff --git a/ThirdParty/Ert/devel/python/python/ert/geo/libgeo.py b/ThirdParty/Ert/devel/python/python/ert/geo/libgeo.py index b56fe8b8e8..51a82db28b 100644 --- a/ThirdParty/Ert/devel/python/python/ert/geo/libgeo.py +++ b/ThirdParty/Ert/devel/python/python/ert/geo/libgeo.py @@ -23,4 +23,4 @@ import ctypes import ert.util.libutil import ert.cwrap.clib as clib -lib = clib.ert_load("libgeometry.so") +lib = clib.ert_load("libert_geometry.so") diff --git a/ThirdParty/Ert/devel/python/python/ert/job_queue/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert/job_queue/CMakeLists.txt index 47054d17ee..01e8f151fe 100644 --- a/ThirdParty/Ert/devel/python/python/ert/job_queue/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/python/ert/job_queue/CMakeLists.txt @@ -1 +1 @@ -add_python_target(pythonjob_queue ${PYTHON_INSTALL_PREFIX}/ert/job_queue "driver;__init__;job;job_queue;libjob_queue;queue") +add_python_target(pythonjob_queue ${PYTHON_INSTALL_PREFIX}/ert/job_queue "driver;__init__;job;job_queue;libjob_queue;queue;ext_job") diff --git a/ThirdParty/Ert/devel/python/python/ert/job_queue/ext_job.py b/ThirdParty/Ert/devel/python/python/ert/job_queue/ext_job.py new file mode 100644 index 0000000000..68badc3553 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/job_queue/ext_job.py @@ -0,0 +1,77 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'ext_job.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class ExtJob(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "ext_job" , ExtJob ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("ext_job") + + +cfunc.free = cwrapper.prototype("void ext_job_free( ext_job )") +cfunc.get_help_text = cwrapper.prototype("char* ext_job_get_help_text(ext_job)") +cfunc.get_private_args_as_string = cwrapper.prototype("char* ext_job_get_private_args_as_string(ext_job)") +cfunc.set_private_args_as_string = cwrapper.prototype("void ext_job_set_private_args_from_string(ext_job, char*)") +cfunc.is_private = cwrapper.prototype("int ext_job_is_private(ext_job)") +cfunc.get_config_file = cwrapper.prototype("char* ext_job_get_config_file(ext_job)") +cfunc.set_config_file = cwrapper.prototype("void ext_job_set_config_file(ext_job, char*)") +cfunc.alloc = cwrapper.prototype("c_void_p ext_job_alloc(char*, char*, int)") +cfunc.fscanf_alloc = cwrapper.prototype("c_void_p ext_job_fscanf_alloc(char*, char*, int, char*)") +cfunc.get_stdin_file = cwrapper.prototype("char* ext_job_get_stdin_file(ext_job)") +cfunc.set_stdin_file = cwrapper.prototype("void ext_job_set_stdin_file(ext_job, char*)") +cfunc.get_stdout_file = cwrapper.prototype("char* ext_job_get_stdout_file(ext_job)") +cfunc.set_stdout_file = cwrapper.prototype("void ext_job_set_stdout_file(ext_job, char*)") +cfunc.get_stderr_file = cwrapper.prototype("char* ext_job_get_stderr_file(ext_job)") +cfunc.set_stderr_file = cwrapper.prototype("void ext_job_set_stderr_file(ext_job, char*)") +cfunc.get_target_file = cwrapper.prototype("char* ext_job_get_target_file(ext_job)") +cfunc.set_target_file = cwrapper.prototype("void ext_job_set_target_file(ext_job, char*)") +cfunc.get_executable = cwrapper.prototype("char* ext_job_get_executable(ext_job)") +cfunc.set_executable = cwrapper.prototype("void ext_job_set_executable(ext_job, char*)") +cfunc.get_max_running = cwrapper.prototype("int ext_job_get_max_running(ext_job)") +cfunc.set_max_running = cwrapper.prototype("void ext_job_set_max_running(ext_job, int)") +cfunc.get_max_running_minutes = cwrapper.prototype("int ext_job_get_max_running_minutes(ext_job)") +cfunc.set_max_running_minutes = cwrapper.prototype("void ext_job_set_max_running_minutes(ext_job, int)") +cfunc.get_environment = cwrapper.prototype("c_void_p ext_job_get_environment(ext_job)") +cfunc.set_environment = cwrapper.prototype("void ext_job_add_environment(ext_job, char*, char*)") +cfunc.clear_environment = cwrapper.prototype("void ext_job_clear_environment(ext_job)") +cfunc.save = cwrapper.prototype("void ext_job_save(ext_job)") diff --git a/ThirdParty/Ert/devel/python/python/ert/job_queue/ext_joblist.py b/ThirdParty/Ert/devel/python/python/ert/job_queue/ext_joblist.py new file mode 100644 index 0000000000..d0eba9d220 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/job_queue/ext_joblist.py @@ -0,0 +1,57 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'ext_joblist.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class ExtJoblist(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "ext_joblist" , ExtJoblist ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("ext_joblist") + + +cfunc.free = cwrapper.prototype("void ext_joblist_free( ext_joblist )") +cfunc.alloc_list = cwrapper.prototype("c_void_p ext_joblist_alloc_list(ext_joblist)") +cfunc.get_job = cwrapper.prototype("c_void_p ext_joblist_get_job(ext_joblist, char*)") +cfunc.del_job = cwrapper.prototype("int ext_joblist_del_job(ext_joblist, char*)") +cfunc.has_job = cwrapper.prototype("int ext_joblist_has_job(ext_joblist, char*)") +cfunc.add_job = cwrapper.prototype("void ext_joblist_add_job(ext_joblist, char*, ext_joblist)") +cfunc.get_jobs = cwrapper.prototype("c_void_p ext_joblist_get_jobs(ext_joblist)") diff --git a/ThirdParty/Ert/devel/python/python/ert/job_queue/forward_model.py b/ThirdParty/Ert/devel/python/python/ert/job_queue/forward_model.py new file mode 100644 index 0000000000..3d3de30e77 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/job_queue/forward_model.py @@ -0,0 +1,54 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'forward_model.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class ForwardModel(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "forward_model" , ForwardModel ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("forward_model") + + +cfunc.free = cwrapper.prototype("void forward_model_free( forward_model )") +cfunc.clear = cwrapper.prototype("void forward_model_clear(forward_model)") +cfunc.add_job = cwrapper.prototype("c_void_p forward_model_add_job(forward_model, char*)") +cfunc.alloc_joblist = cwrapper.prototype("c_void_p forward_model_alloc_joblist(forward_model)") diff --git a/ThirdParty/Ert/devel/python/python/ert/job_queue/job_queue.py b/ThirdParty/Ert/devel/python/python/ert/job_queue/job_queue.py index bf9df5a43b..1fcda04d1b 100644 --- a/ThirdParty/Ert/devel/python/python/ert/job_queue/job_queue.py +++ b/ThirdParty/Ert/devel/python/python/ert/job_queue/job_queue.py @@ -20,3 +20,7 @@ import libjob_queue from queue import JobQueue from driver import Driver from job import Job + +import ext_job +import ext_joblist +import forward_model diff --git a/ThirdParty/Ert/devel/python/python/ert/job_queue/libjob_queue.py b/ThirdParty/Ert/devel/python/python/ert/job_queue/libjob_queue.py index defdb93cca..2615a4c36b 100644 --- a/ThirdParty/Ert/devel/python/python/ert/job_queue/libjob_queue.py +++ b/ThirdParty/Ert/devel/python/python/ert/job_queue/libjob_queue.py @@ -18,19 +18,22 @@ import os import sys import ctypes import ert.util.libutil +import ert.config.libconfig import ert.cwrap.clib as clib -# Getting LSF to work properly is quite painful. The situation is a -# mix of internal dependencies comiled into the libjob_queue.so shared -# library, and external dependencies based on the LSF_xxx environment -# variables: +# Getting LSF to work properly is quite painful. The situation +# is a mix of build complexity and LSF specific requirements: # -# 1. If the C-libraries have been compiled with LSF support, -# i.e. the variable INCLUDE_LSF has been set to True in -# local_config.py then the shared library libjob_queue.so will -# depend on the libraries liblsf and libbat; this dependency -# exists even if you have no intention actually using LSF. +# 1. The LSF libraries are accessed from the libjob_queue.so +# library, but observe that the dependancy on the liblsf and +# libbat libraries is through dlopen(), i.e. runtime. This module +# will therefor load happily without access to the lsf libraries. +# +# If you at a later stage create a lsf driver the runtime +# environment must be able to locate the liblsf.so, libbat.so and +# libnsl.so shared libraries, either through LD_LIBRARY_PATH or +# other means. # # 2. To actually use LSF you need a whole list of environment # variables to be set: LSF_BINDIR , LSF_LIBDIR , XLDF_UIDDIR , @@ -38,9 +41,7 @@ import ert.cwrap.clib as clib # related to ERT or the Python bindings. The normal way to # achieve this is by sourcing a shell script. # -# In the current code we try three different things: -# -# 1: If the environment variable LSF_HOME is set we set the +# If the environment variable LSF_HOME is set we set the # remaining LSF variables according to: # # LSF_BINDIR = $LSF_HOME/bin @@ -54,80 +55,19 @@ import ert.cwrap.clib as clib # already have a value, furthermore it should be observed that # the use of an LSF_HOME variable is something invented with ERT, # and not standard LSF approach. -# -# 2: If the variable LSF_LIBDIR is set (either from 1: above, or -# from external scope), we try to load the lsf libraries from -# this location. -# -# 3. If we have no value for LSF_LIBDIR we just try a wild shot for -# loading the LSF libraries. -# -# -# When we have tried to load the LSF libraries we continue on to load -# the libjob_queue.so ERT library. Then the following possibilities -# exist: -# -# 1. The libjob_queue library has been built without LSF support, -# i.e. INCLUDE_LSF == False, in this case the loading of -# libjob_queue.so is "guaranteed" to suceed. -# -# 2. The libjob_queue library has been built with LSF support, -# i.e. INCLUDE_LSF == True: -# -# - If we succeeded in loading liblsf/libbat in the previous -# section, loading libjob_queue should.so work out OK. -# -# - If we failed to load libbat/liblsf libjob_queue will not -# load, and the whole thing will go up in flames. -# def setenv( var , value): if not os.getenv( var ): os.environ[ var ] = value -# 1: Setting up the full LSF environment +# Set up the full LSF environment - based onf LSF_HOME LSF_HOME = os.getenv( "LSF_HOME") if LSF_HOME: - setenv( "LSF_BINDIR" , "%s/bin" % LSF_HOME ) - setenv( "LSF_LIBDIR" , "%s/lib" % LSF_HOME ) - setenv( "XLSF_UIDDIR" , "%s/lib/uid" % LSF_HOME ) + setenv( "LSF_BINDIR" , "%s/bin" % LSF_HOME ) + setenv( "LSF_LIBDIR" , "%s/lib" % LSF_HOME ) + setenv( "XLSF_UIDDIR" , "%s/lib/uid" % LSF_HOME ) setenv( "LSF_SERVERDIR" , "%s/etc" % LSF_HOME) - setenv( "LSF_ENVDIR" , "%s/conf" % LSF_HOME) # This one might be too simple minded. - - -# 2: Loading the LSF libraries -LSF_LIBDIR = os.getenv("LSF_LIBDIR") -try: - clib.load("libnsl.so" , "libnsl.so.1") - clib.load("libnsl.so.1") - if LSF_LIBDIR: - clib.load("%s/liblsf.so" % LSF_LIBDIR) - clib.load("%s/libbat.so" % LSF_LIBDIR) - else: - clib.load( "liblsf.so" ) - clib.load( "libbat.so" ) - HAVE_LSF = True -except: - HAVE_LSF = False - - -# 3: Loading the libjob_queue library, which might (depending on the -# value of INCLUDE_LSF used when building) depend on the LSF -# libraries we tried to load at the previous step. -clib.ert_load("libconfig.so" ) -try: - lib = clib.ert_load("libjob_queue.so") -except: - if HAVE_LSF == False: - sys.stderr.write("** Failed to load the libjob_queue library, \n") - sys.stderr.write("** have previosuly failed to load the LSF\n") - sys.stderr.write("** libraries liblsf & libbat - that might be\n") - sys.stderr.write("** the reason ... ") - if LSF_LIBDIR: - sys.stderr.write("** LSF_LIBDIR = %s\n" % LSF_LIBDIR) - else: - sys.stderr.write("** LSF_LIBDIR = \n") - sys.exit("Failed to load library: libjob_queue") - + setenv( "LSF_ENVDIR" , "%s/conf" % LSF_HOME) # This is wrong: Statoil: /prog/LSF/conf +lib = clib.ert_load("libjob_queue.so") diff --git a/ThirdParty/Ert/devel/python/python/ert/util/latex.py b/ThirdParty/Ert/devel/python/python/ert/util/latex.py index e60d83ef56..6df9052cd8 100644 --- a/ThirdParty/Ert/devel/python/python/ert/util/latex.py +++ b/ThirdParty/Ert/devel/python/python/ert/util/latex.py @@ -32,8 +32,13 @@ class LaTeX(CClass): def runpath(self): return cfunc.get_runpath( self ) - def compile(self , ignore_errors = False , with_xref = False): - return cfunc.compile( self , ignore_errors , with_xref) + def compile(self , ignore_errors = False , with_xref = False , cleanup = True): + return cfunc.compile( self , ignore_errors , with_xref , cleanup) + + @property + def in_place(self): + return cfunc.compile_in_place( self ) + #----------------------------------------------------------------- def set_target( self , target_file): @@ -55,6 +60,12 @@ class LaTeX(CClass): timeout = property( get_timeout , set_timeout) #----------------------------------------------------------------- + def link_content( self , directory ): + cfunc.link_directory_content( self , directory ) + + def link_path( self , path): + cfunc.link_path( self , path) + cwrapper = CWrapper( libutil.lib ) cwrapper.registerType( "latex" , LaTeX ) @@ -63,9 +74,12 @@ cwrapper.registerType( "latex" , LaTeX ) cfunc = CWrapperNameSpace("latex") cfunc.alloc = cwrapper.prototype("c_void_p latex_alloc( char* , bool )") cfunc.free = cwrapper.prototype("void latex_free( latex )") -cfunc.compile = cwrapper.prototype("bool latex_compile(latex , bool , bool)") +cfunc.compile = cwrapper.prototype("bool latex_compile(latex , bool , bool , bool)") cfunc.get_runpath = cwrapper.prototype("char* latex_get_runpath( latex )") cfunc.get_target = cwrapper.prototype("char* latex_get_target_file( latex )") cfunc.set_target = cwrapper.prototype("void latex_set_target_file( latex , char* )") cfunc.set_timeout = cwrapper.prototype("void latex_set_timeout( latex , int )") cfunc.get_timeout = cwrapper.prototype("int latex_get_timeout( latex )") +cfunc.compile_in_place = cwrapper.prototype("bool latex_compile_in_place( latex )"); +cfunc.link_directory_content = cwrapper.prototype("void latex_link_directory_content( latex , char*)"); +cfunc.link_path = cwrapper.prototype("void latex_link_path( latex , char*)"); diff --git a/ThirdParty/Ert/devel/python/python/ert/util/log.py b/ThirdParty/Ert/devel/python/python/ert/util/log.py new file mode 100644 index 0000000000..29a597e95d --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/util/log.py @@ -0,0 +1,53 @@ +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'log.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import ctypes +from ert.cwrap.cwrap import * +from ert.cwrap.cclass import CClass +from ert.util.tvector import * +from enkf_enum import * +import libenkf +class Log(CClass): + + def __init__(self , c_ptr = None): + self.owner = False + self.c_ptr = c_ptr + + + def __del__(self): + if self.owner: + cfunc.free( self ) + + + def has_key(self , key): + return cfunc.has_key( self ,key ) + + + +################################################################## + +cwrapper = CWrapper( libenkf.lib ) +cwrapper.registerType( "log" , Log ) + +# 3. Installing the c-functions used to manipulate ecl_kw instances. +# These functions are used when implementing the EclKW class, not +# used outside this scope. +cfunc = CWrapperNameSpace("log") +cfunc.free = cwrapper.prototype("void log( log )") +cfunc.get_filename = cwrapper.prototype("char* log_get_filename(long)") +cfunc.reset_filename = cwrapper.prototype("void log_reset_filename(long, char*)") +cfunc.get_level = cwrapper.prototype("int log_get_level(long)") +cfunc.set_level = cwrapper.prototype("void log_set_level(long, int)") diff --git a/ThirdParty/Ert/devel/python/python/ert/util/stringlist.py b/ThirdParty/Ert/devel/python/python/ert/util/stringlist.py index 0606551e3e..6fa3ab7a7b 100644 --- a/ThirdParty/Ert/devel/python/python/ert/util/stringlist.py +++ b/ThirdParty/Ert/devel/python/python/ert/util/stringlist.py @@ -146,6 +146,18 @@ class StringList(CClass): return buffer + def pop(self): + """ + Will remove the last element from the list and return it. + + Will raise IndexError if list is empty. + """ + if len(self): + return cfunc.pop( self ) + else: + raise IndexError("pop() failed - the list is empty") + + def append(self, s): """ Appends a new string @s to list. @@ -169,6 +181,17 @@ class StringList(CClass): slist.append( s ) return slist + @property + def last(self): + """ + Will return the last element in list. Raise IndexError if empty. + """ + if len(self): + return cfunc.last( self ) + else: + raise IndexError("The list is empty") + + def sort(self , cmp_flag = 0): """ Will sort the list inplace. @@ -196,3 +219,5 @@ cfunc.stringlist_iget = cwrapper.prototype("char* stringlist_iget( stringl cfunc.stringlist_get_size = cwrapper.prototype("int stringlist_get_size( stringlist )") cfunc.contains = cwrapper.prototype("bool stringlist_contains(stringlist , char*)") cfunc.sort = cwrapper.prototype("void stringlist_python_sort( stringlist , int)") +cfunc.pop = cwrapper.prototype("char* stringlist_pop( stringlist )") +cfunc.last = cwrapper.prototype("char* stringlist_get_last( stringlist )") diff --git a/ThirdParty/Ert/devel/python/python/ert/util/tvector.py b/ThirdParty/Ert/devel/python/python/ert/util/tvector.py index 9813fb6a35..4b30ebe5ab 100644 --- a/ThirdParty/Ert/devel/python/python/ert/util/tvector.py +++ b/ThirdParty/Ert/devel/python/python/ert/util/tvector.py @@ -576,6 +576,31 @@ class BoolVector(TVector): obj = TVector.__new__( cls ) return obj + + + @classmethod + def active_mask(cls , range_string): + """ + Will create a BoolVector instance with the values from @range_string. + + The range_string input should be of the type "1,3-5,9,17", + i.e. integer values separated by commas, and dashes to + represent ranges. If the input string contains ANY invalid + characters the returned active list will be empty: + + "1,4-7,10" => {F,T,F,F,T,T,T,T,F,F,T} + "1,4-7,10X" => {} + + The empty list will evaluate to false + """ + new_obj = BoolVector.__new__(cls) + c_ptr = cfunc.create_active_mask( range_string ) + new_obj.init_cobj( c_ptr , new_obj.free ) + return new_obj + + + + @@ -622,6 +647,28 @@ class IntVector(TVector): obj = TVector.__new__( cls ) return obj + @classmethod + def active_list(cls , range_string): + """ + Will create a IntVector instance with the values from @range_string. + + The range_string input should be of the type "1,3-5,9,17", + i.e. integer values separated by commas, and dashes to + represent ranges. If the input string contains ANY invalid + characters the returned active list will be empty: + + "1,4-7,10" => {1,4,5,6,7,10} + "1,4-7,10X" => {} + + The empty list will evaluate to false + """ + new_obj = IntVector.__new__(cls) + c_ptr = cfunc.create_active_list( range_string ) + new_obj.init_cobj( c_ptr , new_obj.free ) + return new_obj + + + ################################################################# buffer_from_ptr = ctypes.pythonapi.PyBuffer_FromMemory @@ -734,3 +781,8 @@ cfunc.bool_vector_get_default = cwrapper.prototype("bool bool_vector_g cfunc.bool_vector_alloc_data_copy = cwrapper.prototype("bool* bool_vector_alloc_data_copy( bool_vector )") cfunc.bool_vector_data_ptr = cwrapper.prototype("bool* bool_vector_get_ptr( bool_vector )") cfunc.bool_vector_element_size = cwrapper.prototype("int bool_vector_element_size( bool_vector )") + +#----------------------------------------------------------------- + +cfunc.create_active_list = cwrapper.prototype("c_void_p string_util_alloc_active_list( char* )") +cfunc.create_active_mask = cwrapper.prototype("c_void_p string_util_alloc_active_mask( char* )") diff --git a/ThirdParty/Ert/devel/python/python/ert/well/libwell.py b/ThirdParty/Ert/devel/python/python/ert/well/libwell.py index 91e6d107b6..6666bbc502 100644 --- a/ThirdParty/Ert/devel/python/python/ert/well/libwell.py +++ b/ThirdParty/Ert/devel/python/python/ert/well/libwell.py @@ -1,4 +1,4 @@ import ert.ecl.libecl import ert.cwrap.clib as clib -lib = clib.load("libwell.so") +lib = clib.load("libecl_well.so") diff --git a/ThirdParty/Ert/devel/python/test/CMakeLists.txt b/ThirdParty/Ert/devel/python/test/CMakeLists.txt index 8194bac11f..62ac45fc5b 100644 --- a/ThirdParty/Ert/devel/python/test/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/test/CMakeLists.txt @@ -1,2 +1,2 @@ -set(PYTHON_INSTALL_PREFIX "/python/test") +set(PYTHON_INSTALL_PREFIX "python/test") add_python_target(python_tests ${PYTHON_INSTALL_PREFIX} "ecl_isosurf;enkf_test;ens_config_test;file_test;fortio_test;grav_test;grdecl_test;grid_test0;grid_test;import_test;job_test;kw_test;large_mem_test;latex_test;petrel_kw;poly_test;region_test;restart_test;rft_test;sched_test;stringlist_test;sum_test;test_all;test_fast;test_util;troll_test;util_test") diff --git a/ThirdParty/Ert/devel/python/test/config_test.py b/ThirdParty/Ert/devel/python/test/config_test.py new file mode 100644 index 0000000000..3086b4f0cf --- /dev/null +++ b/ThirdParty/Ert/devel/python/test/config_test.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Statoil ASA, Norway. +# +# The file 'config_test.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + +import os +import unittest +import stat +import math +import ert +import ert.ecl.ecl as ecl +import ert.config.config as config +import ert.config.config_enums as config_enums + +import sys +from test_util import * + + + +class ConfigTest( unittest.TestCase ): + + def setUp( self ): + self.file_list = [] + + + def test_enums(self): + self.assertTrue( config_enums.content_type.CONFIG_STRING ) + self.assertTrue( config_enums.content_type.CONFIG_INVALID ) + self.assertTrue( config_enums.unrecognized.CONFIG_UNRECOGNIZED_ERROR ) + + + + def test_parse(self): + conf = config.ConfigParser() + conf.add("FIELD" , False) + schema_item = conf.add("RSH_HOST" , False) + self.assertTrue( isinstance( schema_item , config.SchemaItem )) + self.assertTrue( conf.parse("test-data/local/config/simple_config" , unrecognized = config_enums.unrecognized.CONFIG_UNRECOGNIZED_IGNORE) ) + + + content_item = conf["RSH_HOST"] + self.assertTrue( isinstance( content_item , config.ContentItem )) + self.assertTrue( conf["BJARNE"] is None ) + + self.assertTrue( len(content_item) == 1) + self.assertRaises( ValueError , content_item.__getitem__ , "BJARNE") + self.assertRaises( IndexError , content_item.__getitem__ , 10 ) + + content_node = content_item[0] + self.assertTrue( isinstance( content_node , config.ContentNode )) + + self.assertTrue( len(content_node) == 2) + self.assertRaises( ValueError , content_node.__getitem__ , "BJARNE") + self.assertRaises( IndexError , content_node.__getitem__ , 10 ) + self.assertTrue( content_node[1] == "be-lx633214:2") + + self.assertTrue( content_node.content( sep = ",") == "be-lx655082:2,be-lx633214:2") + self.assertTrue( content_node.content( ) == "be-lx655082:2 be-lx633214:2") + + + content_item = conf["FIELD"] + self.assertTrue( len(content_item) == 5) + self.assertRaises(IOError , config.ConfigParser.parse , conf , "DoesNotExits") + + + + def test_schema(self): + schema_item = config.SchemaItem("TestItem") + self.assertTrue( isinstance( schema_item , config.SchemaItem )) + self.assertTrue( schema_item.iget_type( 6 ) == config_enums.content_type.CONFIG_STRING ) + schema_item.iset_type( 0 , config_enums.content_type.CONFIG_INT ) + self.assertTrue( schema_item.iget_type( 0 ) == config_enums.content_type.CONFIG_INT ) + schema_item.set_argc_minmax( 3 , 6) + + + +def fast_suite(): + suite = unittest.TestSuite() + suite.addTest( ConfigTest( 'test_enums' )) + suite.addTest( ConfigTest( 'test_schema' )) + suite.addTest( ConfigTest( 'test_parse' )) + return suite + + + +if __name__ == "__main__": + unittest.TextTestRunner().run( fast_suite() ) + + diff --git a/ThirdParty/Ert/devel/python/test/latex_test.py b/ThirdParty/Ert/devel/python/test/latex_test.py index 9f9f4a4993..ae2de24f2f 100644 --- a/ThirdParty/Ert/devel/python/test/latex_test.py +++ b/ThirdParty/Ert/devel/python/test/latex_test.py @@ -41,15 +41,22 @@ class LaTeXTest( unittest.TestCase ): def test_cleanup( self ): lx = latex.LaTeX( "%s/report_OK.tex" % statoil_path , in_place = True ) + self.assertTrue( lx.in_place ) self.assertTrue( lx.compile() ) for ext in ["log" , "aux" , "nav" , "out" , "snm" , "toc"]: self.assertFalse( os.path.exists( "%s/report_OK.%s" % (statoil_path , ext) )) lx = latex.LaTeX( "%s/report_OK.tex" % statoil_path , in_place = False ) + self.assertFalse( lx.in_place ) run_path = lx.runpath self.assertTrue( lx.compile() ) self.assertFalse( os.path.exists( run_path ) ) + lx = latex.LaTeX( "%s/report_OK.tex" % statoil_path , in_place = False ) + run_path = lx.runpath + self.assertTrue( lx.compile( cleanup = False) ) + self.assertTrue( os.path.exists( "%s/report_OK.log" % run_path)) + def test_report(self): @@ -61,12 +68,19 @@ class LaTeXTest( unittest.TestCase ): self.assertTrue( lx.compile() ) + def test_target(self): + lx = latex.LaTeX( "%s/report_OK.tex" % statoil_path ) + self.assertTrue( lx.compile() ) + self.assertTrue( os.path.exists( lx.target )) + + def fast_suite(): suite = unittest.TestSuite() suite.addTest( LaTeXTest( 'test1' )) suite.addTest( LaTeXTest( 'test_report' )) suite.addTest( LaTeXTest( 'test_cleanup' )) + suite.addTest( LaTeXTest( 'test_target' )) return suite diff --git a/ThirdParty/Ert/devel/python/test/local_bash b/ThirdParty/Ert/devel/python/test/local_bash index 9c1b3b4173..828ca31a33 100644 --- a/ThirdParty/Ert/devel/python/test/local_bash +++ b/ThirdParty/Ert/devel/python/test/local_bash @@ -1,13 +1,14 @@ -ln -sf ../../../build/lib/libert_util.so ../lib/libert_util.so -ln -sf ../../../build/lib/libgeometry.so ../lib/libgeometry.so -ln -sf ../../../build/lib/libanalysis.so ../lib/libanalysis.so -ln -sf ../../../build/lib/libecl.so ../lib/libecl.so -ln -sf ../../../build/lib/librms.so ../lib/librms.so -ln -sf ../../../build/lib/libsched.so ../lib/libsched.so -ln -sf ../../../build/lib/libenkf.so ../lib/libenkf.so -ln -sf ../../../build/lib/libjob_queue.so ../lib/libjob_queue.so -ln -sf ../../../build/lib/libconfig.so ../lib/libconfig.so -ln -sf ../../../build/lib/libwell.so ../lib/libwell.so +mkdir -p ../lib64 +ln -sf ../../../build/lib64/libert_util.so ../lib64/libert_util.so +ln -sf ../../../build/lib64/libert_geometry.so ../lib64/libert_geometry.so +ln -sf ../../../build/lib64/libanalysis.so ../lib64/libanalysis.so +ln -sf ../../../build/lib64/libecl.so ../lib64/libecl.so +ln -sf ../../../build/lib64/librms.so ../lib64/librms.so +ln -sf ../../../build/lib64/libsched.so ../lib64/libsched.so +ln -sf ../../../build/lib64/libenkf.so ../lib64/libenkf.so +ln -sf ../../../build/lib64/libjob_queue.so ../lib64/libjob_queue.so +ln -sf ../../../build/lib64/libconfig.so ../lib64/libconfig.so +ln -sf ../../../build/lib64/libecl_well.so ../lib64/libecl_well.so export PYTHONPATH=$PWD/../python:$PYTHONPATH diff --git a/ThirdParty/Ert/devel/python/test/local_csh b/ThirdParty/Ert/devel/python/test/local_csh index 9b3f8a807a..874de02c90 100644 --- a/ThirdParty/Ert/devel/python/test/local_csh +++ b/ThirdParty/Ert/devel/python/test/local_csh @@ -1,12 +1,13 @@ -ln -sf ../../../build/lib/libert_util.so ../lib/libert_util.so -ln -sf ../../../build/lib/libgeometry.so ../lib/libgeometry.so -ln -sf ../../../build/lib/libanalysis.so ../lib/libanalysis.so -ln -sf ../../../build/lib/libecl.so ../lib/libecl.so -ln -sf ../../../build/lib/librms.so ../lib/librms.so -ln -sf ../../../build/lib/libsched.so ../lib/libsched.so -ln -sf ../../../build/lib/libenkf.so ../lib/libenkf.so -ln -sf ../../../build/lib/libjob_queue.so ../lib/libjob_queue.so -ln -sf ../../../build/lib/libconfig.so ../lib/libconfig.so -ln -sf ../../../build/lib/libwell.so ../lib/libwell.so +mkdir -p ../lib64 +ln -sf ../../../build/lib64/libert_util.so ../lib64/libert_util.so +ln -sf ../../../build/lib64/libert_geometry.so ../lib64/libert_geometry.so +ln -sf ../../../build/lib64/libanalysis.so ../lib64/libanalysis.so +ln -sf ../../../build/lib64/libecl.so ../lib64/libecl.so +ln -sf ../../../build/lib64/librms.so ../lib64/librms.so +ln -sf ../../../build/lib64/libsched.so ../lib64/libsched.so +ln -sf ../../../build/lib64/libenkf.so ../lib64/libenkf.so +ln -sf ../../../build/lib64/libjob_queue.so ../lib64/libjob_queue.so +ln -sf ../../../build/lib64/libconfig.so ../lib64/libconfig.so +ln -sf ../../../build/lib64/libecl_well.so ../lib64/libecl_well.so setenv PYTHONPATH $PWD/../python:$PYTHONPATH diff --git a/ThirdParty/Ert/devel/python/test/restart_test.py b/ThirdParty/Ert/devel/python/test/restart_test.py index d6bf3674d1..4aa7382244 100644 --- a/ThirdParty/Ert/devel/python/test/restart_test.py +++ b/ThirdParty/Ert/devel/python/test/restart_test.py @@ -26,9 +26,10 @@ import ert import ert.ecl.ecl as ecl from test_util import approx_equal, approx_equalv, file_equal - -file = "test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST" -fmt_file = "test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.FUNRST" +xfile0 = "test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.X0000" +file = "test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST" +fmt_file = "test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.FUNRST" +grid_file = "test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID" def load_missing(): ecl.EclFile( "No/Does/not/exist") @@ -47,15 +48,16 @@ class RestartTest( unittest.TestCase ): if os.path.exists( file ): os.unlink( file ) + - def test_report(self): - self.assertTrue( ecl.EclFile.contains_report_step( file , 4 )) - self.assertTrue( ecl.EclFile.contains_report_step( file , 0 )) - self.assertTrue( ecl.EclFile.contains_report_step( file , 62 )) - self.assertFalse( ecl.EclFile.contains_report_step( file , -1 )) - self.assertFalse( ecl.EclFile.contains_report_step( file , 100 )) + def test_report_file(self , fname): + self.assertTrue( ecl.EclFile.contains_report_step( fname , 4 )) + self.assertTrue( ecl.EclFile.contains_report_step( fname , 0 )) + self.assertTrue( ecl.EclFile.contains_report_step( fname , 62 )) + self.assertFalse( ecl.EclFile.contains_report_step( fname , -1 )) + self.assertFalse( ecl.EclFile.contains_report_step( fname , 100 )) - f = ecl.EclFile( file ) + f = ecl.EclFile( fname ) self.assertTrue( f.has_report_step( 4 )) self.assertTrue( f.has_report_step( 0 )) self.assertTrue( f.has_report_step( 62 )) @@ -64,9 +66,12 @@ class RestartTest( unittest.TestCase ): self.assertFalse( f.has_report_step( 100 )) + def test_report(self): + self.test_report_file(file) - def test_dates(self): + + def test_date(self): f = ecl.EclFile( file ) self.assertTrue( f.has_sim_time( datetime.datetime( 2001 , 6 , 1) )) self.assertFalse( f.has_sim_time( datetime.datetime( 2005 , 6 , 1) )) @@ -78,6 +83,50 @@ class RestartTest( unittest.TestCase ): self.assertFalse( ecl.EclFile.contains_sim_time( file , datetime.datetime( 1999 , 6 , 1) )) self.assertFalse( ecl.EclFile.contains_sim_time( file , datetime.datetime( 2001 , 6 , 11) )) + + + + def test_report_list_file(self , fname , rlist0): + rlist = ecl.EclFile.file_report_list( fname ) + self.assertTrue( approx_equalv( rlist , rlist0 )) + + f = ecl.EclFile( fname ) + rlist = f.report_list + self.assertTrue( approx_equalv( rlist , rlist0 )) + + + + def test_report_list(self): + rlist0 = range(63) + self.test_report_list_file( file , rlist0 ) + + rlist0 = [0] + self.test_report_list_file( xfile0 , rlist0 ) + + f = ecl.EclFile( grid_file ) + self.assertRaises( TypeError , ecl.EclFile.file_report_list) + + + def test_dates(self): + f = ecl.EclFile(file) + dates = f.dates + self.assertTrue( len(dates) == 63 ) + + f = ecl.EclFile(xfile0) + dates = f.dates + self.assertTrue( len(dates) == 1 ) + self.assertTrue( dates[0] == datetime.datetime(2000,1,1)) + + + + def test_name(self): + f = ecl.EclFile( file ) + self.assertTrue( f.name == file ) + + f = ecl.EclFile( xfile0 ) + self.assertTrue( f.name == xfile0 ) + + def test_kw( self ): f = ecl.EclFile( file ) @@ -93,16 +142,21 @@ class RestartTest( unittest.TestCase ): self.assertTrue( kw4 is None ) + def fast_suite(): suite = unittest.TestSuite() + suite.addTest( RestartTest( 'test_name' )) suite.addTest( RestartTest( 'test_report' )) - suite.addTest( RestartTest( 'test_dates' )) + suite.addTest( RestartTest( 'test_date' )) suite.addTest( RestartTest( 'test_kw' )) + suite.addTest( RestartTest( 'test_report_list' )) + suite.addTest( RestartTest( 'test_dates' )) return suite if __name__ == "__main__": unittest.TextTestRunner().run( fast_suite() ) + diff --git a/ThirdParty/Ert/devel/python/test/stringlist_test.py b/ThirdParty/Ert/devel/python/test/stringlist_test.py index 7b4d19d2aa..7a441f9176 100644 --- a/ThirdParty/Ert/devel/python/test/stringlist_test.py +++ b/ThirdParty/Ert/devel/python/test/stringlist_test.py @@ -32,6 +32,21 @@ path = "test-data/Statoil/ECLIPSE/Gurbat" case = "%s/%s" % (path , base) +def pop_empty(): + s = StringList( initial = initList ) + s.pop() + s.pop() + s.pop() + s.pop() + +def last_empty(): + s = StringList( initial = initList ) + s.pop() + s.pop() + s.pop() + s.last + + class StringListTest( unittest.TestCase ): def setUp( self ): @@ -44,6 +59,22 @@ class StringListTest( unittest.TestCase ): del s return st + def test_pop( self ): + s = StringList( initial = initList ) + s1 = s.pop() + self.assertTrue( len(s) == 2 ) + self.assertTrue( s1 == "S33") + + s1 = s.pop() + self.assertTrue( len(s) == 1 ) + self.assertTrue( s1 == "SABC") + + s1 = s.pop() + self.assertTrue( len(s) == 0 ) + self.assertTrue( s1 == "S1") + + self.assertRaises( IndexError , pop_empty ) + def test_create( self ): s = StringList() @@ -61,12 +92,19 @@ class StringListTest( unittest.TestCase ): for i in range(len(s)): self.assertTrue( s3[i] == initList[i] ) + def test_last( self ): + s = StringList( initial = initList ) + l = s.last + self.assertTrue( "S33" == l ) + self.assertRaises( IndexError , last_empty) + def test_reference(self): sum = ecl.EclSum( case ) wells = sum.wells() self.assertTrue( approx_equalv( wells , ['OP_1','OP_2','OP_3','OP_4','OP_5','WI_1','WI_2','WI_3'])) - + self.assertTrue( isinstance( wells , StringList )) + @@ -74,6 +112,8 @@ def fast_suite(): suite = unittest.TestSuite() suite.addTest( StringListTest( 'test_create' )) suite.addTest( StringListTest( 'test_reference' )) + suite.addTest( StringListTest( 'test_pop' )) + suite.addTest( StringListTest( 'test_last' )) return suite diff --git a/ThirdParty/Ert/devel/python/test/sum_test.py b/ThirdParty/Ert/devel/python/test/sum_test.py index 6fe607f3e2..c2b254f8fa 100644 --- a/ThirdParty/Ert/devel/python/test/sum_test.py +++ b/ThirdParty/Ert/devel/python/test/sum_test.py @@ -95,6 +95,8 @@ class SumTest( unittest.TestCase ): sum = self.sum d = sum.dates + self.assertEqual( d[0] , datetime.datetime( 2000 , 1 , 1 , 0 , 0 , 0)) + self.assertEqual( d[62] , datetime.datetime( 2004 , 12 , 31 , 0 , 0 , 0)) self.assertEqual( len(d) , 63 ) self.assertEqual( d[25] , datetime.datetime( 2001 , 12 , 1 , 0 , 0 , 0)) self.assertEqual( sum.iget_date( 25 ) , datetime.datetime( 2001 , 12 , 1 , 0 , 0 , 0)) @@ -105,6 +107,9 @@ class SumTest( unittest.TestCase ): days = sum.days self.assertTrue( approx_equal( days[50] , 1461 )) + self.assertEqual( sum.start_time , datetime.datetime( 2000 , 1 , 1 , 0 , 0 , 0)) + self.assertEqual( sum.end_time , datetime.datetime( 2004 , 12 , 31 , 0 , 0 , 0)) + self.assertTrue( sum.check_sim_time(datetime.datetime( 2004 , 12 , 31 , 0 , 0 , 0))) def test_keys(self): sum = self.sum @@ -176,6 +181,55 @@ class SumTest( unittest.TestCase ): os.chdir( cwd ) + + + def test_var_properties( self ): + sum = self.sum + self.assertRaises( KeyError , sum.smspec_node , "BJARNE" ) + + node = sum.smspec_node( "FOPT" ) + self.assertTrue( node.is_total ) + self.assertFalse( node.is_historical ) + + node = sum.smspec_node( "FOPR" ) + self.assertFalse( node.is_total ) + self.assertFalse( node.is_historical ) + self.assertTrue( node.keyword == "FOPR" ) + + node = sum.smspec_node( "FOPRH" ) + self.assertFalse( node.is_total ) + self.assertTrue( node.is_historical ) + self.assertTrue( node.is_rate ) + self.assertTrue( node.keyword == "FOPRH" ) + + node = sum.smspec_node( "WOPR:OP_1" ) + self.assertFalse( node.is_total ) + self.assertTrue( node.is_rate ) + self.assertTrue( node.keyword == "WOPR" ) + + node = sum.smspec_node( "WOPT:OP_1" ) + self.assertTrue( node.is_total ) + self.assertFalse( node.is_rate ) + self.assertTrue( node.unit == "SM3" ) + self.assertTrue( node.wgname == "OP_1") + self.assertTrue( node.keyword == "WOPT" ) + + self.assertTrue( sum.unit( "FOPR" ) == "SM3/DAY") + + + node = sum.smspec_node( "FOPTH" ) + self.assertTrue( node.is_total ) + self.assertFalse( node.is_rate ) + self.assertTrue( node.wgname is None ) + + node = sum.smspec_node( "FOPTH" ) + self.assertTrue( node.num is None ) + + node = sum.smspec_node( "BPR:1095" ) + self.assertTrue( node.num == 1095 ) + + + def fast_suite(): suite = unittest.TestSuite() suite.addTest( SumTest( 'test_load' )) @@ -191,6 +245,7 @@ def fast_suite(): suite.addTest( SumTest( 'test_fwrite' )) suite.addTest( SumTest( 'test_block' )) suite.addTest( SumTest( 'test_restart' )) + suite.addTest( SumTest( 'test_var_properties' )) return suite diff --git a/ThirdParty/Ert/devel/python/test/test-data/local/config/simple_config b/ThirdParty/Ert/devel/python/test/test-data/local/config/simple_config new file mode 100644 index 0000000000..413fd38a8f --- /dev/null +++ b/ThirdParty/Ert/devel/python/test/test-data/local/config/simple_config @@ -0,0 +1,226 @@ +QUEUE_OPTION LSF LSF_LOGIN_SHELL /bin/csh + +DEFINE __NAME__ EXAMPLE_01_BASE +DEFINE __INCLUDE_PATH__ /private/joaho/ERT/git/ert/Gurbat +DEFINE __GRID__ __NAME__.EGRID +DEFINE MULTIR_FILE MULTIR.INC + +JOB_SCRIPT /private/joaho/ERT/Statoil/etc/ERT/Scripts/job_dispatch.py + + +-- The ECLIPSE data files which are used as init. + +GRID __GRID__ +SCHEDULE_FILE target.SCH + + +--SCHEDULE_PREDICTION_FILE prediction.sch + +INSTALL_JOB RMS_BATCH /private/joaho/ERT/Statoil/etc/ERT/Config/jobs/resmod/RMS_BATCH_TEST +INSTALL_JOB ECLIPSE_TEST ECLIPSE_TEST +INSTALL_JOB AVGP jobs/AVGP +--INSTALL_JOB RMS_TEST /private/joaho/ERT/Statoil/etc/ERT/Config/jobs/resmod/RMS_BATCH +SETENV MANY_PATH $PATH:$LD_LIBRARY_PATH:$MANPATH:/lib + + +--SCHEDULE_PREDICTION_FILE prediction2.schi + +DATA_FILE Example_01_base.data + + +INIT_SECTION __INCLUDE_PATH__/EQUIL.INC +LICENSE_PATH /tmp/BJARNE_PATH + +--SETENV ERT_LINK_LSF True +--LSF_SERVER be-grid01 + +--CASE_TABLE CaseNames + + +--PRE_CLEAR_RUNPATH TRUE + +-- Where do you want to store things + + +RUNPATH /scratch/ert/joaho/Run1/Xrun%d +RERUN_PATH /scratch/ert/joaho/Rerun/Xrun%d + + + + + +ENSPATH /tmp/Gurbat/104BlockFS +ECLBASE ECL_%04d + +QC_PATH /tmp/QC + +-- How to simulate + + +INSTALL_JOB PVT jobs/PVT +INSTALL_JOB NULL jobs/NULL + +INSTALL_JOB RMS_TEST /private/joaho/ERT/Statoil/etc/ERT/Config/jobs/resmod/RUN_RMS_20XX +INSTALL_JOB PRESSURE33 jobs/Pressure33 + +--FORWARD_MODEL RMS_BATCH(=2012.0.1, =/rms/rms_project_2012 , =MAIN_WORKFLOW) +FORWARD_MODEL ECLIPSE100_2009.1 +--FORWARD_MODEL PRESSURE33 +--FORWARD_MODEL RMS_TEST( = , = , = 2011.0.2, =/rms/rms_project_2012 , =/d/proj/bg/ior_fsenter/GRM_TDP/Gimle/work/tfen/r0004/models/eclipse/refcase/, =Forward_Seismic,=SEISMIC_FORWARD_TARGET.INC) + +--FORWARD_MODEL AVGP +--FORWARD_MODEL NULL + + +UMASK 0 +MAX_SUBMIT 10 +MAX_RESAMPLE 1 + + +ADD_FIXED_LENGTH_SCHEDULE_KW Jalla 7 +ADD_FIXED_LENGTH_SCHEDULE_KW Jalla2 70 + + + +DBASE_TYPE BLOCK_FS + +-- The ensemble +NUM_REALIZATIONS 25 + +IMAGE_TYPE png +PLOT_DRIVER PLPLOT + +RUN_TEMPLATE Template1 File1 File:1 +RUN_TEMPLATE Template1 File2 File:2 + + +INSTALL_JOB PRESSURE100 PRESSURE100 + + +GEN_KW MULTFLT FAULT_TEMPLATE MULTFLT.INC Config/MULTFLT.txt +GEN_KW GRID_PARAMS GRID_PARAM_TEMPLATE GRID_PARAMS.INC Config/GRID_PARAMS.txt --MIN_STD:Config/GRID_PARAMS.min_std +GEN_KW FLUID_PARAMS FLUID_PARAM_TEMPLATE FLUID_PARAMS.INC Config/FLUID_PARAMS.txt --MIN_STD:Config/FLUID_PARAMS.min_std + +GEN_PARAM GP GP.txt INIT_FILES:GP/GP.txt INPUT_FORMAT:ASCII OUTPUT_FORMAT:ASCII + + + + +UPDATE_RESULTS TRUE +ENKF_RERUN FALSE +RERUN_START 0 + +INSTALL_JOB SGOF_TAB jobs/SGOF_TAB + + + +ENKF_MERGE_OBSERVATIONS TRUE +--ENKF_SCHED_FILE sched_config + + +--ADD_STATIC_KW __ALL__ +ADD_STATIC_KW BJARNE KW2 + +ENKF_ALPHA 1.50 +----------------------------------------------------------------- +IMAGE_VIEWER /tmp/echo.sh +IMAGE_VIEWER /usr/bin/display + + +QUEUE_SYSTEM LSF +QUEUE_SYSTEM LOCAL +QUEUE_SYSTEM RSH + +MAX_RUNNING_LOCAL 3 +MAX_RUNNING_LSF 100 +MAX_RUNNING_RSH 6 +--LSF_QUEUE SUPERKO + +RSH_HOST be-lx655082:2 be-lx633214:2 + + + +LOG_LEVEL 3 +LOG_FILE /tmp/log/log.txt +UPDATE_LOG_PATH /tmp/UP + +KEEP_RUNPATH 0 - 9 +DATA_KW __INCLUDE_PATH__ +DATA_KW WhatEver SomeThing + + + + +-- Quantities to estimate on + +HISTORY_SOURCE REFCASE_HISTORY +REFCASE __NAME__.DATA + + +STORE_SEED RandomSeed +LOAD_SEED RandomSeed + + +--EQUIL EQUIL EQUIL.INC equil_config + +RUN_TEMPLATE GEN_DATA_TEMPLATE GEN_DATA_FILE +--GEN_DATA PRESSURE100 INPUT_FORMAT:ASCII RESULT_FILE:PRESSURE%04d + + + +--ANALYSIS_LOAD RML_ENKF /project/res/x86_64_RH_5/lib/rml_enkf.so +--ANALYSIS_LOAD RML_ENKF rml_enkf.so +ANALYSIS_LOAD RML_ENKF /private/joaho/ERT/NR/libanalysis/src/rml_enkf.so + +--ANALYSIS_LOAD FWD_ENKF /private/joaho/ERT/NR/tmp-build/libanalysis/src/sqrt_enkf.so +--ANALYSIS_LOAD SFWD_ENKF /private/joaho/ERT/NR/tmp-build/libanalysis/src/std_enkf.so +ANALYSIS_SET_VAR STD_ENKF ENKF_TRUNCATION 0.95 +--ANALYSIS_SET_VAR SQRT_ENKF ENKF_TRUNCATION 0.99 +ANALYSIS_SET_VAR STD_ENKF ENKF_NCOMP 2 +ANALYSIS_SET_VAR STD_ENKF ENKF_TRUNCATION 0.98 +ANALYSIS_SELECT STD_ENKF + +ANALYSIS_LOAD TEST_ENKF /private/joaho/ERT/NR/libanalysis/src/test_enkf.so + + +QUEUE_OPTION LSF LSF_LOGIN_SHELL /bin/csh + + +FIELD PRESSURE DYNAMIC +FIELD SWAT DYNAMIC MIN:0 MAX:1 +FIELD SGAS DYNAMIC MIN:0 MAX:1 +FIELD RS DYNAMIC MIN:0 +FIELD RV DYNAMIC MIN:0.0034 + +--CONTAINER CXX PRESSURE SWAT + + +--SURFACE TOP OUTPUT_FILE:surf.irap INIT_FILES:Surfaces/d_BCU_%d.irap BASE_SURFACE:Surfaces/d_BCU_0.irap + +-- Observations +OBS_CONFIG observations + + +--SUMMARY F* RPR:* + +PLOT_PATH plots + + +IMAGE_VIEWER /tmp/noplot.sh + +REPORT_SEARCH_PATH /private/joaho/ERT/Statoil/etc/ERT/reports + +REPORT_WELL_LIST OP_1 OP_2 OP_3 +REPORT_WELL_LIST OP_4 OP_5 + +REPORT_LIST well_opt_report.tex + +REPORT_PATH Reports + + +----------------------------------------------------------------- + + + +WORKFLOW_JOB_DIRECTORY WorkflowJobs +LOAD_WORKFLOW Workflows/PLOT_AND_EXIT diff --git a/ThirdParty/Ert/devel/python/test/test_all.py b/ThirdParty/Ert/devel/python/test/test_all.py index 8f9c310294..e1f21e2322 100644 --- a/ThirdParty/Ert/devel/python/test/test_all.py +++ b/ThirdParty/Ert/devel/python/test/test_all.py @@ -14,7 +14,9 @@ import region_test import latex_test import fortio_test import restart_test +import config_test import stringlist_test +import tvector_test def run_suite(name , suite): print "Running tests from %12s:" % name, @@ -29,7 +31,7 @@ def run(name , module): if hasattr(module , "slow_suite"): run_suite( name , getattr(module , "slow_suite")()) - +run("config" , config_test) run("restart" , restart_test) run("kw" , kw_test) run("summary" , sum_test) @@ -43,3 +45,4 @@ run("region" , region_test) run("latex" , latex_test) run("fortio" , fortio_test) run("stringlist" , stringlist_test) +run("tvector" , tvector_test) diff --git a/ThirdParty/Ert/devel/python/test/tvector_test.py b/ThirdParty/Ert/devel/python/test/tvector_test.py new file mode 100644 index 0000000000..f3b5c4b70c --- /dev/null +++ b/ThirdParty/Ert/devel/python/test/tvector_test.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# Copyright (C) 2011 Statoil ASA, Norway. +# +# The file 'tvector_test.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT 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. +# +# ERT 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. + + +import os +import datetime +import unittest +import ert +from ert.util.tvector import DoubleVector +from ert.util.tvector import IntVector +from ert.util.tvector import BoolVector + +from test_util import approx_equal, approx_equalv + + + +class TVectorTest( unittest.TestCase ): + + + def setUp(self): + pass + + + def test_activeList(self): + active_list = IntVector.active_list("1,10,100-105") + self.assertTrue( len(active_list) == 8 ) + self.assertTrue( active_list[0] == 1) + self.assertTrue( active_list[2] == 100) + self.assertTrue( active_list[7] == 105) + + active_list = IntVector.active_list("1,10,100-105X") + self.assertFalse( active_list ) + + + + def test_activeMask(self): + active_list = BoolVector.active_mask("1 , 4 - 7 , 10") + self.assertTrue( len(active_list) == 11 ) + self.assertTrue( active_list[1]) + self.assertTrue( active_list[4]) + self.assertTrue( active_list[10]) + self.assertFalse( active_list[9]) + self.assertFalse( active_list[8]) + + active_list = BoolVector.active_mask("1,4-7,10X") + self.assertFalse( active_list ) + + + + def test_true(self): + l = IntVector() + self.assertFalse( l ) # Will invoke the __len__ function; could override with __nonzero__ + l[0] = 1 + self.assertTrue( l ) + + + +def fast_suite(): + suite = unittest.TestSuite() + suite.addTest( TVectorTest( 'test_activeList' )) + suite.addTest( TVectorTest( 'test_activeMask' )) + suite.addTest( TVectorTest( 'test_true' )) + return suite + + +if __name__ == "__main__": + unittest.TextTestRunner().run( fast_suite() ) + + diff --git a/ThirdParty/Ert/devel/redhat/ert.ecl.spec b/ThirdParty/Ert/devel/redhat/ert.ecl.spec index cd206bfbf9..64f138af60 100644 --- a/ThirdParty/Ert/devel/redhat/ert.ecl.spec +++ b/ThirdParty/Ert/devel/redhat/ert.ecl.spec @@ -4,7 +4,7 @@ Name: ert.ecl Version: 1.0 -Release: 0 +Release: 1 Summary: ERT - Ensemble based Reservoir Tool - ECL library License: GPL-3+ Group: Development/Libraries/C and C++ @@ -38,6 +38,7 @@ Group: Development/Libraries/C and C++ Requires: %{name} = %{version} Requires: lapack-devel Requires: libert.ecl1 = %{version} +BuildArch: noarch %description devel This package contains the development and header files for ert.ecl @@ -47,7 +48,7 @@ This package contains the development and header files for ert.ecl %build cd devel -cmake28 -DSHARED_LIB=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%{_prefix} +cmake28 -DSHARED_LIB=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%{_prefix} -DBUILD_ECL_SUMMARY=1 make %install @@ -67,8 +68,13 @@ rm -rf %{buildroot} %files -n libert.ecl1 %defattr(-,root,root,-) %{_libdir}/*.so.* +%{_bindir}/* %files devel %defattr(-,root,root,-) %{_libdir}/*.so %{_includedir}/* + +%changelog +* Tue Feb 19 2013 Arne Morten Kvarving 1.0-1 +- Mark -devel package as architecture independent diff --git a/VisualizationModules/LibCore/CMakeLists.txt b/VisualizationModules/LibCore/CMakeLists.txt index 6acce2eec9..f3c0ab4c6e 100644 --- a/VisualizationModules/LibCore/CMakeLists.txt +++ b/VisualizationModules/LibCore/CMakeLists.txt @@ -14,6 +14,7 @@ cvfAssert.h cvfBase.h cvfBase64.h cvfCharArray.h +cvfCodeLocation.h cvfCollection.h cvfCollection.inl cvfColor3.h @@ -24,6 +25,11 @@ cvfFlags.h cvfFlags.inl cvfFunctorRange.h cvfLibCore.h +cvfLogDestination.h +cvfLogDestinationConsole.h +cvfLogDestinationFile.h +cvfLogEvent.h +cvfLogManager.h cvfLogger.h cvfMath.h cvfMath.inl @@ -31,6 +37,7 @@ cvfMatrix3.h cvfMatrix3.inl cvfMatrix4.h cvfMatrix4.inl +cvfMutex.h cvfObject.h cvfObject.inl cvfPlane.h @@ -60,11 +67,17 @@ set(CEE_SOURCE_FILES cvfAssert.cpp cvfBase64.cpp cvfCharArray.cpp +cvfCodeLocation.cpp cvfColor3.cpp cvfColor4.cpp cvfDebugTimer.cpp +cvfLogDestinationConsole.cpp +cvfLogDestinationFile.cpp +cvfLogEvent.cpp +cvfLogManager.cpp cvfLogger.cpp cvfMath.cpp +cvfMutex.cpp cvfObject.cpp cvfPlane.cpp cvfPropertySet.cpp diff --git a/VisualizationModules/LibCore/cvfCodeLocation.cpp b/VisualizationModules/LibCore/cvfCodeLocation.cpp new file mode 100644 index 0000000000..4716136be2 --- /dev/null +++ b/VisualizationModules/LibCore/cvfCodeLocation.cpp @@ -0,0 +1,163 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfBase.h" +#include "cvfCodeLocation.h" + +#include +#include + +namespace cvf { + + +//================================================================================================== +/// +/// \class cvf::CodeLocation +/// \ingroup Core +/// +/// Represents a source code location. +/// +/// Typically used with logging, asserts etc. Typically initialized using built-in compiler macros +/// such as __FILE__ and __LINE__. +/// +/// Note that the strings parameters for file name and function must be a static strings with a +/// lifetime that's longer than the lifetime of the CodeLocation object +/// +//================================================================================================== + +static const char* const EMPTY_STRING = ""; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CodeLocation::CodeLocation() +: m_fileName(EMPTY_STRING), + m_functionName(EMPTY_STRING), + m_lineNumber(-1) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CodeLocation::CodeLocation(const char* fileName, const char* functionName, int lineNumber) +: m_fileName(fileName), + m_functionName(functionName), + m_lineNumber(lineNumber) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CodeLocation::CodeLocation(const CodeLocation& other) +: m_fileName(other.m_fileName), + m_functionName(other.m_functionName), + m_lineNumber(other.m_lineNumber) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const CodeLocation& CodeLocation::operator=(CodeLocation rhs) +{ + // Copy-and-swap (copy already done since parameter is passed by value) + rhs.swap(*this); + + return *this; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const char* CodeLocation::fileName() const +{ + return m_fileName ? m_fileName : EMPTY_STRING; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const char* CodeLocation::shortFileName() const +{ + if (m_fileName) + { + const char* ptrToLastSlash = strrchr(m_fileName, '/'); + +#ifdef WIN32 + const char* ptrToLastBwdSlash = strrchr(m_fileName, '\\'); + if (ptrToLastBwdSlash > ptrToLastSlash) + { + ptrToLastSlash = ptrToLastBwdSlash; + } +#endif + + if (ptrToLastSlash) + { + return ptrToLastSlash + 1; + } + else + { + return m_fileName; + } + } + else + { + return EMPTY_STRING; + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const char* CodeLocation::functionName() const +{ + return m_functionName ? m_functionName : EMPTY_STRING; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int CodeLocation::lineNumber() const +{ + return m_lineNumber; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CodeLocation::swap(CodeLocation& other) +{ + std::swap(m_fileName, other.m_fileName); + std::swap(m_functionName, other.m_functionName); + std::swap(m_lineNumber, other.m_lineNumber); +} + + +} // namespace cvf + diff --git a/VisualizationModules/LibCore/cvfCodeLocation.h b/VisualizationModules/LibCore/cvfCodeLocation.h new file mode 100644 index 0000000000..c8f5722a72 --- /dev/null +++ b/VisualizationModules/LibCore/cvfCodeLocation.h @@ -0,0 +1,65 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 + +namespace cvf { + + +//================================================================================================== +// +// +// +//================================================================================================== +class CodeLocation +{ +public: + CodeLocation(); + CodeLocation(const char* fileName, const char* functionName, int lineNumber); + CodeLocation(const CodeLocation& other); + + const CodeLocation& operator=(CodeLocation rhs); + + const char* fileName() const; + const char* shortFileName() const; + const char* functionName() const; + int lineNumber() const; + void swap(CodeLocation& other); + +private: + const char* m_fileName; + const char* m_functionName; + int m_lineNumber; +}; + + +#if defined(_MSC_VER) +#define CVF_CODELOC_FUNCNAME __FUNCSIG__ +#elif defined(__GNUC__) +#define CVF_CODELOC_FUNCNAME __PRETTY_FUNCTION__ +#else +#define CVF_CODELOC_FUNCNAME "" +#endif + +#define CVF_CODE_LOCATION ::cvf::CodeLocation(__FILE__, CVF_CODELOC_FUNCNAME, __LINE__) + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfLogDestination.h b/VisualizationModules/LibCore/cvfLogDestination.h new file mode 100644 index 0000000000..9fa8e12ae0 --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogDestination.h @@ -0,0 +1,44 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfObject.h" + +namespace cvf { + +class LogEvent; + + +//================================================================================================== +// +// Interface for log destinations +// +//================================================================================================== +class LogDestination : public Object +{ +public: + virtual void log(const LogEvent& logEvent) = 0; +}; + + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfLogDestinationConsole.cpp b/VisualizationModules/LibCore/cvfLogDestinationConsole.cpp new file mode 100644 index 0000000000..3ec37d5d57 --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogDestinationConsole.cpp @@ -0,0 +1,141 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfBase.h" +#include "cvfLogDestinationConsole.h" +#include "cvfLogEvent.h" + +#ifdef WIN32 +#pragma warning (push) +#pragma warning (disable: 4668) +#include +#pragma warning (pop) +#else +#include +#include +#endif + +namespace cvf { + + + +//================================================================================================== +/// +/// \class cvf::LogDestinationConsole +/// \ingroup Core +/// +/// +/// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogDestinationConsole::log(const LogEvent& logEvent) +{ + String str; + bool addLocationInfo = false; + + Logger::Level logEventLevel = logEvent.level(); + if (logEventLevel == Logger::LL_ERROR) + { + str = "ERROR: " + logEvent.message(); + addLocationInfo = true; + } + else if (logEventLevel == Logger::LL_WARNING) + { + str = "warn: " + logEvent.message(); + } + else if (logEventLevel == Logger::LL_INFO) + { + str = "info: " + logEvent.message(); + } + else if (logEventLevel == Logger::LL_DEBUG) + { + str = "debug: " + logEvent.message(); + } + + if (addLocationInfo) + { + str += "\n"; + str += String(" -func: %1\n").arg(logEvent.location().functionName()); + str += String(" -file: %1(%2)").arg(logEvent.location().shortFileName()).arg(logEvent.location().lineNumber()); + } + + CharArray charArrMsg = str.toAscii(); + const char* szMsg = charArrMsg.ptr(); + + { + Mutex::ScopedLock lock(m_mutex); + +#ifdef WIN32 + writeToWindowsConsole(szMsg, true); +#else + writeToStderr(szMsg, true); +#endif + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogDestinationConsole::writeToWindowsConsole(const char* theString, bool addNewLine) +{ +#ifdef WIN32 + CVF_ASSERT(theString); + + AllocConsole(); + + HANDLE hStdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); + if (hStdOutputHandle && theString) + { + DWORD stringLength = static_cast(System::strlen(theString)); + + unsigned long iDum = 0; + WriteConsoleA(hStdOutputHandle, theString, stringLength, &iDum, NULL); + if (addNewLine) WriteConsole(hStdOutputHandle, "\n", 1, &iDum, NULL); + } +#else + CVF_UNUSED(theString); + CVF_UNUSED(addNewLine); +#endif +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogDestinationConsole::writeToStderr(const char* theString, bool addNewLine) +{ + CVF_ASSERT(theString); + + if (theString) + { + fprintf(stderr, "%s", theString); + if (addNewLine) + { + fprintf(stderr, "\n"); + } + } +} + + +} // namespace cvf + diff --git a/VisualizationModules/LibCore/cvfLogDestinationConsole.h b/VisualizationModules/LibCore/cvfLogDestinationConsole.h new file mode 100644 index 0000000000..87f3bdd00a --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogDestinationConsole.h @@ -0,0 +1,49 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfLogDestination.h" +#include "cvfMutex.h" + +namespace cvf { + + +//================================================================================================== +// +// +// +//================================================================================================== +class LogDestinationConsole : public LogDestination +{ +public: + virtual void log(const LogEvent& logEvent); + +private: + static void writeToWindowsConsole(const char* theString, bool addNewLine); + static void writeToStderr(const char* theString, bool addNewLine); + +private: + Mutex m_mutex; +}; + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfLogDestinationFile.cpp b/VisualizationModules/LibCore/cvfLogDestinationFile.cpp new file mode 100644 index 0000000000..67c65a1bcd --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogDestinationFile.cpp @@ -0,0 +1,169 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfBase.h" +#include "cvfLogDestinationFile.h" +#include "cvfLogEvent.h" + +#ifdef WIN32 +#pragma warning (push) +#pragma warning (disable: 4668) +#include +#pragma warning (pop) +#else +#include +#include +#endif + +namespace cvf { + +class FileWrapper +{ +public: + FileWrapper(const String& fileName) + : m_fileName(fileName), + m_filePtr(NULL) + { + } + + ~FileWrapper() + { + if (m_filePtr) + { + fclose(m_filePtr); + } + } + + bool open(const String& mode) + { + CVF_ASSERT(m_filePtr == NULL); + +#ifdef WIN32 + if (_wfopen_s(&m_filePtr, m_fileName.c_str(), mode.c_str()) != 0) + { + m_filePtr = NULL; + } +#else + m_filePtr = ::fopen(m_fileName.toUtf8().ptr(), mode.toUtf8().ptr()); +#endif + + return m_filePtr != NULL; + } + + FILE* filePtr() + { + return m_filePtr; + } + +private: + String m_fileName; + FILE* m_filePtr; +}; + + +//================================================================================================== +/// +/// \class cvf::LogDestinationFile +/// \ingroup Core +/// +/// +/// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogDestinationFile::log(const LogEvent& logEvent) +{ + String str; + bool addLocationInfo = false; + + Logger::Level logEventLevel = logEvent.level(); + if (logEventLevel == Logger::LL_ERROR) + { + str = "ERROR: " + logEvent.message(); + addLocationInfo = true; + } + else if (logEventLevel == Logger::LL_WARNING) + { + str = "warn: " + logEvent.message(); + } + else if (logEventLevel == Logger::LL_INFO) + { + str = "info: " + logEvent.message(); + } + else if (logEventLevel == Logger::LL_DEBUG) + { + str = "debug: " + logEvent.message(); + } + + if (addLocationInfo) + { + str += "\n"; + str += String(" -func: %1\n").arg(logEvent.location().functionName()); + str += String(" -file: %1(%2)").arg(logEvent.location().shortFileName()).arg(logEvent.location().lineNumber()); + } + + CharArray charArrMsg = str.toAscii(); + const char* szMsg = charArrMsg.ptr(); + + Mutex::ScopedLock lock(m_mutex); + writeToFile(szMsg, true); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogDestinationFile::writeToFile(const char* theString, bool addNewLine) +{ + FileWrapper file(m_fileName); + if (m_firstTimeOpen) + { + if (!file.open("wt")) + { + return; + } + + m_firstTimeOpen = false; + } + else + { + if (!file.open("at")) + { + return; + } + } + + if (file.filePtr() && theString) + { + if (addNewLine) + { + fprintf(file.filePtr(), "%s\n", theString); + } + else + { + fprintf(file.filePtr(), "%s", theString); + } + } +} + + +} // namespace cvf + diff --git a/VisualizationModules/LibCore/cvfLogDestinationFile.h b/VisualizationModules/LibCore/cvfLogDestinationFile.h new file mode 100644 index 0000000000..a01ddc344b --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogDestinationFile.h @@ -0,0 +1,53 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfLogDestination.h" +#include "cvfString.h" +#include "cvfMutex.h" + +namespace cvf { + + +//================================================================================================== +// +// +// +//================================================================================================== +class LogDestinationFile : public LogDestination +{ +public: + LogDestinationFile(const String& fileName); + + virtual void log(const LogEvent& logEvent); + +private: + void writeToFile(const char* theString, bool addNewLine); + +private: + String m_fileName; + bool m_firstTimeOpen; // Initialized to true, Will be set to false after first write operation + Mutex m_mutex; +}; + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfLogEvent.cpp b/VisualizationModules/LibCore/cvfLogEvent.cpp new file mode 100644 index 0000000000..7d08ffe386 --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogEvent.cpp @@ -0,0 +1,128 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfBase.h" +#include "cvfLogEvent.h" + +namespace cvf { + + +//================================================================================================== +/// +/// \class cvf::LogEvent +/// \ingroup Core +/// +/// +/// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LogEvent::LogEvent() +: m_level(Logger::LL_ERROR) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LogEvent::LogEvent(const String& source, const String& message, Logger::Level level, const CodeLocation& codeLocation) +: m_source(source), + m_message(message), + m_level(level), + m_codeLocation(codeLocation) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LogEvent::LogEvent(const LogEvent& other) +: m_source(other.m_source), + m_message(other.m_message), + m_level(other.m_level), + m_codeLocation(other.m_codeLocation) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const LogEvent& LogEvent::operator=(LogEvent rhs) +{ + // Copy-and-swap (copy already done since parameter is passed by value) + rhs.swap(*this); + + return *this; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const String& LogEvent::source() const +{ + return m_source; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Logger::Level LogEvent::level() const +{ + return m_level; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const String& LogEvent::message() const +{ + return m_message; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const CodeLocation& LogEvent::location() const +{ + return m_codeLocation; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogEvent::swap(LogEvent& other) +{ + m_source.swap(other.m_source); + m_message.swap(other.m_message); + std::swap(m_level, other.m_level); + m_codeLocation.swap(other.m_codeLocation); +} + +} // namespace cvf + diff --git a/VisualizationModules/LibCore/cvfLogEvent.h b/VisualizationModules/LibCore/cvfLogEvent.h new file mode 100644 index 0000000000..25c5c6592e --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogEvent.h @@ -0,0 +1,62 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfObject.h" +#include "cvfString.h" +#include "cvfLogger.h" + +namespace cvf { + + +//================================================================================================== +// +// +// +//================================================================================================== +class LogEvent +{ +public: + LogEvent(); + LogEvent(const String& source, const String& message, Logger::Level level, const CodeLocation& codeLocation); + LogEvent(const LogEvent& other); + + const LogEvent& operator=(LogEvent rhs); + + const String& source() const; + Logger::Level level() const; + const String& message() const; + const CodeLocation& location() const; + +private: + void swap(LogEvent& other); + +private: + String m_source; + String m_message; + Logger::Level m_level; + CodeLocation m_codeLocation; +}; + + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfLogManager.cpp b/VisualizationModules/LibCore/cvfLogManager.cpp new file mode 100644 index 0000000000..1facf09548 --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogManager.cpp @@ -0,0 +1,236 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfBase.h" +#include "cvfLogManager.h" +#include "cvfLogger.h" +#include "cvfLogDestinationConsole.h" + +namespace cvf { + + + +//================================================================================================== +/// +/// \class cvf::LogManager +/// \ingroup Core +/// +/// +/// +//================================================================================================== + +cvf::ref LogManager::sm_logManagerInstance; +Mutex LogManager::sm_instanceMutex; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LogManager::LogManager() +{ + // Create the root logger + ref rootLogger = new Logger("", Logger::LL_WARNING, new LogDestinationConsole); + m_loggerMap[""] = rootLogger; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LogManager::~LogManager() +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LogManager* LogManager::instance() +{ + Mutex::ScopedLock mutexLock(sm_instanceMutex); + + if (sm_logManagerInstance.isNull()) + { + sm_logManagerInstance = new LogManager; + } + + return sm_logManagerInstance.p(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogManager::setInstance(LogManager* logManagerInstance) +{ + Mutex::ScopedLock mutexLock(sm_instanceMutex); + + sm_logManagerInstance = logManagerInstance; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogManager::shutdownInstance() +{ + Mutex::ScopedLock mutexLock(sm_instanceMutex); + + sm_logManagerInstance = NULL; +} + + +//-------------------------------------------------------------------------------------------------- +/// Returns logger with the specified name +/// +/// Will create the logger if it doesn't already exist. In this case, the newly created logger will +/// be initialized with the same logging level and appender as its parent. +//-------------------------------------------------------------------------------------------------- +Logger* LogManager::logger(const String& loggerName) +{ + Mutex::ScopedLock mutexLock(m_mutex); + + ref theLogger = find(loggerName); + if (theLogger.isNull()) + { + // Must create a new logger + // Try and find parent (optionally we'll use the root logger) and use its settings to initialize level and appender + String parentLoggerName = LogManager::nameOfParentLogger(loggerName); + ref parentLogger = find(parentLoggerName); + if (parentLogger.isNull()) + { + parentLogger = rootLogger(); + } + + CVF_ASSERT(parentLogger.notNull()); + + theLogger = new Logger(loggerName, parentLogger->level(), parentLogger->destination()); + m_loggerMap[loggerName] = theLogger; + } + + return theLogger.p(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Logger* LogManager::rootLogger() +{ + return logger(String()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogManager::setLevelRecursive(const String& baseLoggerName, int logLevel) +{ + Mutex::ScopedLock mutexLock(m_mutex); + + const size_t baseNameLength = baseLoggerName.size(); + const bool baseNameIsRoot = (baseNameLength == 0); + + for (LoggerMap_T::iterator it = m_loggerMap.begin(); it != m_loggerMap.end(); ++it) + { + Logger* logger = it->second.p(); + if (baseNameIsRoot) + { + logger->setLevel(logLevel); + } + else + { + const String& loggerName = logger->name(); + if (loggerName.startsWith(baseLoggerName) && + ((loggerName.size() == baseNameLength) || (loggerName[baseNameLength] == '.')) ) + { + logger->setLevel(logLevel); + } + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogManager::setDestinationRecursive(const String& baseLoggerName, LogDestination* logDestination) +{ + Mutex::ScopedLock mutexLock(m_mutex); + + const size_t baseNameLength = baseLoggerName.size(); + const bool baseNameIsRoot = (baseNameLength == 0); + + for (LoggerMap_T::iterator it = m_loggerMap.begin(); it != m_loggerMap.end(); ++it) + { + Logger* logger = it->second.p(); + if (baseNameIsRoot) + { + logger->setDestination(logDestination); + } + else + { + const String& loggerName = logger->name(); + if (loggerName.startsWith(baseLoggerName) && + ((loggerName.size() == baseNameLength) || (loggerName[baseNameLength] == '.')) ) + { + logger->setDestination(logDestination); + } + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Logger* LogManager::find(const String& loggerName) +{ + LoggerMap_T::iterator it = m_loggerMap.find(loggerName); + if (it != m_loggerMap.end()) + { + return it->second.p(); + } + else + { + return NULL; + } +} + + +//-------------------------------------------------------------------------------------------------- +/// Determine name of the parent logger of \a childLoggerName +//-------------------------------------------------------------------------------------------------- +String LogManager::nameOfParentLogger(const String& childLoggerName) +{ + std::wstring childName = childLoggerName.toStdWString(); + std::wstring::size_type pos = childName.rfind('.'); + if (pos != std::wstring::npos) + { + std::wstring parentName = childName.substr(0, pos); + return parentName; + } + else + { + return String(); + } +} + + +} // namespace cvf + diff --git a/VisualizationModules/LibCore/cvfLogManager.h b/VisualizationModules/LibCore/cvfLogManager.h new file mode 100644 index 0000000000..b3dde9e597 --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogManager.h @@ -0,0 +1,74 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfObject.h" +#include "cvfString.h" +#include "cvfMutex.h" + +#include + +namespace cvf { + +class Logger; +class LogDestination; + + + +//================================================================================================== +// +// +// +//================================================================================================== +class LogManager : public Object +{ +public: + LogManager(); + ~LogManager(); + + static LogManager* instance(); + static void setInstance(LogManager* logManagerInstance); + static void shutdownInstance(); + + Logger* logger(const String& loggerName); + Logger* rootLogger(); + + void setLevelRecursive(const String& baseLoggerName, int logLevel); + void setDestinationRecursive(const String& baseLoggerName, LogDestination* logDestination); + +private: + Logger* find(const String& loggerName); + static String nameOfParentLogger(const String& childLoggerName); + +private: + typedef std::map > LoggerMap_T; + LoggerMap_T m_loggerMap; + Mutex m_mutex; + static cvf::ref sm_logManagerInstance; + static Mutex sm_instanceMutex; + + CVF_DISABLE_COPY_AND_ASSIGN(LogManager); +}; + + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfLogger.cpp b/VisualizationModules/LibCore/cvfLogger.cpp index ad5ca091c3..d44feb8d65 100644 --- a/VisualizationModules/LibCore/cvfLogger.cpp +++ b/VisualizationModules/LibCore/cvfLogger.cpp @@ -19,7 +19,8 @@ #include "cvfBase.h" #include "cvfLogger.h" -#include "cvfTrace.h" +#include "cvfLogEvent.h" +#include "cvfLogDestination.h" namespace cvf { @@ -31,17 +32,20 @@ namespace cvf { /// \ingroup Core /// /// Logger class -/// -/// Currently, output is written using Trace, and special formatting of the string makes it possible -/// to navigate to source code using F4 in Visual Studio. See http://msdn.microsoft.com/en-us/library/yxkt8b26.aspx /// +/// Note that in itself, the Logger is not thread safe. This means that logger configuration, such +/// as setting the logging level and specifying the log destination, must be done in a single +/// threaded environment. +/// //================================================================================================== //-------------------------------------------------------------------------------------------------- /// Constructor //-------------------------------------------------------------------------------------------------- -Logger::Logger() -: m_debugLogging(false) +Logger::Logger(const String& loggerName, int logLevel, LogDestination* logDestination) +: m_name(loggerName), + m_logLevel(logLevel), + m_destination(logDestination) { } @@ -51,62 +55,145 @@ Logger::Logger() //-------------------------------------------------------------------------------------------------- Logger::~Logger() { - } //-------------------------------------------------------------------------------------------------- -/// Use file and line to create a specially formatted string for Visual Studio. /// -/// \param message The actual error message -/// \param fileName Use system macro __FILE__ for source code file name -/// \param line Use system macro __LINE__ for source code line number +//-------------------------------------------------------------------------------------------------- +const String& Logger::name() const +{ + return m_name; +} + + +//-------------------------------------------------------------------------------------------------- +/// Set the logging level of this logger /// -/// __FILE__ and __LINE__ are used to create the variables used to navigate to the line in the -/// source code file the error message was logged at. +/// Set a level of 0 to disable all logging for this logger. //-------------------------------------------------------------------------------------------------- -void Logger::error(const String& message, const char* fileName, int lineNumber) +void Logger::setLevel(int logLevel) { - String tmp; - tmp = String(fileName) + "(" + String(lineNumber) + "): error: " + message; - - Trace::show(tmp); + m_logLevel = logLevel; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void Logger::enableDebug(bool enableDebugLogging) +int Logger::level() const { - m_debugLogging = enableDebugLogging; + return m_logLevel; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool Logger::isDebugEnabled() const +LogDestination* Logger::destination() { - return m_debugLogging; + return m_destination.p(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void Logger::debug(const String& message, const char* /*fileName*/, int /*lineNumber*/) +void Logger::setDestination(LogDestination* logDestination) { - if (m_debugLogging) + m_destination = logDestination; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::error(const String& message) +{ + error(message, CodeLocation()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::error(const String& message, const CodeLocation& location) +{ + if (m_logLevel >= LL_ERROR && m_destination.notNull()) { - // For now, don't report file and line - String tmp; - tmp = "debug: " + message; - - Trace::show(tmp); + log(message, LL_ERROR, location); } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::warning(const String& message) +{ + warning(message, CodeLocation()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::warning(const String& message, const CodeLocation& location) +{ + if (m_logLevel >= LL_WARNING && m_destination.notNull()) + { + log(message, LL_WARNING, location); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::info(const String& message) +{ + info(message, CodeLocation()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::info(const String& message, const CodeLocation& location) +{ + if (m_logLevel >= LL_INFO && m_destination.notNull()) + { + log(message, LL_INFO, location); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::debug(const String& message, const CodeLocation& location) +{ + if (m_logLevel >= LL_DEBUG && m_destination.notNull()) + { + log(message, LL_DEBUG, location); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::log(const String& message, Logger::Level messageLevel, const CodeLocation& location) +{ + if (m_logLevel >= messageLevel && m_destination.notNull()) + { + m_destination->log(LogEvent(m_name, message, messageLevel, location)); + } +} + + + + + } // namespace cvf diff --git a/VisualizationModules/LibCore/cvfLogger.h b/VisualizationModules/LibCore/cvfLogger.h index 8c29a9c8eb..d48e4363a6 100644 --- a/VisualizationModules/LibCore/cvfLogger.h +++ b/VisualizationModules/LibCore/cvfLogger.h @@ -21,9 +21,14 @@ #include "cvfObject.h" #include "cvfString.h" +#include "cvfCodeLocation.h" namespace cvf { - + +class LogEvent; +class LogDestination; + + //================================================================================================== // @@ -33,20 +38,57 @@ namespace cvf { class Logger : public Object { public: - Logger(); + enum Level + { + LL_ERROR = 1, + LL_WARNING, + LL_INFO, + LL_DEBUG + }; + +public: + Logger(const String& loggerName, int logLevel, LogDestination* logDestination); ~Logger(); - void error(const String& message, const char* fileName, int lineNumber); + const String& name() const; + int level() const; + void setLevel(int logLevel); + LogDestination* destination(); + void setDestination(LogDestination* logDestination); - void enableDebug(bool enableDebugLogging); - bool isDebugEnabled() const; - void debug(const String& message, const char* fileName, int lineNumber); + void error(const String& message); + void error(const String& message, const CodeLocation& location); + void warning(const String& message); + void warning(const String& message, const CodeLocation& location); + void info(const String& message); + void info(const String& message, const CodeLocation& location); + void debug(const String& message, const CodeLocation& location); + + bool isErrorEnabled() const { return m_logLevel >= LL_ERROR; } + bool isWarningEnabled() const { return m_logLevel >= LL_WARNING; } + bool isInfoEnabled() const { return m_logLevel >= LL_INFO; } + bool isDebugEnabled() const { return m_logLevel >= LL_DEBUG; } private: - bool m_debugLogging; // Whether debug messages get logged or not + void log(const String& message, Logger::Level messageLevel, const CodeLocation& location); + +private: + String m_name; // Logger name + int m_logLevel; // Logging level, all messages with a level less than or equal to this level will be logged + ref m_destination; + + CVF_DISABLE_COPY_AND_ASSIGN(Logger); }; +// Helper macros for writing log messages to a logger +#define CVF_LOG_ERROR(theLogger, theMessage) if ((theLogger)->isErrorEnabled()) { (theLogger)->error((theMessage), CVF_CODE_LOCATION); } +#define CVF_LOG_WARNING(theLogger, theMessage) if ((theLogger)->isWarningEnabled()) { (theLogger)->warning((theMessage), CVF_CODE_LOCATION); } +#define CVF_LOG_INFO(theLogger, theMessage) if ((theLogger)->isInfoEnabled()) { (theLogger)->info((theMessage), CVF_CODE_LOCATION); } +#define CVF_LOG_DEBUG(theLogger, theMessage) if ((theLogger)->isDebugEnabled()) { (theLogger)->debug((theMessage), CVF_CODE_LOCATION); } + + + } // cvf diff --git a/VisualizationModules/LibCore/cvfMutex.cpp b/VisualizationModules/LibCore/cvfMutex.cpp new file mode 100644 index 0000000000..532005c7a1 --- /dev/null +++ b/VisualizationModules/LibCore/cvfMutex.cpp @@ -0,0 +1,202 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfBase.h" +#include "cvfMutex.h" + +#ifdef WIN32 +#pragma warning (push) +#pragma warning (disable: 4668) +#include +#pragma warning (pop) +#endif + +#ifdef CVF_LINUX +#include +#endif + +namespace cvf { + + +//================================================================================================== +// +// Win32 implementation using critical section +// +//================================================================================================== +#ifdef WIN32 +class MutexImpl +{ +public: + MutexImpl() + { + ::InitializeCriticalSection(&m_critSection); + } + + ~MutexImpl() + { + ::DeleteCriticalSection(&m_critSection); + } + + void lock() + { + ::EnterCriticalSection(&m_critSection); + } + + void unlock() + { + ::LeaveCriticalSection(&m_critSection); + } + +private: + CRITICAL_SECTION m_critSection; +}; +#endif + + +//================================================================================================== +// +// Linux implementation using POSIX/Pthreads +// +//================================================================================================== +#ifdef CVF_LINUX +class MutexImpl +{ +public: + MutexImpl() + { + pthread_mutexattr_t mutexAttribs; + + int errCode = 0; + CVF_UNUSED(errCode); + errCode = pthread_mutexattr_init(&mutexAttribs); + CVF_ASSERT(errCode == 0); + + // Use a recursive mutex to be aligned with Win32 implementation + errCode = pthread_mutexattr_settype(&mutexAttribs, PTHREAD_MUTEX_RECURSIVE); + CVF_ASSERT(errCode == 0); + + errCode = pthread_mutex_init(&m_mutex, &mutexAttribs); + CVF_ASSERT(errCode == 0); + + // We're done with the attribs object + errCode = pthread_mutexattr_destroy(&mutexAttribs); + CVF_ASSERT(errCode == 0); + } + + ~MutexImpl() + { + int errCode = pthread_mutex_destroy(&m_mutex); + CVF_UNUSED(errCode); + CVF_TIGHT_ASSERT(errCode == 0); + } + + void lock() + { + int errCode = pthread_mutex_lock(&m_mutex); + CVF_UNUSED(errCode); + CVF_TIGHT_ASSERT(errCode == 0); + } + + void unlock() + { + int errCode = pthread_mutex_unlock(&m_mutex); + CVF_UNUSED(errCode); + CVF_TIGHT_ASSERT(errCode == 0); + } + +private: + pthread_mutex_t m_mutex; +}; +#endif + + + +//================================================================================================== +/// +/// \class cvf::Mutex +/// \ingroup Core +/// +/// Implements a recursive mutex where the same thread can acquire the lock multiple times. +/// +/// The mutex is implemented as an recursive mutex since on Windows platforms its implementation +/// is based critical sections. Win32 critical sections are always recursive, and therefore we also +/// make the other platform implementations recursive for consistency. +/// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Mutex::Mutex() +: m_pimpl(new MutexImpl) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Mutex::~Mutex() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Mutex::lock() +{ + m_pimpl->lock(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Mutex::unlock() +{ + m_pimpl->unlock(); +} + + +//================================================================================================== +/// +/// \class cvf::Mutex::ScopedLock +/// \ingroup Core +/// +/// +/// +//================================================================================================== +Mutex::ScopedLock::ScopedLock(Mutex& mutex) +: m_theMutex(mutex) +{ + m_theMutex.lock(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Mutex::ScopedLock::~ScopedLock() +{ + m_theMutex.unlock(); +} + + +} // namespace cvf + diff --git a/VisualizationModules/LibCore/cvfMutex.h b/VisualizationModules/LibCore/cvfMutex.h new file mode 100644 index 0000000000..5571a9717c --- /dev/null +++ b/VisualizationModules/LibCore/cvfMutex.h @@ -0,0 +1,60 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 + +namespace cvf { + + +//================================================================================================== +// +// +// +//================================================================================================== +class Mutex +{ +public: + Mutex(); + ~Mutex(); + + void lock(); + void unlock(); + + class ScopedLock + { + public: + ScopedLock(Mutex& mutex); + ~ScopedLock(); + + private: + Mutex& m_theMutex; + }; + +private: + std::auto_ptr m_pimpl; + + CVF_DISABLE_COPY_AND_ASSIGN(Mutex); +}; + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfString.cpp b/VisualizationModules/LibCore/cvfString.cpp index 9e9b6754b8..b042a5daf0 100644 --- a/VisualizationModules/LibCore/cvfString.cpp +++ b/VisualizationModules/LibCore/cvfString.cpp @@ -1063,6 +1063,15 @@ size_t String::find(const String& str, size_t start) const } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool String::startsWith(const String& str) const +{ + return (find(str) == 0); +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/VisualizationModules/LibCore/cvfString.h b/VisualizationModules/LibCore/cvfString.h index 7a0d45e0b0..35c820e867 100644 --- a/VisualizationModules/LibCore/cvfString.h +++ b/VisualizationModules/LibCore/cvfString.h @@ -69,6 +69,7 @@ public: std::vector split(const String& delimiters = " ") const; size_t find(const String& str, size_t start = 0) const; + bool startsWith(const String& str) const; String subString(size_t start, size_t length = npos) const; void replace(const String& before, const String& after); diff --git a/VisualizationModules/LibRender/CMakeLists.txt b/VisualizationModules/LibRender/CMakeLists.txt index f2005f4d69..d4ea84debf 100644 --- a/VisualizationModules/LibRender/CMakeLists.txt +++ b/VisualizationModules/LibRender/CMakeLists.txt @@ -20,6 +20,7 @@ include_directories(glew) set(CEE_HEADER_FILES cvfBufferObjectManaged.h cvfCamera.h +cvfCameraAnimation.h cvfDrawable.h cvfDrawableGeo.h cvfDrawableText.h @@ -98,6 +99,7 @@ cvfViewport.h set(CEE_SOURCE_FILES cvfBufferObjectManaged.cpp cvfCamera.cpp +cvfCameraAnimation.cpp cvfDrawable.cpp cvfDrawableGeo.cpp cvfDrawableVectors.cpp diff --git a/VisualizationModules/LibRender/cvfCamera.cpp b/VisualizationModules/LibRender/cvfCamera.cpp index 6ea6a8ebc7..0aea6f4b47 100644 --- a/VisualizationModules/LibRender/cvfCamera.cpp +++ b/VisualizationModules/LibRender/cvfCamera.cpp @@ -268,13 +268,23 @@ void Camera::setProjectionAsPixelExact2D() /// the view to. The relativeDistance parameter specifies the distance from the camera to the /// center of the bounding box //-------------------------------------------------------------------------------------------------- -void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double distanceScaleFactor) +void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor) +{ + // Use old view direction, but look towards model center + Vec3d eye = fitViewEyePosition(boundingBox, dir, up, coverageFactor); + + // Will update cached values + setFromLookAt(eye, boundingBox.center(), up); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Vec3d Camera::fitViewEyePosition(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor) const { CVF_ASSERT(projection() == PERSPECTIVE); - // TODO! !!! !! !! - CVF_UNUSED(distanceScaleFactor); - cvf::Vec3d corners[8]; boundingBox.cornerVertices(corners); @@ -312,8 +322,8 @@ void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec distUp += (centerToCornerSide*boxEyeNorm); // Adjust for the distance scale factor - distRight /= distanceScaleFactor; - distUp /= distanceScaleFactor; + distRight /= coverageFactor; + distUp /= coverageFactor; dist = CVF_MAX(dist, distRight); dist = CVF_MAX(dist, distUp); @@ -328,8 +338,7 @@ void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec // Use old view direction, but look towards model center Vec3d eye = boundingBox.center()- dir.getNormalized()*dist; - // Will update cached values - setFromLookAt(eye, boundingBox.center(), up); + return eye; } @@ -1023,6 +1032,5 @@ void Camera::applyOpenGL() const #endif } - } // namespace cvf diff --git a/VisualizationModules/LibRender/cvfCamera.h b/VisualizationModules/LibRender/cvfCamera.h index d00e364cf4..c247c47fe0 100644 --- a/VisualizationModules/LibRender/cvfCamera.h +++ b/VisualizationModules/LibRender/cvfCamera.h @@ -66,6 +66,8 @@ public: void fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9); void fitViewOrtho(const BoundingBox& boundingBox, double eyeDist, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9); + Vec3d fitViewEyePosition(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9) const; + void setClipPlanesFromBoundingBox(const BoundingBox& boundingBox, double minNearPlaneDistance = 0.01); const Mat4d& viewMatrix() const; diff --git a/VisualizationModules/LibRender/cvfCameraAnimation.cpp b/VisualizationModules/LibRender/cvfCameraAnimation.cpp new file mode 100644 index 0000000000..f18144f184 --- /dev/null +++ b/VisualizationModules/LibRender/cvfCameraAnimation.cpp @@ -0,0 +1,109 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfBase.h" +#include "cvfCameraAnimation.h" +#include "cvfCamera.h" +#include "cvfTimer.h" + +namespace cvf { + + +//================================================================================================== +/// +/// \class cvf::CameraAnimation +/// \ingroup Render +/// +/// Support class for creating a camera path animation from one camera configuration to another. +/// +//================================================================================================== + + +//-------------------------------------------------------------------------------------------------- +/// Configures the animation with start and end point +//-------------------------------------------------------------------------------------------------- +CameraAnimation::CameraAnimation(const Vec3d& currentPos, const Vec3d& currentDir, const Vec3d& currentUp, const Vec3d& newPos, const Vec3d& newDir, const Vec3d& newUp) +: m_currentPos(currentPos), + m_currentDir(currentDir), + m_currentUp(currentUp), + m_newPos(newPos), + m_newDir(newDir), + m_newUp(newUp), + m_animDuration(0.75), + m_animDone(false) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// Returns the next position in the animation. After the duration of the animation is used up, +/// the method returns the end point and after that always returns false. +/// +/// So usage would be: +/// \code +/// cvf::Vec3d pos, dir, up; +/// while(anim.newPosition(&pos, &dir, &up)) +/// { +/// m_camera->setFromLookAt(pos, pos + dir, up); +/// repaint(); +/// } +/// \endcode +//-------------------------------------------------------------------------------------------------- +bool CameraAnimation::newPosition(Vec3d* pos, Vec3d* dir, Vec3d* up) +{ + if (m_animDone) + { + return false; + } + + if (m_timer.isNull()) + { + m_timer = new Timer; + } + + double timeNow = m_timer->time(); + + if (timeNow > m_animDuration) + { + *pos = m_newPos; + *dir = m_newDir; + *up = m_newUp; + + m_animDone = true; + + return true; + } + + *pos = m_currentPos + (m_newPos - m_currentPos)*(timeNow/m_animDuration); + *dir = m_currentDir + (m_newDir - m_currentDir)*(timeNow/m_animDuration); + *up = m_currentUp + (m_newUp - m_currentUp )*(timeNow/m_animDuration); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// Sets the duration of the animation +//-------------------------------------------------------------------------------------------------- +void CameraAnimation::setDuration(double seconds) +{ + m_animDuration = seconds; +} + +} // namespace cvf + diff --git a/VisualizationModules/LibRender/cvfCameraAnimation.h b/VisualizationModules/LibRender/cvfCameraAnimation.h new file mode 100644 index 0000000000..70e166f8bf --- /dev/null +++ b/VisualizationModules/LibRender/cvfCameraAnimation.h @@ -0,0 +1,56 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cvfObject.h" +#include "cvfVector3.h" + +namespace cvf { + +class Timer; + +//================================================================================================== +// +// Camera animation class +// +//================================================================================================== +class CameraAnimation : public Object +{ +public: + CameraAnimation(const Vec3d& currentPos, const Vec3d& currentDir, const Vec3d& currentUp, const Vec3d& newPos, const Vec3d& newDir, const Vec3d& newUp); + + void setDuration(double seconds); + + bool newPosition(Vec3d* pos, Vec3d* dir, Vec3d* up); + +private: + Vec3d m_currentPos; + Vec3d m_currentDir; + Vec3d m_currentUp; + Vec3d m_newPos; + Vec3d m_newDir; + Vec3d m_newUp; + + ref m_timer; + double m_animDuration; + bool m_animDone; +}; + +} diff --git a/VisualizationModules/LibRender/cvfDrawableGeo.cpp b/VisualizationModules/LibRender/cvfDrawableGeo.cpp index 447496332e..28ee7bba9c 100644 --- a/VisualizationModules/LibRender/cvfDrawableGeo.cpp +++ b/VisualizationModules/LibRender/cvfDrawableGeo.cpp @@ -1273,8 +1273,6 @@ BoundingBox DrawableGeo::boundingBox() const //-------------------------------------------------------------------------------------------------- bool DrawableGeo::rayIntersect(const Ray& ray, Vec3d* intersectionPoint, uint* faceHit) const { - CVF_ASSERT(intersectionPoint); - bool anyHits = false; double minDistSquared = 1.0e300; @@ -1314,19 +1312,23 @@ bool DrawableGeo::rayIntersect(const Ray& ray, Vec3d* intersectionPoint, uint* f double distSquared = (ray.origin() - localIntersect).lengthSquared(); #pragma omp critical { - if (distSquared < minDistSquared) + if (distSquared < minDistSquared) + { + if (intersectionPoint) { - *intersectionPoint = localIntersect; - minDistSquared = distSquared; - - if (faceHit) - { - *faceHit = i + accumulatedFaceCount; - } + *intersectionPoint = localIntersect; } - anyHits = true; - } + + minDistSquared = distSquared; + + if (faceHit) + { + *faceHit = i + accumulatedFaceCount; + } + } + anyHits = true; } + } } // End omp parallel for accumulatedFaceCount += numPrimFaces; } diff --git a/VisualizationModules/LibRender/cvfDrawableText.cpp b/VisualizationModules/LibRender/cvfDrawableText.cpp index 1948122fdf..11ac32b535 100644 --- a/VisualizationModules/LibRender/cvfDrawableText.cpp +++ b/VisualizationModules/LibRender/cvfDrawableText.cpp @@ -64,7 +64,8 @@ DrawableText::DrawableText() m_borderColor(Color3::BLACK), m_drawBackground(true), m_drawBorder(true), - m_checkPosVisible(true) + m_checkPosVisible(true), + m_useDepthBuffer(false) { } @@ -158,6 +159,15 @@ void DrawableText::setCheckPosVisible(bool checkpos) } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void DrawableText::setUseDepthBuffer(bool useDepthBuffer) +{ + m_useDepthBuffer = useDepthBuffer; +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -323,7 +333,7 @@ void DrawableText::renderText(OpenGLContext* oglContext, ShaderProgram* shaderPr if (!m_checkPosVisible || labelAnchorVisible(oglContext, proj, m_positions[pos], shaderProgram == NULL)) { // Note: Need to adjust for the current viewport, as the coords returned from project are in global windows coordinates - projCoords.push_back(Vec3f(static_cast(proj.x() - matrixState.viewportPosition().x()), static_cast(proj.y() - matrixState.viewportPosition().y()), 0.0f)); + projCoords.push_back(Vec3f(static_cast(proj.x() - matrixState.viewportPosition().x()), static_cast(proj.y() - matrixState.viewportPosition().y()), static_cast(1.0 - 2.0*proj.z()))); // Map z into 1 .. -1 textsToDraw.push_back(m_texts[pos]); } } @@ -355,12 +365,13 @@ void DrawableText::renderText(OpenGLContext* oglContext, ShaderProgram* shaderPr drawer.setBorderColor(m_borderColor); drawer.setDrawBorder(m_drawBorder); drawer.setDrawBackground(m_drawBackground); + drawer.setUseDepthBuffer(m_useDepthBuffer); size_t i; for (i = 0; i < textsToDraw.size(); i++) { Vec3f pos = projCoords[i]; - drawer.addText(textsToDraw[i], Vec2f(pos)); + drawer.addText(textsToDraw[i], pos); } if (shaderProgram) @@ -423,4 +434,38 @@ bool DrawableText::labelAnchorVisible(OpenGLContext* oglContext, const Vec3d win } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool DrawableText::rayIntersect(const Ray& ray, const Camera& camera, Vec3d* intersectionPoint) +{ + Vec3d pickCoord2d; + camera.project(ray.origin(), &pickCoord2d); + + size_t i; + for (i = 0; i < m_positions.size(); i++) + { + Vec3d proj; + camera.project(Vec3d(m_positions[i]), &proj); + + Vec3f posTextDrawer = Vec3f(static_cast(proj.x() - camera.viewport()->x()), static_cast(proj.y() - camera.viewport()->y()), static_cast(1.0 - 2.0*proj.z())); // Map z into 1 .. -1 + + if (TextDrawer::pickText(Vec3f(pickCoord2d), m_texts[i], posTextDrawer, m_font.p())) + { + if (m_useDepthBuffer) + { + *intersectionPoint = Vec3d(m_positions[i]); + } + else + { + *intersectionPoint = ray.origin(); + } + + return true; + } + } + + return false; +} + } // namespace cvf diff --git a/VisualizationModules/LibRender/cvfDrawableText.h b/VisualizationModules/LibRender/cvfDrawableText.h index 9299ecd699..f9a6bdacfc 100644 --- a/VisualizationModules/LibRender/cvfDrawableText.h +++ b/VisualizationModules/LibRender/cvfDrawableText.h @@ -30,6 +30,7 @@ class Font; class DrawableGeo; class ShaderProgram; class BufferObjectManaged; +class Camera; //================================================================================================== @@ -55,6 +56,7 @@ public: void setDrawBackground(bool drawBackground); void setDrawBorder(bool drawBorder); void setCheckPosVisible(bool checkpos); + void setUseDepthBuffer(bool useDepthBuffer); virtual void createUploadBufferObjectsGPU(OpenGLContext* /*oglContext*/) {} virtual void releaseBufferObjectsGPU() {} @@ -69,6 +71,7 @@ public: virtual BoundingBox boundingBox() const; virtual bool rayIntersectCreateDetail(const Ray& ray, Vec3d* intersectionPoint, ref* hitDetail) const; + bool rayIntersect(const Ray& ray, const Camera& camera, Vec3d* intersectionPoint); // TO BE REMOVED! virtual void renderFixedFunction(OpenGLContext* oglContext, const MatrixState& matrixState) { renderSoftware(oglContext, matrixState); } @@ -92,6 +95,7 @@ private: bool m_drawBackground; bool m_drawBorder; bool m_checkPosVisible; + bool m_useDepthBuffer; BoundingBox m_boundingBox; // }; diff --git a/VisualizationModules/LibRender/cvfOpenGL.cpp b/VisualizationModules/LibRender/cvfOpenGL.cpp index 3d76136ca0..b021de0ae9 100644 --- a/VisualizationModules/LibRender/cvfOpenGL.cpp +++ b/VisualizationModules/LibRender/cvfOpenGL.cpp @@ -136,7 +136,7 @@ String OpenGL::mapOpenGLErrorToString(cvfGLenum errorCode) //-------------------------------------------------------------------------------------------------- /// Returns false if no error. //-------------------------------------------------------------------------------------------------- -bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* operation, const char* fileName, int line) +bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* operation, const CodeLocation& codeLocation) { // glGetError will end up in an endless loop if no context is current CVF_ASSERT(oglContext); @@ -157,7 +157,7 @@ bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* ope String errCodeStr = mapOpenGLErrorToString(err); String msg = String("Operation: ") + operation; msg += "OGL(" + errCodeStr + "): "; - logger->error(msg, fileName, line); + logger->error(msg, codeLocation); } err = glGetError(); @@ -170,7 +170,7 @@ bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* ope //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void OpenGL::cvf_check_ogl(OpenGLContext* oglContext, const char* fileName, int line) +void OpenGL::cvf_check_ogl(OpenGLContext* oglContext, const CodeLocation& codeLocation) { if (OpenGL::m_enableCheckOgl) { @@ -186,7 +186,7 @@ void OpenGL::cvf_check_ogl(OpenGLContext* oglContext, const char* fileName, int { String errCodeStr = mapOpenGLErrorToString(err); String msg = "OGL(" + errCodeStr + "): "; - logger->error(msg, fileName, line); + logger->error(msg, codeLocation); } err = glGetError(); diff --git a/VisualizationModules/LibRender/cvfOpenGL.h b/VisualizationModules/LibRender/cvfOpenGL.h index a08b3dbd0f..691563dc73 100644 --- a/VisualizationModules/LibRender/cvfOpenGL.h +++ b/VisualizationModules/LibRender/cvfOpenGL.h @@ -84,6 +84,7 @@ #include "cvfOpenGLTypes.h" #include "cvfString.h" +#include "cvfCodeLocation.h" // As long as we're using GLEW we will almost always need the context and context group when doing OpenGL calls #include "cvfOpenGLContext.h" @@ -105,9 +106,9 @@ public: static void clearOpenGLError(OpenGLContext* oglContext); static String mapOpenGLErrorToString(cvfGLenum errorCode); - static bool testAndReportOpenGLError(OpenGLContext* oglContext, const char* operation, const char* fileName, int line); + static bool testAndReportOpenGLError(OpenGLContext* oglContext, const char* operation, const CodeLocation& codeLocation); - static void cvf_check_ogl(OpenGLContext* oglContext, const char* fileName, int line); + static void cvf_check_ogl(OpenGLContext* oglContext, const CodeLocation& codeLocation); static void enableCheckOgl(bool enable); static bool isCheckOglEnabled(); @@ -123,8 +124,8 @@ private: #define CVF_OGL_BUFFER_OFFSET(BYTE_OFFSET) ((char*)NULL + (BYTE_OFFSET)) // Define used to log error messages with file and line -#define CVF_CHECK_OGL(OGL_CTX_PTR) cvf::OpenGL::cvf_check_ogl(OGL_CTX_PTR, __FILE__, __LINE__) +#define CVF_CHECK_OGL(OGL_CTX_PTR) cvf::OpenGL::cvf_check_ogl(OGL_CTX_PTR, CVF_CODE_LOCATION) #define CVF_CLEAR_OGL_ERROR(OGL_CTX_PTR) cvf::OpenGL::clearOpenGLError(OGL_CTX_PTR) -#define CVF_TEST_AND_REPORT_OPENGL_ERROR(OGL_CTX_PTR, OPERATION) cvf::OpenGL::testAndReportOpenGLError(OGL_CTX_PTR, OPERATION, __FILE__, __LINE__) +#define CVF_TEST_AND_REPORT_OPENGL_ERROR(OGL_CTX_PTR, OPERATION) cvf::OpenGL::testAndReportOpenGLError(OGL_CTX_PTR, OPERATION, CVF_CODE_LOCATION) diff --git a/VisualizationModules/LibRender/cvfOpenGLContext.h b/VisualizationModules/LibRender/cvfOpenGLContext.h index 32f0520207..2ae21727d9 100644 --- a/VisualizationModules/LibRender/cvfOpenGLContext.h +++ b/VisualizationModules/LibRender/cvfOpenGLContext.h @@ -58,9 +58,9 @@ private: friend class OpenGLContextGroup; }; -#define CVF_LOG_RENDER_ERROR(OGL_CTX_PTR, THE_MESSAGE) OGL_CTX_PTR->group()->logger()->error((THE_MESSAGE), __FILE__, __LINE__ ) +#define CVF_LOG_RENDER_ERROR(OGL_CTX_PTR, THE_MESSAGE) OGL_CTX_PTR->group()->logger()->error((THE_MESSAGE), CVF_CODE_LOCATION) -#define CVF_LOG_RENDER_DEBUG(OGL_CTX_PTR, THE_MESSAGE) OGL_CTX_PTR->group()->logger()->debug((THE_MESSAGE), __FILE__, __LINE__ ) +#define CVF_LOG_RENDER_DEBUG(OGL_CTX_PTR, THE_MESSAGE) OGL_CTX_PTR->group()->logger()->debug((THE_MESSAGE), CVF_CODE_LOCATION) #define CVF_SHOULD_LOG_RENDER_DEBUG(OGL_CTX_PTR) OGL_CTX_PTR->group()->logger()->isDebugEnabled() diff --git a/VisualizationModules/LibRender/cvfOpenGLContextGroup.cpp b/VisualizationModules/LibRender/cvfOpenGLContextGroup.cpp index ad6e99c802..abf299e7b2 100644 --- a/VisualizationModules/LibRender/cvfOpenGLContextGroup.cpp +++ b/VisualizationModules/LibRender/cvfOpenGLContextGroup.cpp @@ -23,7 +23,7 @@ #include "cvfOpenGLContext.h" #include "cvfOpenGLResourceManager.h" #include "cvfOpenGLCapabilities.h" -#include "cvfTrace.h" +#include "cvfLogDestinationConsole.h" #include @@ -58,7 +58,7 @@ OpenGLContextGroup::OpenGLContextGroup() m_wglewContextStruct(NULL) { m_resourceManager = new OpenGLResourceManager; - m_logger = new Logger; + m_logger = new Logger("cvf.OpenGL", Logger::LL_WARNING, new LogDestinationConsole); m_capabilities = new OpenGLCapabilities; } diff --git a/VisualizationModules/LibRender/cvfOverlayImage.cpp b/VisualizationModules/LibRender/cvfOverlayImage.cpp index 0bb7443fc8..1c42403920 100644 --- a/VisualizationModules/LibRender/cvfOverlayImage.cpp +++ b/VisualizationModules/LibRender/cvfOverlayImage.cpp @@ -40,6 +40,7 @@ #ifndef CVF_OPENGL_ES #include "cvfRenderState_FF.h" #endif +#include "cvfTexture2D_FF.h" namespace cvf { @@ -152,6 +153,23 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons if (software) { + // Create a POW2 texture for software rendering if needed + if (m_image.notNull() && m_pow2Image.isNull() && (!Math::isPow2(m_image->width()) || !Math::isPow2(m_image->height()))) + { + m_pow2Image = new TextureImage; + m_pow2Image->allocate(Math::roundUpPow2(m_image->width()), Math::roundUpPow2(m_image->height())); + m_pow2Image->fill(Color4ub(Color3::BLACK)); + + for (uint y = 0; y < m_image->height(); ++y) + { + for (uint x = 0; x < m_image->width(); ++x) + { + m_pow2Image->setPixel(x, y, m_image->pixel(x, y)); + } + } + } + + if (ShaderProgram::supportedOpenGL(oglContext)) { ShaderProgram::useNoProgram(oglContext); @@ -164,7 +182,34 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons RenderStateLighting_FF light(false); light.applyOpenGL(oglContext); + + if (m_textureBindings.isNull()) + { + // Use fixed function texture setup + ref texture = new Texture2D_FF(m_pow2Image.notNull() ? m_pow2Image.p() : m_image.p()); + texture->setWrapMode(Texture2D_FF::CLAMP); + texture->setMinFilter(Texture2D_FF::NEAREST); + texture->setMagFilter(Texture2D_FF::NEAREST); + texture->setupTexture(oglContext); + texture->setupTextureParams(oglContext); + + ref textureMapping = new RenderStateTextureMapping_FF(texture.p()); + textureMapping->setTextureFunction(m_blendMode == TEXTURE_ALPHA ? RenderStateTextureMapping_FF::MODULATE : RenderStateTextureMapping_FF::DECAL); + + m_textureBindings = textureMapping; + } #endif + // Adjust texture coordinates + if (m_pow2Image.notNull()) + { + float xMax = static_cast(m_image->width())/static_cast(m_pow2Image->width()); + float yMax = static_cast(m_image->height())/static_cast(m_pow2Image->height()); + textureCoords[2] = xMax; + textureCoords[4] = xMax; + textureCoords[5] = yMax; + textureCoords[7] = yMax; + } + projCam.applyOpenGL(); } else @@ -200,10 +245,23 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons m_shaderProgram->clearUniformApplyTracking(); m_shaderProgram->applyFixedUniforms(oglContext, projMatrixState); } + + if (m_texture->textureOglId() == 0) + { + m_texture->setupTexture(oglContext); + } + + if (m_textureBindings.isNull()) + { + cvf::RenderStateTextureBindings* textureBindings = new cvf::RenderStateTextureBindings; + textureBindings->addBinding(m_texture.p(), m_sampler.p(), "u_texture2D"); + m_textureBindings = textureBindings; + } } - Vec3f min(1.0f, 1.0f, 0.0f); - Vec3f max(static_cast(size.x() - 1), static_cast(size.y() - 1), 0.0f); + float offset = 0.0f; + Vec3f min(offset, offset, 0.0f); + Vec3f max(static_cast(size.x()) + offset, static_cast(size.y()) + offset, 0.0f); // Setup the vertex array float* v1 = &vertexArray[0]; @@ -214,12 +272,6 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons v2[0] = max.x(); v2[1] = min.y(); v2[2] = 0.0f; v3[0] = max.x(); v3[1] = max.y(); v3[2] = 0.0f; v4[0] = min.x(); v4[1] = max.y(); v4[2] = 0.0f; - - - if (m_texture->textureOglId() == 0) - { - m_texture->setupTexture(oglContext); - } if (m_blendMode != NO_BLENDING) { @@ -233,7 +285,7 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons if (software) { #ifndef CVF_OPENGL_ES - glColor4f(1.0f, 1.0f, 1.0f, m_alpha); + glColor4f(1.0f, 1.0f, 1.0f, m_blendMode == GLOBAL_ALPHA ? m_alpha : 1.0f); glBegin(GL_TRIANGLE_FAN); glTexCoord2f(textureCoords[0], textureCoords[1]); glVertex3fv(v1); @@ -263,6 +315,17 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons blend.applyOpenGL(oglContext); } + RenderStateDepth resetDepth; + resetDepth.applyOpenGL(oglContext); + + if (software) + { +#ifndef CVF_OPENGL_ES + RenderStateTextureMapping_FF resetTextureMapping; + resetTextureMapping.applyOpenGL(oglContext); +#endif + } + if (!software) { glDisableVertexAttribArray(ShaderProgram::VERTEX); @@ -277,11 +340,11 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons void OverlayImage::setImage(TextureImage* image) { m_image = image; + m_pow2Image = NULL; m_texture = new Texture(image); - m_textureBindings = new cvf::RenderStateTextureBindings; - m_textureBindings->addBinding(m_texture.p(), m_sampler.p(), "u_texture2D"); + m_textureBindings = NULL; } diff --git a/VisualizationModules/LibRender/cvfOverlayImage.h b/VisualizationModules/LibRender/cvfOverlayImage.h index 8a68e5274f..854f491475 100644 --- a/VisualizationModules/LibRender/cvfOverlayImage.h +++ b/VisualizationModules/LibRender/cvfOverlayImage.h @@ -25,7 +25,7 @@ namespace cvf { class TextureImage; class Sampler; -class RenderStateTextureBindings; +class RenderState; class Texture; class ShaderProgram; @@ -68,8 +68,9 @@ private: private: Vec2ui m_size; ref m_image; + ref m_pow2Image; ref m_sampler; - ref m_textureBindings; + ref m_textureBindings; ref m_texture; ref m_shaderProgram; diff --git a/VisualizationModules/LibRender/cvfOverlayItem.h b/VisualizationModules/LibRender/cvfOverlayItem.h index d196c29e16..a419c93015 100644 --- a/VisualizationModules/LibRender/cvfOverlayItem.h +++ b/VisualizationModules/LibRender/cvfOverlayItem.h @@ -43,7 +43,8 @@ public: TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, - BOTTOM_RIGHT + BOTTOM_RIGHT, + UNMANAGED }; enum LayoutDirection @@ -56,10 +57,17 @@ public: virtual Vec2ui sizeHint() = 0; // In Pixels virtual Vec2ui maximumSize() = 0; // In Pixels virtual Vec2ui minimumSize() = 0; // In Pixels + + cvf::Vec2i unmanagedPosition() const { return m_unmanagedPosition; } + void setUnmanagedPosition(cvf::Vec2i val) { m_unmanagedPosition = val; } virtual void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) = 0; virtual void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) = 0; virtual bool pick(int oglXCoord, int oglYCoord, const Vec2i& position, const Vec2ui& size); + +private: + Vec2i m_unmanagedPosition; + }; } diff --git a/VisualizationModules/LibRender/cvfOverlayNavigationCube.cpp b/VisualizationModules/LibRender/cvfOverlayNavigationCube.cpp index 8a0c6d9d2a..a28fb8bf08 100644 --- a/VisualizationModules/LibRender/cvfOverlayNavigationCube.cpp +++ b/VisualizationModules/LibRender/cvfOverlayNavigationCube.cpp @@ -40,9 +40,15 @@ #include "cvfPrimitiveSetIndexedUShort.h" #include "cvfShaderProgramGenerator.h" #include "cvfShaderSourceProvider.h" +#include "cvfRay.h" +#include "cvfRenderStateDepth.h" +#include "cvfTexture.h" +#include "cvfSampler.h" +#include "cvfRenderStateTextureBindings.h" #ifndef CVF_OPENGL_ES #include "cvfRenderState_FF.h" +#include "cvfTexture2D_FF.h" #endif @@ -63,12 +69,22 @@ namespace cvf { //-------------------------------------------------------------------------------------------------- OverlayNavigationCube::OverlayNavigationCube(Camera* camera, Font* font) : m_camera(camera), - m_xLabel("ax"), - m_yLabel("by"), - m_zLabel("cz"), - m_textColor(Color3::BLACK), m_font(font), - m_size(120, 120) + m_xLabel("x"), + m_yLabel("y"), + m_zLabel("z"), + m_textColor(Color3::BLACK), + m_size(120, 120), + m_homeViewDirection(-Vec3f::Z_AXIS), + m_homeUp(Vec3f::Y_AXIS), + m_hightlightItem(NCI_NONE), + m_upVector(Vec3d::Z_AXIS), + m_frontVector(-Vec3d::Y_AXIS), + m_xFaceColor(Color3::RED), + m_yFaceColor(Color3::GREEN), + m_zFaceColor(Color3::BLUE), + m_itemHighlightColor(Color3::GRAY), + m_2dItemsColor(Color3::WHITE) { } @@ -78,14 +94,13 @@ OverlayNavigationCube::OverlayNavigationCube(Camera* camera, Font* font) //-------------------------------------------------------------------------------------------------- OverlayNavigationCube::~OverlayNavigationCube() { - // Empty destructor to avoid errors with undefined types when cvf::ref's destructor gets called } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void OverlayNavigationCube::setAxisLabels( const String& xLabel, const String& yLabel, const String& zLabel ) +void OverlayNavigationCube::setAxisLabels(const String& xLabel, const String& yLabel, const String& zLabel) { // Clipping of axis label text is depends on m_size and // z-part of axisMatrix.setTranslation(Vec3d(0, 0, -4.4)) defined in OverlayNavigationCube::render() @@ -147,8 +162,7 @@ void OverlayNavigationCube::setSize(const Vec2ui& size) //-------------------------------------------------------------------------------------------------- void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) { - Mat4d viewMatrix = m_camera->viewMatrix(); - render(oglContext, position, size, false, viewMatrix); + render(oglContext, position, size, false); } @@ -157,21 +171,25 @@ void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& posit //-------------------------------------------------------------------------------------------------- void OverlayNavigationCube::renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) { - Mat4d viewMatrix = m_camera->viewMatrix(); - render(oglContext, position, size, true, viewMatrix); + render(oglContext, position, size, true); } //-------------------------------------------------------------------------------------------------- /// Set up camera/viewport and render //-------------------------------------------------------------------------------------------------- -void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software, const Mat4d& viewMatrix) +void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software) { if (size.x() <= 0 || size.y() <= 0) { return; } + if (software && ShaderProgram::supportedOpenGL(oglContext)) + { + ShaderProgram::useNoProgram(oglContext); + } + if (m_axis.isNull()) { createAxisGeometry(software); @@ -181,22 +199,42 @@ void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& posit { createCubeGeos(); - // Create the shader for the cube geometry - ShaderProgramGenerator gen("CubeGeoShader", ShaderSourceProvider::instance()); - gen.configureStandardHeadlightColor(); - m_cubeGeoShader = gen.generate(); - m_cubeGeoShader->linkProgram(oglContext); + if (!software) + { + // Create the shader for the cube geometry + ShaderProgramGenerator gen("CubeGeoShader", ShaderSourceProvider::instance()); + gen.configureStandardHeadlightColor(); + m_cubeGeoShader = gen.generate(); + m_cubeGeoShader->linkProgram(oglContext); + + { + ShaderProgramGenerator gen("CubeGeoTextureShader", ShaderSourceProvider::instance()); + + gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); + gen.addFragmentCode(cvf::ShaderSourceRepository::src_Texture); + gen.addFragmentCode(cvf::ShaderSourceRepository::light_Headlight); + gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard); + + m_cubeGeoTextureShader = gen.generate(); + + m_cubeGeoTextureShader->setDefaultUniform(new cvf::UniformFloat("u_specularIntensity", 0.1f)); + m_cubeGeoTextureShader->setDefaultUniform(new cvf::UniformFloat("u_ambientIntensity", 0.2f)); + m_cubeGeoTextureShader->setDefaultUniform(new cvf::UniformFloat("u_emissiveColor", cvf::Vec3f(0.0f, 0.0f, 0.0f))); + m_cubeGeoTextureShader->setDefaultUniform(new cvf::UniformFloat("u_ecLightPosition", cvf::Vec3f(0.5f, 5.0f, 7.0f))); + + m_cubeGeoTextureShader->linkProgram(oglContext); + } + } } - // Position the camera far enough away to make the axis and the text fit within the viewport - Mat4d axisMatrix = viewMatrix; - axisMatrix.setTranslation(Vec3d(0, 0, -2.0)); + if (m_2dGeos.size() == 0) + { + create2dGeos(); + } // Setup camera Camera cam; - cam.setProjectionAsPerspective(40.0, 0.05, 100.0); - cam.setViewMatrix(axisMatrix); - cam.setViewport(position.x(), position.y(), size.x(), size.y()); + configureLocalCamera(&cam, position, size); // Setup viewport cam.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH); @@ -204,7 +242,6 @@ void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& posit // Do the actual rendering - // ----------------------------------------------- MatrixState matrixState(cam); if (software) { @@ -216,8 +253,9 @@ void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& posit } renderCubeGeos(oglContext, software, matrixState); - renderAxisLabels(oglContext, software, matrixState); + + render2dItems(oglContext, position, size, software); } @@ -275,23 +313,25 @@ void OverlayNavigationCube::createAxisGeometry(bool software) ref vertexArray = new Vec3fArray; vertexArray->resize(3); - vertexArray->set(0, cp[0]); // X axis - vertexArray->set(1, cp[0]); // Y axis - vertexArray->set(2, cp[0]); // Z axis + vertexArray->set(0, cp[0]); // X axis + vertexArray->set(1, cp[0]); // Y axis + vertexArray->set(2, cp[0]); // Z axis // Direction & magnitude of the vectors + float arrowLength = 0.8f; + ref vectorArray = new Vec3fArray; vectorArray->resize(3); - vectorArray->set(0, Vec3f::X_AXIS); // X axis - vectorArray->set(1, Vec3f::Y_AXIS); // Y axis - vectorArray->set(2, Vec3f::Z_AXIS); // Z axis + vectorArray->set(0, arrowLength*Vec3f::X_AXIS); + vectorArray->set(1, arrowLength*Vec3f::Y_AXIS); + vectorArray->set(2, arrowLength*Vec3f::Z_AXIS); // Create the arrow glyph for the vector drawer GeometryBuilderTriangles arrowBuilder; ArrowGenerator gen; - gen.setShaftRelativeRadius(0.045f); - gen.setHeadRelativeRadius(0.12f); - gen.setHeadRelativeLength(0.2f); + gen.setShaftRelativeRadius(0.020f); + gen.setHeadRelativeRadius(0.05f); + gen.setHeadRelativeLength(0.1f); gen.setNumSlices(30); gen.generate(&arrowBuilder); @@ -310,6 +350,61 @@ void OverlayNavigationCube::createAxisGeometry(bool software) } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::updateTextureBindings(OpenGLContext* oglContext, bool software) +{ + m_faceTextureBindings.clear(); + + for (size_t i = 0; i < 6; i++) + { + NavCubeFace face = static_cast(i); + std::map >::iterator it = m_faceTextures.find(face); + + if (it != m_faceTextures.end()) + { + if (software) + { +#ifndef CVF_OPENGL_ES + // Use fixed function texture setup + ref texture = new Texture2D_FF(it->second.p()); + texture->setWrapMode(Texture2D_FF::CLAMP); + texture->setMinFilter(Texture2D_FF::NEAREST); + texture->setMagFilter(Texture2D_FF::NEAREST); + texture->setupTexture(oglContext); + texture->setupTextureParams(oglContext); + + ref textureMapping = new RenderStateTextureMapping_FF(texture.p()); + textureMapping->setTextureFunction(RenderStateTextureMapping_FF::MODULATE); + + m_faceTextureBindings[face] = textureMapping; +#else + CVF_FAIL_MSG("Not supported on OpenGL ES"); +#endif + + } + else + { + ref texture = new cvf::Texture(it->second.p()); + ref sampler = new cvf::Sampler; + texture->enableMipmapGeneration(true); + sampler->setWrapMode(Sampler::CLAMP_TO_EDGE); + sampler->setMinFilter(Sampler::LINEAR_MIPMAP_LINEAR); + sampler->setMagFilter(Sampler::NEAREST); + + ref texBind = new cvf::RenderStateTextureBindings; + texBind->addBinding(texture.p(), sampler.p(), "u_texture2D"); + + texBind->setupTextures(oglContext); + + m_faceTextureBindings[face] = texBind; + } + } + } +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -317,10 +412,312 @@ void OverlayNavigationCube::renderCubeGeos(OpenGLContext* oglContext, bool softw { CVF_UNUSED(software); - for (size_t i = 0; i < m_cubeGeos.size(); ++i) + if (m_faceTextureBindings.size() != m_faceTextures.size()) { - m_cubeGeos[i]->render(oglContext, m_cubeGeoShader.p(), matrixState); + updateTextureBindings(oglContext, software); } + + if (software) + { +#ifndef CVF_OPENGL_ES + RenderStateMaterial_FF mat; + mat.enableColorMaterial(true); + mat.applyOpenGL(oglContext); + + RenderStateLighting_FF light; + light.applyOpenGL(oglContext); +#endif + } + + for (size_t i = 0; i < 6; i++) + { + NavCubeFace face = static_cast(i); + + std::map >::iterator it = m_faceTextures.find(m_cubeGeoFace[i]); + ShaderProgram* shader = NULL; + bool hasTexture = it != m_faceTextures.end(); + + if (hasTexture) + { + RenderState* textureBinding = m_faceTextureBindings[face].p(); + CVF_ASSERT(textureBinding); + textureBinding->applyOpenGL(oglContext); + } + + if (!software) + { + shader = hasTexture ? m_cubeGeoTextureShader.p() : m_cubeGeoShader.p(); + + if (shader->useProgram(oglContext)) + { + shader->applyFixedUniforms(oglContext, matrixState); + } + } + + Color3f faceColor; + switch (face) + { + case NCF_X_POS: + case NCF_X_NEG: faceColor = m_xFaceColor; break; + case NCF_Y_POS: + case NCF_Y_NEG: faceColor = m_yFaceColor; break; + case NCF_Z_POS: + case NCF_Z_NEG: faceColor = m_zFaceColor; break; + } + + for (size_t i = 0; i < m_cubeGeos.size(); ++i) + { + if (m_cubeGeoFace[i] == face) + { + Color3f renderFaceColor = faceColor; + cvf::Vec3f emissiveColor = cvf::Vec3f(0.0f, 0.0f, 0.0f); + + if (m_cubeItemType[i] == m_hightlightItem) + { + renderFaceColor = m_itemHighlightColor; + emissiveColor = cvf::Vec3f(-0.25f, -0.25f, -0.25f); + } + + if (software) + { + if (hasTexture) + { + glColor3f(1.0f, 1.0f, 1.0f); + } + else + { + glColor3fv(renderFaceColor.ptr()); + } + + m_cubeGeos[i]->renderImmediateMode(oglContext, matrixState); + } + else + { + if (hasTexture) + { + UniformFloat uniform("u_emissiveColor", emissiveColor); + shader->applyUniform(oglContext, uniform); + } + else + { + UniformFloat uniform("u_color", Color4f(renderFaceColor)); + shader->applyUniform(oglContext, uniform); + } + + m_cubeGeos[i]->render(oglContext, m_cubeGeoShader.p(), matrixState); + } + } + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::render2dItems(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software) +{ + Camera cam; + cam.setViewport(position.x(), position.y(), size.x(), size.y()); + cam.setProjectionAsUnitOrtho(); + + // Setup viewport + cam.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH); + cam.applyOpenGL(); + + RenderStateDepth depth(false); + depth.applyOpenGL(oglContext); + + MatrixState matrixState(cam); + + if (software) + { +#ifdef CVF_OPENGL_ES + CVF_FAIL_MSG("Not supported on OpenGL ES"); +#else + RenderStateLighting_FF light(false); + light.applyOpenGL(oglContext); + glColor3fv(m_hightlightItem == NCI_HOME ? m_itemHighlightColor.ptr() : m_2dItemsColor.ptr()); + + m_homeGeo->renderImmediateMode(oglContext, matrixState); +#endif + } + else + { + if (m_cubeGeoShader->useProgram(oglContext)) + { + m_cubeGeoShader->applyFixedUniforms(oglContext, matrixState); + } + + UniformFloat colorUniform("u_color", Color4f(m_hightlightItem == NCI_HOME ? m_itemHighlightColor : m_2dItemsColor)); + m_cubeGeoShader->applyUniform(oglContext, colorUniform); + m_homeGeo->render(oglContext, m_cubeGeoShader.p(), matrixState); + } + + if (isFaceAlignedViewPoint()) + { + for (size_t i = 0; i < m_2dGeos.size(); ++i) + { + Color3f renderFaceColor = Color3f(1,1,1); + + if (m_2dItemType[i] == m_hightlightItem) + { + renderFaceColor = m_itemHighlightColor; + } + + if (software) + { + glColor3fv(renderFaceColor.ptr()); + m_2dGeos[i]->renderImmediateMode(oglContext, matrixState); + } + else + { + UniformFloat colorUniform("u_color", Color4f(renderFaceColor)); + m_cubeGeoShader->applyUniform(oglContext, colorUniform); + + m_2dGeos[i]->render(oglContext, m_cubeGeoShader.p(), matrixState); + } + } + } + + RenderStateDepth resetDepth; + resetDepth.applyOpenGL(oglContext); + + if (software) + { +#ifdef CVF_OPENGL_ES + CVF_FAIL_MSG("Not supported on OpenGL ES"); +#else + RenderStateLighting_FF resetLight; + resetLight.applyOpenGL(oglContext); +#endif + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::create2dGeos() +{ + // "Home" aka. House geometry + { + m_homeGeo = new DrawableGeo; + + ref vertexArray = new Vec3fArray(12); + vertexArray->set(0, Vec3f(-0.97f, 0.86f, 0.0f)); + vertexArray->set(1, Vec3f(-0.68f, 0.86f, 0.0f)); + vertexArray->set(2, Vec3f(-0.825f, 1.0f, 0.0f)); + vertexArray->set(3, Vec3f(-0.825f, 1.0f, 0.0f)); + + vertexArray->set(4, Vec3f(-0.9f, 0.76f, 0.0f)); + vertexArray->set(5, Vec3f(-0.75f, 0.76f, 0.0f)); + vertexArray->set(6, Vec3f(-0.75f, 0.86f, 0.0f)); + vertexArray->set(7, Vec3f(-0.9f, 0.86f, 0.0f)); + + vertexArray->set(8, Vec3f(-0.77f, 0.86f, 0.0f)); + vertexArray->set(9, Vec3f(-0.75f, 0.86f, 0.0f)); + vertexArray->set(10, Vec3f(-0.75f, 1.0f, 0.0f)); + vertexArray->set(11, Vec3f(-0.77f, 1.0f, 0.0f)); + + for (size_t i = 0; i < vertexArray->size(); ++i) + { + Vec3f v = vertexArray->get(i); + v.x() = 0.5f + v.x()/2.0f; + v.y() = 0.5f + v.y()/2.0f; + vertexArray->set(i, v); + } + + m_homeGeo->setVertexArray(vertexArray.p()); + + ref indices = new cvf::UShortArray(18); + indices->set(0, 0); indices->set(1, 1); indices->set(2, 2); + indices->set(3, 0); indices->set(4, 2); indices->set(5, 3); + + indices->set(6, 4); indices->set(7, 5); indices->set(8, 6); + indices->set(9, 4); indices->set(10, 6); indices->set(11, 7); + + indices->set(12, 8); indices->set(13, 9); indices->set(14, 10); + indices->set(15, 8); indices->set(16, 10); indices->set(17, 11); + + ref primSet = new cvf::PrimitiveSetIndexedUShort(cvf::PT_TRIANGLES); + primSet->setIndices(indices.p()); + m_homeGeo->addPrimitiveSet(primSet.p()); + m_homeGeo->computeNormals(); + } + + m_2dGeos.push_back(create2dArrow(Vec3f(-0.7f, 0,0), Vec3f(-0.9f, 0,0)).p()); m_2dItemType.push_back(NCI_ARROW_LEFT); + m_2dGeos.push_back(create2dArrow(Vec3f(0.7f, 0,0), Vec3f(0.9f, 0,0)).p()); m_2dItemType.push_back(NCI_ARROW_RIGHT); + m_2dGeos.push_back(create2dArrow(Vec3f(0, -0.7f,0), Vec3f(0, -0.9f,0)).p()); m_2dItemType.push_back(NCI_ARROW_BOTTOM); + m_2dGeos.push_back(create2dArrow(Vec3f(0, 0.7f,0), Vec3f(0, 0.9f,0)).p()); m_2dItemType.push_back(NCI_ARROW_TOP); + + // Rotate arrows + m_2dGeos.push_back(create2dArrow(Vec3f(0.75f, 0.65f, 0.0f), Vec3f(0.87f,0.49f, 0.0f)).p()); m_2dItemType.push_back(NCI_ROTATE_CW); + m_2dGeos.push_back(create2dArrow(Vec3f(0.71f, 0.70f, 0.0f), Vec3f(0.59f,0.86f, 0.0f)).p()); m_2dItemType.push_back(NCI_ROTATE_CCW); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +ref OverlayNavigationCube::create2dArrow(const Vec3f& start, const Vec3f& end) +{ + float fWidth = 0.042f; + float fArrowWidth = 0.12f; + float fBaseRelLength = 0.50f; + float fLength = (end - start).length(); + + Vec3f vUp = Vec3f(0,0,1); + Vec3f vDir = (end - start); + Vec3f vRight = vUp^vDir; + vDir.normalize(); + vRight.normalize(); + + Vec3f vBaseBL = start + vDir*fLength*fBaseRelLength + vRight*fWidth; + Vec3f vBaseBR = start + vRight*fWidth; + Vec3f vBaseTL = start + vDir*fLength*fBaseRelLength - vRight*fWidth; + Vec3f vBaseTR = start - vRight*fWidth; + + Vec3f vArrowB = start + vDir*fLength*fBaseRelLength + vRight*fArrowWidth; + Vec3f vArrowT = start + vDir*fLength*fBaseRelLength - vRight*fArrowWidth; + + ref geo = new DrawableGeo; + + ref vertexArray = new Vec3fArray(7); + + vertexArray->set(0, vBaseBL); + vertexArray->set(1, vBaseBR); + vertexArray->set(2, vBaseTR); + vertexArray->set(3, vBaseTL); + + vertexArray->set(4, vArrowT); + vertexArray->set(5, end); + vertexArray->set(6, vArrowB); + + for (size_t i = 0; i < vertexArray->size(); ++i) + { + Vec3f v = vertexArray->get(i); + v.x() = 0.5f + v.x()/2.0f; + v.y() = 0.5f + v.y()/2.0f; + vertexArray->set(i, v); + } + + geo->setVertexArray(vertexArray.p()); + + ref indices = new cvf::UShortArray(9); + indices->set(0, 0); indices->set(1, 1); indices->set(2, 2); + indices->set(3, 0); indices->set(4, 2); indices->set(5, 3); + indices->set(6, 4); indices->set(7, 5); indices->set(8, 6); + + ref primSet = new cvf::PrimitiveSetIndexedUShort(cvf::PT_TRIANGLES); + primSet->setIndices(indices.p()); + geo->addPrimitiveSet(primSet.p()); + geo->computeNormals(); + + m_2dGeos.push_back(geo.p()); + m_2dItemType.push_back(NCI_HOME); + + return geo; } @@ -329,14 +726,22 @@ void OverlayNavigationCube::renderCubeGeos(OpenGLContext* oglContext, bool softw //-------------------------------------------------------------------------------------------------- void OverlayNavigationCube::renderAxisLabels(OpenGLContext* oglContext, bool software, const MatrixState& matrixState) { + if (m_xLabel.isEmpty() && m_yLabel.isEmpty() && m_zLabel.isEmpty()) + { + return; + } + + float fBoxLength = 0.65f; + // Multiply with 1.08 will slightly pull the labels away from the corresponding arrow head - Vec3f xPos(1.08f, 0, 0); - Vec3f yPos(0, 1.08f, 0); - Vec3f zPos(0, 0, 1.08f); + Vec3f xPos(0.5f, -fBoxLength/2.0f, -fBoxLength/2.0f); + Vec3f yPos(-fBoxLength/2.0f, 0.5f, -fBoxLength/2.0f); + Vec3f zPos(-fBoxLength/2.0f, -fBoxLength/2.0f, 0.5f); DrawableText drawableText; drawableText.setFont(m_font.p()); drawableText.setCheckPosVisible(false); + drawableText.setUseDepthBuffer(true); drawableText.setDrawBorder(false); drawableText.setDrawBackground(false); drawableText.setVerticalAlignment(TextDrawer::CENTER); @@ -346,7 +751,6 @@ void OverlayNavigationCube::renderAxisLabels(OpenGLContext* oglContext, bool sof if (!m_yLabel.isEmpty()) drawableText.addText(m_yLabel, yPos); if (!m_zLabel.isEmpty()) drawableText.addText(m_zLabel, zPos); - // Do the actual rendering // ----------------------------------------------- if (software) @@ -415,14 +819,14 @@ void OverlayNavigationCube::createCubeGeos() m_cubeGeos.clear(); - createCubeFaceGeos(NCF_Y_NEG, cp[0], cp[1], cp[5], cp[4]);//, m_yNegAxisName, m_yFaceColor, m_textureNegYAxis.p()); // Front - createCubeFaceGeos(NCF_Y_POS, cp[2], cp[3], cp[7], cp[6]);//, m_yPosAxisName, m_yFaceColor, m_texturePosYAxis.p()); // Back + createCubeFaceGeos(NCF_Y_NEG, cp[0], cp[1], cp[5], cp[4]); + createCubeFaceGeos(NCF_Y_POS, cp[2], cp[3], cp[7], cp[6]); - createCubeFaceGeos(NCF_Z_POS, cp[4], cp[5], cp[6], cp[7]);//, m_zPosAxisName, m_zFaceColor, m_texturePosZAxis.p()); // Top - createCubeFaceGeos(NCF_Z_NEG, cp[3], cp[2], cp[1], cp[0]);//, m_zNegAxisName, m_zFaceColor, m_textureNegZAxis.p()); // Bottom + createCubeFaceGeos(NCF_Z_POS, cp[4], cp[5], cp[6], cp[7]); + createCubeFaceGeos(NCF_Z_NEG, cp[3], cp[2], cp[1], cp[0]); - createCubeFaceGeos(NCF_X_NEG, cp[3], cp[0], cp[4], cp[7]);//, m_xNegAxisName, m_xFaceColor, m_textureNegXAxis.p()); // left - createCubeFaceGeos(NCF_X_POS, cp[1], cp[2], cp[6], cp[5]);//, m_xPosAxisName, m_xFaceColor, m_texturePosXAxis.p()); // Right + createCubeFaceGeos(NCF_X_NEG, cp[3], cp[0], cp[4], cp[7]); + createCubeFaceGeos(NCF_X_POS, cp[1], cp[2], cp[6], cp[5]); } @@ -440,71 +844,82 @@ void OverlayNavigationCube::createCubeGeos() /// |---|----------|---| /// 1 2 //-------------------------------------------------------------------------------------------------- -void OverlayNavigationCube::createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4)//, const String& name, const Color3f& baseColor, TextureImage* texture) +void OverlayNavigationCube::createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4) { - // Get the orientation vectors for the face -// Vec3f vNormal, vUp, vRight; -// faceOrientation(face, &vNormal, &vUp, &vRight); + Vec2f t1(0,0); + Vec2f t2(1,0); + Vec2f t3(1,1); + Vec2f t4(0,1); float fCornerFactor = 0.175f; - Vec3f p12 = p1 + (p2 - p1)*fCornerFactor; - Vec3f p14 = p1 + (p4 - p1)*fCornerFactor; - Vec3f pi1 = p1 + (p12 - p1) + (p14 - p1); + float fOneMinusCF = 1.0f - fCornerFactor; + Vec3f p12 = p1 + (p2 - p1)*fCornerFactor; Vec2f t12(fCornerFactor, 0); + Vec3f p14 = p1 + (p4 - p1)*fCornerFactor; Vec2f t14(0, fCornerFactor); + Vec3f pi1 = p1 + (p12 - p1) + (p14 - p1); Vec2f ti1(fCornerFactor, fCornerFactor); - Vec3f p21 = p2 + (p1 - p2)*fCornerFactor; - Vec3f p23 = p2 + (p3 - p2)*fCornerFactor; - Vec3f pi2 = p2 + (p21 - p2) + (p23 - p2); + Vec3f p21 = p2 + (p1 - p2)*fCornerFactor; Vec2f t21(fOneMinusCF, 0); + Vec3f p23 = p2 + (p3 - p2)*fCornerFactor; Vec2f t23(1.0, fCornerFactor); + Vec3f pi2 = p2 + (p21 - p2) + (p23 - p2); Vec2f ti2(fOneMinusCF, fCornerFactor); - Vec3f p32 = p3 + (p2 - p3)*fCornerFactor; - Vec3f p34 = p3 + (p4 - p3)*fCornerFactor; - Vec3f pi3 = p3 + (p32 - p3) + (p34 - p3); + Vec3f p32 = p3 + (p2 - p3)*fCornerFactor; Vec2f t32(1.0, fOneMinusCF); + Vec3f p34 = p3 + (p4 - p3)*fCornerFactor; Vec2f t34(fOneMinusCF, 1.0); + Vec3f pi3 = p3 + (p32 - p3) + (p34 - p3); Vec2f ti3(fOneMinusCF, fOneMinusCF); - Vec3f p41 = p4 + (p1 - p4)*fCornerFactor; - Vec3f p43 = p4 + (p3 - p4)*fCornerFactor; - Vec3f pi4 = p4 + (p41 - p4) + (p43 - p4); + Vec3f p41 = p4 + (p1 - p4)*fCornerFactor; Vec2f t41(0, fOneMinusCF); + Vec3f p43 = p4 + (p3 - p4)*fCornerFactor; Vec2f t43(fCornerFactor, 1.0); + Vec3f pi4 = p4 + (p41 - p4) + (p43 - p4); Vec2f ti4(fCornerFactor, fOneMinusCF); // Bottom left m_cubeItemType.push_back(navCubeItem(face, NCFI_BOTTOM_LEFT)); - m_cubeGeos.push_back(createQuadGeo(p1, p12, pi1, p14).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p1, p12, pi1, p14, t1, t12, ti1, t14).p()); // Bottom right m_cubeItemType.push_back(navCubeItem(face, NCFI_BOTTOM_RIGHT)); - m_cubeGeos.push_back(createQuadGeo(p2, p23, pi2, p21).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p2, p23, pi2, p21, t2, t23, ti2, t21).p()); // Top right m_cubeItemType.push_back(navCubeItem(face, NCFI_TOP_RIGHT)); - m_cubeGeos.push_back(createQuadGeo(p3, p34, pi3, p32).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p3, p34, pi3, p32, t3, t34, ti3, t32).p()); // Top left m_cubeItemType.push_back(navCubeItem(face, NCFI_TOP_LEFT)); - m_cubeGeos.push_back(createQuadGeo(p4, p41, pi4, p43).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p4, p41, pi4, p43, t4, t41, ti4, t43).p()); // Bottom m_cubeItemType.push_back(navCubeItem(face, NCFI_BOTTOM)); - m_cubeGeos.push_back(createQuadGeo(p12, p21, pi2, pi1).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p12, p21, pi2, pi1, t12, t21, ti2, ti1).p()); // Top m_cubeItemType.push_back(navCubeItem(face, NCFI_TOP)); - m_cubeGeos.push_back(createQuadGeo(p34, p43, pi4, pi3).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p34, p43, pi4, pi3, t34, t43, ti4, ti3).p()); // Right m_cubeItemType.push_back(navCubeItem(face, NCFI_RIGHT)); - m_cubeGeos.push_back(createQuadGeo(p23, p32, pi3, pi2).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p23, p32, pi3, pi2, t23, t32, ti3, ti2).p()); // Left m_cubeItemType.push_back(navCubeItem(face, NCFI_LEFT)); - m_cubeGeos.push_back(createQuadGeo(p41, p14, pi1, pi4).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p41, p14, pi1, pi4, t41, t14, ti1, ti4).p()); // Inner part m_cubeItemType.push_back(navCubeItem(face, NCFI_CENTER)); - m_cubeGeos.push_back(createQuadGeo(pi1, pi2, pi3, pi4).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(pi1, pi2, pi3, pi4, ti1, ti2, ti3, ti4).p()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -ref OverlayNavigationCube::createQuadGeo(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4) +ref OverlayNavigationCube::createQuadGeo(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4, const Vec2f& t1, const Vec2f& t2, const Vec2f& t3, const Vec2f& t4) { ref geo = new DrawableGeo; @@ -514,7 +929,14 @@ ref OverlayNavigationCube::createQuadGeo(const Vec3f& v1, const Vec vertexArray->set(2, v3); vertexArray->set(3, v4); + ref textureCoordArray = new Vec2fArray(4); + textureCoordArray->set(0, t1); + textureCoordArray->set(1, t2); + textureCoordArray->set(2, t3); + textureCoordArray->set(3, t4); + geo->setVertexArray(vertexArray.p()); + geo->setTextureCoordArray(textureCoordArray.p()); ref indices = new cvf::UShortArray(6); indices->set(0, 0); @@ -527,6 +949,7 @@ ref OverlayNavigationCube::createQuadGeo(const Vec3f& v1, const Vec ref primSet = new cvf::PrimitiveSetIndexedUShort(cvf::PT_TRIANGLES); primSet->setIndices(indices.p()); geo->addPrimitiveSet(primSet.p()); + geo->computeNormals(); return geo; } @@ -560,11 +983,9 @@ void OverlayNavigationCube::navCubeCornerPoints(Vec3f points[8]) } -/************************************************************************************************* - *//** - * Convert face + faceItem to VTNavCubeItem - * - *************************************************************************************************/ +//-------------------------------------------------------------------------------------------------- +/// Convert face + faceItem to NavCubeItem +//-------------------------------------------------------------------------------------------------- OverlayNavigationCube::NavCubeItem OverlayNavigationCube::navCubeItem(NavCubeFace face, NavCubeFaceItem faceItem) const { NavCubeItem item = NCI_NONE; @@ -673,12 +1094,6 @@ OverlayNavigationCube::NavCubeItem OverlayNavigationCube::navCubeItem(NavCubeFac } break; } - - case NCF_NONE: - { - CVF_FAIL_MSG("Illegal nav cube face specified"); - break; - } } return item; @@ -688,38 +1103,449 @@ OverlayNavigationCube::NavCubeItem OverlayNavigationCube::navCubeItem(NavCubeFac //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void OverlayNavigationCube::faceOrientation(NavCubeFace face, Vec3f* normal, Vec3f* upVector, Vec3f* rightVector) const +bool OverlayNavigationCube::pick(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size) { - CVF_ASSERT(normal && upVector && rightVector); - - switch (face) - { - case NCF_X_POS: *normal = Vec3f::X_AXIS; break; - case NCF_X_NEG: *normal = -Vec3f::X_AXIS; break; - case NCF_Y_POS: *normal = Vec3f::Y_AXIS; break; - case NCF_Y_NEG: *normal = -Vec3f::Y_AXIS; break; - case NCF_Z_POS: *normal = Vec3f::Z_AXIS; break; - case NCF_Z_NEG: *normal = -Vec3f::Z_AXIS; break; - case NCF_NONE: CVF_FAIL_MSG("Illegal nav cube face"); break; - } - - if ((*normal)*m_upVector == 0.0) - { - if (*normal == m_upVector) *upVector = -m_frontVector; - else *upVector = m_frontVector; - } - else - { - *upVector = m_upVector; - } - - *rightVector = *upVector^*normal; - - normal->normalize(); - upVector->normalize(); - rightVector->normalize(); + return pickItem(winCoordX, winCoordY, position, size) != cvf::UNDEFINED_UINT; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool OverlayNavigationCube::updateHighlight(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size) +{ + // Early out + if (winCoordX < position.x() || winCoordX > (position.x() + static_cast(size.x())) || + winCoordY < position.y() || winCoordY > (position.y() + static_cast(size.y()))) + { + bool redraw = m_hightlightItem != NCI_NONE; + m_hightlightItem = NCI_NONE; + return redraw; + } + + NavCubeItem item2d = pick2dItem(winCoordX, winCoordY, position, size); + if (item2d != NCI_NONE) + { + bool redraw = m_hightlightItem != item2d; + m_hightlightItem = item2d; + return redraw; + } + + size_t itemIndex = pickItem(winCoordX, winCoordY, position, size); + + bool redraw = false; + + if (itemIndex == cvf::UNDEFINED_SIZE_T) + { + if (m_hightlightItem != NCI_NONE) + { + m_hightlightItem = NCI_NONE; + redraw = true; + } + } + else + { + if (m_hightlightItem != m_cubeItemType[itemIndex]) + { + m_hightlightItem = m_cubeItemType[itemIndex]; + redraw = true; + } + } + + return redraw; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool OverlayNavigationCube::processSelection(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size, Vec3d* viewDir, Vec3d* up) +{ + *viewDir = Vec3d::UNDEFINED; + *up = Vec3d::UNDEFINED; + + NavCubeItem faceItem = pick2dItem(winCoordX, winCoordY, position, size); + + if (faceItem == NCI_NONE) + { + size_t minIndex = pickItem(winCoordX, winCoordY, position, size); + + if (minIndex == cvf::UNDEFINED_SIZE_T) + { + return false; + } + + faceItem = m_cubeItemType[minIndex]; + } + + if (faceItem == NCI_NONE) + { + return false; + } + + viewConfigurationFromNavCubeItem(faceItem, viewDir, up); + + return true; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t OverlayNavigationCube::pickItem(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size) +{ + Camera cam; + configureLocalCamera(&cam, position, size); + + ref ray = cam.rayFromWindowCoordinates(winCoordX, winCoordY); + + double minDistSq = cvf::UNDEFINED_DOUBLE_THRESHOLD; + size_t minIndex = cvf::UNDEFINED_SIZE_T; + + for (size_t i = 0; i < m_cubeGeos.size(); ++i) + { + Vec3d intersectionPoint; + ref detail; + if (m_cubeGeos[i]->rayIntersectCreateDetail(*ray, &intersectionPoint, &detail)) + { + double distSq = ray->origin().pointDistanceSquared(intersectionPoint); + + if (distSq < minDistSq) + { + minDistSq = distSq; + minIndex = i; + } + } + } + + return minIndex; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +OverlayNavigationCube::NavCubeItem OverlayNavigationCube::pick2dItem(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size) +{ + Vec2f vpOrigin; + vpOrigin.x() = static_cast(position.x()) + static_cast(size.x())*0.5f; + vpOrigin.y() = static_cast(position.y()) + static_cast(size.y())*0.5f; + + Vec2f relCoord; + relCoord.x() = (static_cast(winCoordX) - vpOrigin.x())/(static_cast(size.x())*0.5f); + relCoord.y() = (static_cast(winCoordY) - vpOrigin.y())/(static_cast(size.y())*0.5f); + + // Check for home + Rectf home(-0.97f, 0.76f, 0.21f, 0.24f); + if (home.contains(relCoord)) return NCI_HOME; + + if (isFaceAlignedViewPoint()) + { + float fEnd = 0.9f; + float fStart = 0.7f; + float fWidth = 0.12f; + + Rectf leftArrow(-fEnd, -fWidth, 0.2f, 2*fWidth); + Rectf rightArrow(fStart, -fWidth, 0.2f, 2*fWidth); + Rectf topArrow(-fWidth, fStart, 2*fWidth, 0.2f); + Rectf bottomArrow(-fWidth, -fEnd, 2*fWidth, 0.2f); + Rectf rotateCW(0.75f, 0.49f, 0.12f, 0.16f); + Rectf rotateCCW(0.59f, 0.70f, 0.12f, 0.16f); + + if (leftArrow.contains(relCoord)) return NCI_ARROW_LEFT; + else if (rightArrow.contains(relCoord)) return NCI_ARROW_RIGHT; + else if (topArrow.contains(relCoord)) return NCI_ARROW_TOP; + else if (bottomArrow.contains(relCoord)) return NCI_ARROW_BOTTOM; + else if (rotateCW.contains(relCoord)) return NCI_ROTATE_CW; + else if (rotateCCW.contains(relCoord)) return NCI_ROTATE_CCW; + } + + return NCI_NONE; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::configureLocalCamera(Camera* camera, const Vec2i& position, const Vec2ui& size) +{ + // Position the camera far enough away to make the axis and the text fit within the viewport + Mat4d axisMatrix = m_camera->viewMatrix(); + axisMatrix.setTranslation(Vec3d(0, 0, -2.0)); + + // Setup camera + camera->setProjectionAsPerspective(40.0, 0.05, 100.0); + camera->setViewMatrix(axisMatrix); + camera->setViewport(position.x(), position.y(), size.x(), size.y()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::viewConfigurationFromNavCubeItem(NavCubeItem item, Vec3d* viewDir, Vec3d* up) +{ + // Handle Home and Rotate specially, as they do not fall into the simple "view from" category + if (item == NCI_HOME) + { + *viewDir = m_homeViewDirection; + *up = m_homeUp; + return; + } + else if ((item == NCI_ROTATE_CW) || (item == NCI_ROTATE_CCW)) + { + *viewDir = m_camera->direction(); + *up = m_camera->up(); + + Mat4d mat = Mat4d::fromRotation(*viewDir, Math::toRadians(item == NCI_ROTATE_CW ? -90.0 : 90.0)); + up->transformVector(mat); + + return; + } + + // Determine the view from point based on the VTNavCubeItem + Vec3d viewFrom; + + switch(item) + { + case NCI_ARROW_LEFT: + case NCI_ARROW_RIGHT: + case NCI_ARROW_TOP: + case NCI_ARROW_BOTTOM: + { + Vec3d currentViewDir = m_camera->direction(); + Vec3d currentUp = m_camera->up(); + Vec3d rightVec = currentViewDir^currentUp; + + if (item == NCI_ARROW_LEFT) viewFrom = -rightVec; + else if (item == NCI_ARROW_RIGHT) viewFrom = rightVec; + else if (item == NCI_ARROW_TOP) viewFrom = currentUp; + else if (item == NCI_ARROW_BOTTOM) viewFrom = -currentUp; + break; + } + case NCI_CORNER_XN_YN_ZN: viewFrom = Vec3d(-1, -1, -1); break; + case NCI_CORNER_XP_YN_ZN: viewFrom = Vec3d( 1, -1, -1); break; + case NCI_CORNER_XP_YP_ZN: viewFrom = Vec3d( 1, 1, -1); break; + case NCI_CORNER_XN_YP_ZN: viewFrom = Vec3d(-1, 1, -1); break; + case NCI_CORNER_XN_YN_ZP: viewFrom = Vec3d(-1, -1, 1); break; + case NCI_CORNER_XP_YN_ZP: viewFrom = Vec3d( 1, -1, 1); break; + case NCI_CORNER_XP_YP_ZP: viewFrom = Vec3d( 1, 1, 1); break; + case NCI_CORNER_XN_YP_ZP: viewFrom = Vec3d(-1, 1, 1); break; + case NCI_EDGE_YN_ZN: viewFrom = Vec3d( 0, -1, -1); break; + case NCI_EDGE_XP_ZN: viewFrom = Vec3d( 1, 0, -1); break; + case NCI_EDGE_YP_ZN: viewFrom = Vec3d( 0, 1, -1); break; + case NCI_EDGE_XN_ZN: viewFrom = Vec3d(-1, 0, -1); break; + case NCI_EDGE_YN_ZP: viewFrom = Vec3d( 0, -1, 1); break; + case NCI_EDGE_XP_ZP: viewFrom = Vec3d( 1, 0, 1); break; + case NCI_EDGE_YP_ZP: viewFrom = Vec3d( 0, 1, 1); break; + case NCI_EDGE_XN_ZP: viewFrom = Vec3d(-1, 0, 1); break; + case NCI_EDGE_XN_YN: viewFrom = Vec3d(-1, -1, 0); break; + case NCI_EDGE_XP_YN: viewFrom = Vec3d( 1, -1, 0); break; + case NCI_EDGE_XP_YP: viewFrom = Vec3d( 1, 1, 0); break; + case NCI_EDGE_XN_YP: viewFrom = Vec3d(-1, 1, 0); break; + case NCI_FACE_X_POS: viewFrom = Vec3d( 1, 0, 0); break; + case NCI_FACE_X_NEG: viewFrom = Vec3d(-1, 0, 0); break; + case NCI_FACE_Y_POS: viewFrom = Vec3d( 0, 1, 0); break; + case NCI_FACE_Y_NEG: viewFrom = Vec3d( 0, -1, 0); break; + case NCI_FACE_Z_POS: viewFrom = Vec3d( 0, 0, 1); break; + case NCI_FACE_Z_NEG: viewFrom = Vec3d( 0, 0, -1); break; + case NCI_NONE: + case NCI_HOME: + case NCI_ROTATE_CW: + case NCI_ROTATE_CCW: + default: CVF_ASSERT(0); break; + } + + *viewDir = Vec3d::ZERO - viewFrom; + + // Find the new up vector + *up = computeNewUpVector(viewFrom, m_camera->up()); +} + + +//-------------------------------------------------------------------------------------------------- +/// Find the new up vector +//-------------------------------------------------------------------------------------------------- +Vec3d OverlayNavigationCube::computeNewUpVector(const Vec3d& viewFrom, const Vec3d currentUp) const +{ + Vec3d upVector = currentUp; + upVector.normalize(); + + // Snap to axis before rotate, give priority to Z axis if equal + upVector = snapToAxis(upVector, &Vec3d::Z_AXIS); + + Vec3d currentUpVectorSnapped = upVector; + Vec3d viewDir = -viewFrom; + + // New approach: + Vec3d currentViewDir = m_camera->direction(); + Vec3d rotAxis; + + if (vectorsParallelFuzzy(currentViewDir, viewDir)) + { + // The current and new dirs are parallel, just use the up vector as it is perpendicular to the view dir + rotAxis = currentUp; + } + else + { + rotAxis = currentViewDir^viewDir; + } + + rotAxis.normalize(); + + // Guard acos against out-of-domain input + const double dotProduct = Math::clamp(currentViewDir*viewDir, -1.0, 1.0); + const double angle = Math::acos(dotProduct); + Mat4d rotMat = Mat4d::fromRotation(rotAxis, angle); + upVector.transformVector(rotMat); + + // Snap to closest axis + if (cvf::Math::abs(upVector*currentUpVectorSnapped) > 0.01) + { + upVector = currentUpVectorSnapped; + } + else + { + upVector = snapToAxis(upVector, ¤tUpVectorSnapped); + } + + if (vectorsParallelFuzzy(upVector, viewDir)) + { + // The found up vector and view dir are parallel, select another axis based on the current up vector + if (vectorsParallelFuzzy(Vec3d::Z_AXIS, viewDir)) + { + if (cvf::Math::abs(currentUp.y()) >= cvf::Math::abs(currentUp.x())) upVector = (currentUp.y() >= 0.0f) ? Vec3d::Y_AXIS : -Vec3d::Y_AXIS; + else upVector = (currentUp.x() >= 0.0f) ? Vec3d::X_AXIS : -Vec3d::X_AXIS; + } + else if (vectorsParallelFuzzy(Vec3d::Y_AXIS, viewDir)) + { + if (cvf::Math::abs(currentUp.x()) >= cvf::Math::abs(currentUp.z())) upVector = (currentUp.x() >= 0.0f) ? Vec3d::X_AXIS : -Vec3d::X_AXIS; + else upVector = (currentUp.z() >= 0.0f) ? Vec3d::Z_AXIS : -Vec3d::Z_AXIS; + } + else + { + if (cvf::Math::abs(currentUp.y()) >= cvf::Math::abs(currentUp.z())) upVector = (currentUp.y() >= 0.0f) ? Vec3d::Y_AXIS : -Vec3d::Y_AXIS; + else upVector = (currentUp.z() >= 0.0f) ? Vec3d::Z_AXIS : -Vec3d::Z_AXIS; + } + } + + return upVector; +} + + +//-------------------------------------------------------------------------------------------------- +/// Static +//-------------------------------------------------------------------------------------------------- +Vec3d OverlayNavigationCube::snapToAxis(const Vec3d& vector, const Vec3d* pPreferIfEqual) +{ + // Snap to closest axis + int closestAxis = findClosestAxis(vector); + + if (pPreferIfEqual) + { + int closestPreferAxis = findClosestAxis(*pPreferIfEqual); + + if (closestAxis != closestPreferAxis) + { + if (cvf::Math::abs(cvf::Math::abs(vector[closestAxis]) - cvf::Math::abs(vector[closestPreferAxis])) < 0.01) + { + closestAxis = closestPreferAxis; + } + } + } + + Vec3d snapVector = vector; + + if (closestAxis == 0) snapVector = vector.x() >= 0.0f ? Vec3d::X_AXIS : -Vec3d::X_AXIS; + if (closestAxis == 1) snapVector = vector.y() >= 0.0f ? Vec3d::Y_AXIS : -Vec3d::Y_AXIS; + if (closestAxis == 2) snapVector = vector.z() >= 0.0f ? Vec3d::Z_AXIS : -Vec3d::Z_AXIS; + + return snapVector; +} + + +//-------------------------------------------------------------------------------------------------- +/// Static +//-------------------------------------------------------------------------------------------------- +bool OverlayNavigationCube::vectorsParallelFuzzy(Vec3d v1, Vec3d v2) +{ + v1.normalize(); + v2.normalize(); + if (cvf::Math::abs(v1*v2) < 0.999f) return false; + + return true; +} + + +//-------------------------------------------------------------------------------------------------- +/// Static +//-------------------------------------------------------------------------------------------------- +int OverlayNavigationCube::findClosestAxis(const Vec3d& vector) +{ + int retAxis = 0; + double largest = cvf::Math::abs(vector.x()); + + if (cvf::Math::abs(vector.y()) > largest) + { + largest = cvf::Math::abs(vector.y()); + retAxis = 1; + } + + if (cvf::Math::abs(vector.z()) > largest) + { + retAxis = 2; + } + + return retAxis; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::setFaceTexture(NavCubeFace face, TextureImage* texture) +{ + m_faceTextures[face] = texture; + m_faceTextureBindings.clear(); +} + + +//-------------------------------------------------------------------------------------------------- +/// Check if the current view dir is aligned with a face (principal axis) +//-------------------------------------------------------------------------------------------------- +bool OverlayNavigationCube::isFaceAlignedViewPoint() const +{ + Vec3d viewDir = m_camera->direction().getNormalized(); + Vec3d upVector = m_camera->up().getNormalized(); + + // First check up vector + float fThreshold = 0.999f; + if ((Math::abs(upVector*Vec3d::X_AXIS) < fThreshold) && + (Math::abs(upVector*Vec3d::Y_AXIS) < fThreshold) && + (Math::abs(upVector*Vec3d::Z_AXIS) < fThreshold)) + { + return false; + } + + if (viewDir*Vec3d::X_AXIS > fThreshold) return true; + else if (viewDir*Vec3d::X_AXIS < -fThreshold) return true; + else if (viewDir*Vec3d::Y_AXIS > fThreshold) return true; + else if (viewDir*Vec3d::Y_AXIS < -fThreshold) return true; + else if (viewDir*Vec3d::Z_AXIS > fThreshold) return true; + else if (viewDir*Vec3d::Z_AXIS < -fThreshold) return true; + + return false; +} + + +//-------------------------------------------------------------------------------------------------- +/// Set the "home" camera angle, which is used when the user presses the house 2d item +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::setHome(const Vec3d& viewDirection, const Vec3d& up) +{ + m_homeViewDirection = viewDirection; + m_homeUp = up; +} + } // namespace cvf diff --git a/VisualizationModules/LibRender/cvfOverlayNavigationCube.h b/VisualizationModules/LibRender/cvfOverlayNavigationCube.h index e878ecf9ce..1a5750f47d 100644 --- a/VisualizationModules/LibRender/cvfOverlayNavigationCube.h +++ b/VisualizationModules/LibRender/cvfOverlayNavigationCube.h @@ -26,6 +26,8 @@ #include "cvfBoundingBox.h" #include "cvfCollection.h" +#include + namespace cvf { class Camera; @@ -35,7 +37,7 @@ class Font; class ShaderProgram; class MatrixState; class TextureImage; - +class RenderState; //================================================================================================== // @@ -45,8 +47,8 @@ class TextureImage; class OverlayNavigationCube: public OverlayItem { public: - enum NavCubeFace { - NCF_NONE, + enum NavCubeFace + { NCF_X_POS, NCF_X_NEG, NCF_Y_POS, @@ -55,8 +57,31 @@ public: NCF_Z_NEG }; - // Note that the order of the items starting at the VT_NCFI_BOTTOM_LEFT is important (in a CCW order) - enum NavCubeFaceItem { +public: + OverlayNavigationCube(Camera* camera, Font* font); + ~OverlayNavigationCube(); + + virtual Vec2ui sizeHint(); + virtual Vec2ui maximumSize(); + virtual Vec2ui minimumSize(); + + virtual void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size); + virtual void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size); + virtual bool pick(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size); + + bool updateHighlight(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size); + bool processSelection(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size, Vec3d* viewDir, Vec3d* up); + + void setSize(const Vec2ui& size); + void setHome(const Vec3d& viewDirection, const Vec3d& up); + void setAxisLabels(const String& xLabel, const String& yLabel, const String& zlabel); + void setAxisLabelsColor(const Color3f& color); + void setFaceTexture(NavCubeFace face, TextureImage* texture); + +private: + // Note that the order of the items starting at the NCFI_BOTTOM_LEFT is important (in a CCW order) + enum NavCubeFaceItem + { NCFI_NONE, NCFI_CENTER, NCFI_BOTTOM_LEFT, @@ -111,77 +136,76 @@ public: NCI_ROTATE_CCW }; -public: - OverlayNavigationCube(Camera* camera, Font* font); - ~OverlayNavigationCube(); +private: + void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software); + void createAxisGeometry(bool software); + void renderAxis(OpenGLContext* oglContext, const MatrixState& matrixState); + void renderAxisImmediateMode(OpenGLContext* oglContext, const MatrixState& matrixState); + void renderAxisLabels(OpenGLContext* oglContext, bool software, const MatrixState& matrixState); + void renderCubeGeos(OpenGLContext* oglContext, bool software, const MatrixState& matrixState); + void render2dItems(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software); - virtual Vec2ui sizeHint(); - virtual Vec2ui maximumSize(); - virtual Vec2ui minimumSize(); + void createCubeGeos(); + void createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4); + ref createQuadGeo(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4, const Vec2f& t1, const Vec2f& t2, const Vec2f& t3, const Vec2f& t4); + void navCubeCornerPoints(Vec3f points[8]); + void create2dGeos(); + ref create2dArrow(const Vec3f& start, const Vec3f& end); - virtual void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size); - virtual void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size); + NavCubeItem navCubeItem(NavCubeFace face, NavCubeFaceItem item) const; - void setSize(const Vec2ui& size); - void updateHighlight(int winCoordX, int winCoordY); - void processSelection(int winCoordX, int winCoordY, const BoundingBox& boundingBox, Vec3d* eye, Vec3d* viewDirection); + void configureLocalCamera(Camera* camera, const Vec2i& position, const Vec2ui& size); - void setAxisLabels(const String& xLabel, const String& yLabel, const String& zlabel); - void setAxisLabelsColor(const Color3f& color); + void viewConfigurationFromNavCubeItem(NavCubeItem item, Vec3d* viewDir, Vec3d* up); + Vec3d computeNewUpVector(const Vec3d& viewFrom, const Vec3d currentUp) const; + + size_t pickItem(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size); + NavCubeItem pick2dItem(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size); + + void updateTextureBindings(OpenGLContext* oglContext, bool software); + bool isFaceAlignedViewPoint() const; + + static Vec3d snapToAxis(const Vec3d& vector, const Vec3d* pPreferIfEqual = NULL); + static bool vectorsParallelFuzzy(Vec3d v1, Vec3d v2); + static int findClosestAxis(const Vec3d& vector); private: - void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software, const Mat4d& viewMatrix); - void createAxisGeometry(bool software); - void renderAxis(OpenGLContext* oglContext, const MatrixState& matrixState); - void renderAxisImmediateMode(OpenGLContext* oglContext, const MatrixState& matrixState); - void renderAxisLabels(OpenGLContext* oglContext, bool software, const MatrixState& matrixState); - void renderCubeGeos(OpenGLContext* oglContext, bool software, const MatrixState& matrixState); + ref m_camera; // This camera's view matrix will be used to orient the axis cross + ref m_font; + String m_xLabel; // Label to display on x axis, default 'x' + String m_yLabel; + String m_zLabel; + Color3f m_textColor; // Text color - void createCubeGeos(); - void createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4);//, const String& name, const Color3f& baseColor, TextureImage* texture); - void navCubeCornerPoints(Vec3f points[8]); - ref createQuadGeo(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4); + Vec2ui m_size; // Pixel size of the nav cube area - NavCubeItem navCubeItem(NavCubeFace face, NavCubeFaceItem item) const; - void faceOrientation(NavCubeFace face, Vec3f* normal, Vec3f* upVector, Vec3f* rightVector) const; + Vec3d m_homeViewDirection; + Vec3d m_homeUp; -private: - ref m_camera; // This camera's view matrix will be used to orient the axis cross - String m_xLabel; // Label to display on x axis, default 'x' - String m_yLabel; - String m_zLabel; - Color3f m_textColor; // Text color - ref m_font; + Collection m_cubeGeos; // These arrays have the same length + std::vector m_cubeItemType; // These arrays have the same length + std::vector m_cubeGeoFace; // These arrays have the same length - Vec2ui m_size; // Pixel size of the axis area + ref m_homeGeo; // These arrays have the same length + Collection m_2dGeos; // These arrays have the same length + std::vector m_2dItemType; - Collection m_cubeGeos; - std::vector m_cubeItemType; ref m_cubeGeoShader; + ref m_cubeGeoTextureShader; ref m_axis; - NavCubeItem m_hightlightItem; ///< The currently highlighted cube item (face, corner, edge, buttons) - Vec3f m_upVector; ///< Specify the up vector, which is used for the orientation of the text and textures on the faces - Vec3f m_frontVector; ///< Specify the front vector, which is used for the orientation of the top and bottom faces + NavCubeItem m_hightlightItem; ///< The currently highlighted cube item (face, corner, edge, buttons) + Vec3f m_upVector; ///< Specify the up vector, which is used for the orientation of the text and textures on the faces + Vec3f m_frontVector; ///< Specify the front vector, which is used for the orientation of the top and bottom faces - String m_xPosAxisName; ///< The name of the X_POS face - String m_xNegAxisName; ///< The name of the X_NEG face - String m_yPosAxisName; ///< The name of the Y_POS face - String m_yNegAxisName; ///< The name of the Y_NEG face - String m_zPosAxisName; ///< The name of the Z_POS face - String m_zNegAxisName; ///< The name of the Z_NEG face + Color3f m_xFaceColor; ///< The color of the X_POS and X_NEG faces + Color3f m_yFaceColor; ///< The color of the Y_POS and Y_NEG faces + Color3f m_zFaceColor; ///< The color of the Z_POS and Z_NEG faces + Color3f m_itemHighlightColor; + Color3f m_2dItemsColor; - ref m_texturePosXAxis; ///< The texture to draw on the X_POS face. If NULL, the specified text will be drawn. - ref m_textureNegXAxis; ///< The texture to draw on the X_NEG face. If NULL, the specified text will be drawn. - ref m_texturePosYAxis; ///< The texture to draw on the Y_POS face. If NULL, the specified text will be drawn. - ref m_textureNegYAxis; ///< The texture to draw on the Y_NEG face. If NULL, the specified text will be drawn. - ref m_texturePosZAxis; ///< The texture to draw on the Z_POS face. If NULL, the specified text will be drawn. - ref m_textureNegZAxis; ///< The texture to draw on the Z_NEG face. If NULL, the specified text will be drawn. - - Color3f m_xFaceColor; ///< The color of the X_POS and X_NEG faces - Color3f m_yFaceColor; ///< The color of the Y_POS and Y_NEG faces - Color3f m_zFaceColor; ///< The color of the Z_POS and Z_NEG faces + std::map > m_faceTextures; + std::map > m_faceTextureBindings; }; } - diff --git a/VisualizationModules/LibRender/cvfOverlayScalarMapperLegend.cpp b/VisualizationModules/LibRender/cvfOverlayScalarMapperLegend.cpp index 93ea5c99a6..f5b649083e 100644 --- a/VisualizationModules/LibRender/cvfOverlayScalarMapperLegend.cpp +++ b/VisualizationModules/LibRender/cvfOverlayScalarMapperLegend.cpp @@ -686,7 +686,14 @@ void OverlayScalarMapperLegend::layoutInfo(OverlayColorLegendLayoutInfo* layout) if (m_scalarMapper.isNull()) t = 0; else t = m_scalarMapper->normalizedValue(m_tickValues[i]); t = Math::clamp(t, 0.0, 1.1); - layout->tickPixelPos->set(i, t*layout->legendRect.height()); + if (i != numTicks -1) + { + layout->tickPixelPos->set(i, t*layout->legendRect.height()); + } + else + { + layout->tickPixelPos->set(i, layout->legendRect.height()); // Make sure we get a value at the top even if the scalarmapper range is zero + } } } diff --git a/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.cpp b/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.cpp index e3c8fd53a8..8cccdcae42 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.cpp +++ b/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.cpp @@ -22,6 +22,7 @@ #include "cvfMath.h" #include "cvfTextureImage.h" #include +#include namespace cvf { @@ -34,6 +35,9 @@ namespace cvf { /// Configured by specifying a number of level colors and a min/max range. //================================================================================================== ScalarMapperContinuousLog::ScalarMapperContinuousLog() + : m_hasNegativeRange(false), + m_logRange(0.0), + m_logRangeMin(0.0) { } @@ -43,17 +47,16 @@ ScalarMapperContinuousLog::ScalarMapperContinuousLog() //-------------------------------------------------------------------------------------------------- double ScalarMapperContinuousLog::normalizedValue(double scalarValue) const { - double logRangeMax = log10(m_rangeMax); - double logRangeMin = log10(m_rangeMin); - double logRange = logRangeMax - logRangeMin; + if (m_hasNegativeRange) scalarValue = -1.0*scalarValue; + double logValue; - - if (scalarValue <= 0) logValue = logRangeMin; + + if (scalarValue <= 0) logValue = std::numeric_limits::min_exponent10; else logValue = log10(scalarValue); - if (logRange != 0) + if (m_logRange != 0) { - return cvf::Math::clamp((logValue - logRangeMin)/logRange, 0.0, 1.0); + return cvf::Math::clamp((logValue - m_logRangeMin)/m_logRange, 0.0, 1.0); } else { @@ -66,13 +69,37 @@ double ScalarMapperContinuousLog::normalizedValue(double scalarValue) const //-------------------------------------------------------------------------------------------------- double ScalarMapperContinuousLog::domainValue(double normalizedPosition) const { - double logRangeMax = log10(m_rangeMax); - double logRangeMin = log10(m_rangeMin); - double logRange = logRangeMax - logRangeMin; + double logValue = normalizedPosition*m_logRange + m_logRangeMin; + double domainVal = pow(10, logValue); - double logValue = normalizedPosition*logRange + logRangeMin; - - return pow(10, logValue); + if (m_hasNegativeRange) + domainVal *= -1.0; + + return domainVal; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void ScalarMapperContinuousLog::rangeUpdated() +{ + m_hasNegativeRange = false; + + double transformedRangeMax = m_rangeMax; + double transformedRangeMin = m_rangeMin; + + if ( m_rangeMax <= 0 && m_rangeMin <= 0) + { + m_hasNegativeRange = true; + + transformedRangeMax = -1.0*transformedRangeMax; + transformedRangeMin = -1.0*transformedRangeMin; + } + + double logRangeMax = (transformedRangeMax > 0) ? log10(transformedRangeMax): std::numeric_limits::min_exponent10; + m_logRangeMin = (transformedRangeMin > 0) ? log10(transformedRangeMin): std::numeric_limits::min_exponent10; + + m_logRange = logRangeMax - m_logRangeMin; } } // namespace cvf diff --git a/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.h b/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.h index 72a1b62d80..eda29b7339 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.h +++ b/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.h @@ -38,6 +38,15 @@ public: virtual double normalizedValue( double domainValue ) const; virtual double domainValue( double normalizedPosition ) const; + + // +protected: + virtual void rangeUpdated(); + +private: + double m_logRange; + double m_logRangeMin; + bool m_hasNegativeRange; }; } diff --git a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.cpp b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.cpp index 6af6569e9e..febea0c299 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.cpp +++ b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.cpp @@ -41,7 +41,7 @@ ScalarMapperDiscreteLinear::ScalarMapperDiscreteLinear() //-------------------------------------------------------------------------------------------------- Vec2f ScalarMapperDiscreteLinear::mapToTextureCoord(double scalarValue) const { - double discVal = discretize(scalarValue); + double discVal = discretize(scalarValue, m_sortedLevels); return ScalarMapperRangeBased::mapToTextureCoord(discVal); } @@ -50,20 +50,20 @@ Vec2f ScalarMapperDiscreteLinear::mapToTextureCoord(double scalarValue) const //-------------------------------------------------------------------------------------------------- Color3ub ScalarMapperDiscreteLinear::mapToColor(double scalarValue) const { - double discVal = discretize(scalarValue); + double discVal = discretize(scalarValue, m_sortedLevels); return ScalarMapperRangeBased::mapToColor(discVal); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double ScalarMapperDiscreteLinear::discretize(double scalarValue) const +double ScalarMapperDiscreteLinear::discretize(double scalarValue, const std::set& sortedLevels) { std::set::iterator it; - it = m_sortedLevels.upper_bound(scalarValue); - if (it == m_sortedLevels.begin()) return (*it); - if (it == m_sortedLevels.end()) return (*m_sortedLevels.rbegin()); + it = sortedLevels.upper_bound(scalarValue); + if (it == sortedLevels.begin()) return (*it); + if (it == sortedLevels.end()) return (*sortedLevels.rbegin()); double upperValue = *it; it--; double lowerValue = *it; diff --git a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.h b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.h index 824fe00946..da8fcb5fd9 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.h +++ b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.h @@ -23,6 +23,7 @@ namespace cvf { + class ScalarMapperDiscreteLog; //================================================================================================== // // Maps scalar values to texture coordinates/colors @@ -42,8 +43,8 @@ public: virtual double domainValue( double normalizedPosition ) const; private: - double discretize(double scalarValue) const; - + static double discretize(double scalarValue, const std::set& sortedLevels); + friend class ScalarMapperDiscreteLog; }; } diff --git a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.cpp b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.cpp index 0ee3cbabd6..48e1adb274 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.cpp +++ b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.cpp @@ -18,6 +18,7 @@ //################################################################################################## #include "cvfScalarMapperDiscreteLog.h" +#include "cvfScalarMapperDiscreteLinear.h" #include #include "cvfMath.h" @@ -31,42 +32,87 @@ namespace cvf { /// Maps scalar values to texture coordinates/colors using discrete logarithmic mapping //================================================================================================== +ScalarMapperDiscreteLog::ScalarMapperDiscreteLog() +{ + m_decadeLevelCount = 2; +} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double ScalarMapperDiscreteLog::normalizedValue(double domainScalarValue) const +Vec2f ScalarMapperDiscreteLog::mapToTextureCoord(double scalarValue) const { - double logRangeMax = log10(m_rangeMax); - double logRangeMin = log10(m_rangeMin); - double logRange = logRangeMax - logRangeMin; + double discVal = ScalarMapperDiscreteLinear::discretize(scalarValue, m_sortedLevels); + return ScalarMapperRangeBased::mapToTextureCoord(discVal); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Color3ub ScalarMapperDiscreteLog::mapToColor(double scalarValue) const +{ + double discVal = ScalarMapperDiscreteLinear::discretize(scalarValue, m_sortedLevels); + return ScalarMapperRangeBased::mapToColor(discVal); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double ScalarMapperDiscreteLog::normalizedValue(double scalarValue) const +{ + if (m_hasNegativeRange) scalarValue = -1.0*scalarValue; + double logValue; - if (domainScalarValue <= 0) logValue = logRangeMin; - else logValue = log10(domainScalarValue); + if (scalarValue <= 0) logValue = std::numeric_limits::min_exponent10; + else logValue = log10(scalarValue); - if (logRange != 0) + if (m_logRange != 0) { - return cvf::Math::clamp((logValue - logRangeMin)/logRange, 0.0, 1.0); + return cvf::Math::clamp((logValue - m_logRangeMin)/m_logRange, 0.0, 1.0); } else { return 0; } -} +} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double ScalarMapperDiscreteLog::domainValue(double normalizedPosition) const { - double logRangeMax = log10(m_rangeMax); - double logRangeMin = log10(m_rangeMin); - double logRange = logRangeMax - logRangeMin; + double logValue = normalizedPosition*m_logRange + m_logRangeMin; + double domainVal = pow(10, logValue); - double logValue = normalizedPosition*logRange + logRangeMin; + if (m_hasNegativeRange) + domainVal *= -1.0; - return pow(10, logValue); + return domainVal; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void ScalarMapperDiscreteLog::rangeUpdated() +{ + m_hasNegativeRange = false; + + double transformedRangeMax = m_rangeMax; + double transformedRangeMin = m_rangeMin; + + if ( m_rangeMax <= 0 && m_rangeMin <= 0) + { + m_hasNegativeRange = true; + + transformedRangeMax = -1.0*transformedRangeMax; + transformedRangeMin = -1.0*transformedRangeMin; + } + + double logRangeMax = (transformedRangeMax > 0) ? log10(transformedRangeMax): std::numeric_limits::min_exponent10; + m_logRangeMin = (transformedRangeMin > 0) ? log10(transformedRangeMin): std::numeric_limits::min_exponent10; + + m_logRange = logRangeMax - m_logRangeMin; } } // namespace cvf diff --git a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.h b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.h index b947b99bd8..bba36fbbea 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.h +++ b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.h @@ -19,7 +19,7 @@ #pragma once -#include "cvfScalarMapperDiscreteLinear.h" +#include "cvfScalarMapperRangeBased.h" namespace cvf { @@ -29,14 +29,24 @@ namespace cvf { // //================================================================================================== -class ScalarMapperDiscreteLog : public ScalarMapperDiscreteLinear +class ScalarMapperDiscreteLog : public ScalarMapperRangeBased { public: - ScalarMapperDiscreteLog() {m_decadeLevelCount = 2; } + ScalarMapperDiscreteLog(); // Implementing the Scalarmapper interface - + virtual Vec2f mapToTextureCoord(double scalarValue) const; + virtual Color3ub mapToColor(double scalarValue) const; virtual double normalizedValue( double domainValue ) const; virtual double domainValue( double normalizedPosition ) const; + + // +protected: + virtual void rangeUpdated(); + +private: + double m_logRange; + double m_logRangeMin; + bool m_hasNegativeRange; }; } diff --git a/VisualizationModules/LibRender/cvfScalarMapperRangeBased.cpp b/VisualizationModules/LibRender/cvfScalarMapperRangeBased.cpp index 5110300155..f2c41620e5 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperRangeBased.cpp +++ b/VisualizationModules/LibRender/cvfScalarMapperRangeBased.cpp @@ -56,6 +56,7 @@ void ScalarMapperRangeBased::setRange(double min, double max) m_rangeMin = min; m_rangeMax = max; updateSortedLevels(); + rangeUpdated(); } @@ -160,7 +161,8 @@ bool ScalarMapperRangeBased::updateTexture(TextureImage* image) const // Then calculate a stepsize that is humanly understandable // basically rounded to whole or half of the decade in question - +// decadeParts - The number of steps wanted within a decade +// decadeValue - The value used to describe the current decade to round off within static double adjust(double domainValue, double decadeValue, unsigned int decadeParts = 2) { if (decadeValue == 0) return domainValue; // Conceptually correct @@ -200,7 +202,7 @@ void ScalarMapperRangeBased::majorTickValues( std::vector* domainValues) if (m_userDefinedLevelValues.empty()) { - domainValues->push_back(m_rangeMin); + domainValues->push_back(domainValue(0)); if (m_levelCount > 1) { double stepSizeNorm = 1.0/m_levelCount; @@ -213,17 +215,19 @@ void ScalarMapperRangeBased::majorTickValues( std::vector* domainValues) { double prevNormPos = normalizedValue(prevDomValue); double newNormPos = prevNormPos + stepSizeNorm; + double domValue = domainValue(newNormPos); double domStep = domValue - prevDomValue; double newLevel; - newLevel = prevDomValue + adjust(domStep, domStep, m_decadeLevelCount); + //newLevel = prevDomValue + adjust(domStep, domStep, m_decadeLevelCount); + newLevel = domValue; // Must handle first level specially to get a good absolute staring point // For log domain this must be done all the time, and it does not hamper linear, so.. do it always newLevel = adjust(newLevel, domStep, m_decadeLevelCount); - if (newLevel > m_rangeMax - domStep*0.4) break; + if (normalizedValue(newLevel) > 1.0 - stepSizeNorm*0.4) break; domainValues->push_back(newLevel); prevDomValue = newLevel; @@ -237,7 +241,7 @@ void ScalarMapperRangeBased::majorTickValues( std::vector* domainValues) } } } - domainValues->push_back(m_rangeMax); + domainValues->push_back(domainValue(1)); } else { diff --git a/VisualizationModules/LibRender/cvfScalarMapperRangeBased.h b/VisualizationModules/LibRender/cvfScalarMapperRangeBased.h index 93cbadcef1..2a818fb75f 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperRangeBased.h +++ b/VisualizationModules/LibRender/cvfScalarMapperRangeBased.h @@ -48,6 +48,8 @@ public: virtual void majorTickValues(std::vector* domainValues ) const; protected: + virtual void rangeUpdated() {}; //< Called when the range is changed. Subclasses can reimplment to recalculate cached values + double m_rangeMin; double m_rangeMax; unsigned int m_decadeLevelCount; diff --git a/VisualizationModules/LibRender/cvfTextDrawer.cpp b/VisualizationModules/LibRender/cvfTextDrawer.cpp index ad3f7ed460..86a635d9a0 100644 --- a/VisualizationModules/LibRender/cvfTextDrawer.cpp +++ b/VisualizationModules/LibRender/cvfTextDrawer.cpp @@ -34,6 +34,7 @@ #include "cvfMatrixState.h" #include "cvfRenderStateDepth.h" #include "cvfRenderStateBlending.h" +#include "cvfRenderStatePolygonOffset.h" #ifndef CVF_OPENGL_ES #include "cvfRenderState_FF.h" @@ -60,7 +61,8 @@ TextDrawer::TextDrawer(Font* font) m_textColor(Color3::GRAY), m_backgroundColor(1.0f, 1.0f, 0.8f), m_borderColor(Color3::DARK_GRAY), - m_verticalAlignment(0) // BASELINE + m_useDepthBuffer(false), + m_verticalAlignment(0) // BASELINE { CVF_ASSERT(font); CVF_ASSERT(!font->isEmpty()); @@ -88,6 +90,22 @@ void TextDrawer::addText(const String& text, const Vec2f& pos) } +//-------------------------------------------------------------------------------------------------- +/// Add text to be drawn +/// +/// Note: The Z coordinate needs to correspond with the orthographic projection that is setup +/// to render the text. So the range should be <1..-1> with 1 being closest to the near plane. +//-------------------------------------------------------------------------------------------------- +void TextDrawer::addText(const String& text, const Vec3f& pos) +{ + CVF_ASSERT(!text.isEmpty()); + CVF_ASSERT(!pos.isUndefined()); + + m_texts.push_back(text); + m_positions.push_back(pos); +} + + //-------------------------------------------------------------------------------------------------- /// Remove all texts in the drawer //-------------------------------------------------------------------------------------------------- @@ -192,6 +210,15 @@ void TextDrawer::setDrawBorder(bool drawBorder) } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void TextDrawer::setUseDepthBuffer(bool useDepthBuffer) +{ + m_useDepthBuffer = useDepthBuffer; +} + + //-------------------------------------------------------------------------------------------------- /// Returns the color used to draw the text //-------------------------------------------------------------------------------------------------- @@ -284,7 +311,7 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix MatrixState projMatrixState(projCam); // Turn off depth test - RenderStateDepth depth(false, RenderStateDepth::LESS, false); + RenderStateDepth depth(m_useDepthBuffer, RenderStateDepth::LESS, m_useDepthBuffer); depth.applyOpenGL(oglContext); // Setup viewport @@ -322,6 +349,13 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix // ------------------------------------------------------------------------- if (m_drawBackground || m_drawBorder) { + if (m_useDepthBuffer) + { + RenderStatePolygonOffset polygonOffset; + polygonOffset.configurePolygonPositiveOffset(); + polygonOffset.applyOpenGL(oglContext); + } + ref backgroundShader; if (!softwareRendering) @@ -353,10 +387,10 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix Vec3f max = Vec3f(min.x() + static_cast(textExtent.x()) + offset.x()*2.0f, min.y() + static_cast(textExtent.y()) + offset.y()*2.0f, 0.0f); // Draw the background triangle - v1[0] = min.x(); v1[1] = min.y(); - v2[0] = max.x(); v2[1] = min.y(); - v3[0] = max.x(); v3[1] = max.y(); - v4[0] = min.x(); v4[1] = max.y(); + v1[0] = min.x(); v1[1] = min.y(); v1[2] = pos.z(); + v2[0] = max.x(); v2[1] = min.y(); v2[2] = pos.z(); + v3[0] = max.x(); v3[1] = max.y(); v3[2] = pos.z(); + v4[0] = min.x(); v4[1] = max.y(); v4[2] = pos.z(); if (m_drawBackground) { @@ -408,6 +442,12 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix } } } + + if (m_useDepthBuffer) + { + RenderStatePolygonOffset resetPolygonOffset; + resetPolygonOffset.applyOpenGL(oglContext); + } } // Render texts @@ -459,7 +499,6 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix // Need to round off to integer positions to avoid buggy text drawing on iPad2 pos.x() = cvf::Math::floor(pos.x()); pos.y() = cvf::Math::floor(pos.y()); - pos.z() = cvf::Math::floor(pos.z()); // Cursor incrementor Vec2f cursor(pos); @@ -484,18 +523,22 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix // Lower left corner v1[0] = cursor.x() + static_cast(glyph->horizontalBearingX()); v1[1] = cursor.y() + static_cast(glyph->horizontalBearingY()) - textureHeight + static_cast(m_verticalAlignment); + v1[2] = pos.z(); // Lower right corner v2[0] = v1[0] + textureWidth; v2[1] = v1[1]; + v2[2] = pos.z(); // Upper right corner v3[0] = v2[0]; v3[1] = v1[1] + textureHeight; + v3[2] = pos.z(); // Upper left corner v4[0] = v1[0]; v4[1] = v3[1]; + v4[2] = pos.z(); glyph->setupAndBindTexture(oglContext, softwareRendering); @@ -591,4 +634,32 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix CVF_CHECK_OGL(oglContext); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool TextDrawer::pickText(const Vec3f& pickCoord2d, const String& text, const Vec3f& pos, Font* font) +{ + // Figure out margin + ref glyph = font->getGlyph(L'A'); + float charHeight = static_cast(glyph->height()); + float charWidth = static_cast(glyph->width()); + + float offsetX = cvf::Math::floor(charWidth/2.0f); + float offsetY = cvf::Math::floor(charHeight/2.0f); + + Vec2ui textExtent = font->textExtent(text); + + Vec3f min = pos; + Vec3f max = Vec3f(min.x() + static_cast(textExtent.x()) + offsetX*2.0f, min.y() + static_cast(textExtent.y()) + offsetY*2.0f, 0.0f); + + if (pickCoord2d.x() > min.x() && pickCoord2d.x() < max.x() && + pickCoord2d.y() > min.y() && pickCoord2d.y() < max.y()) + { + return true; + } + + return false; +} + } // namespace cvf diff --git a/VisualizationModules/LibRender/cvfTextDrawer.h b/VisualizationModules/LibRender/cvfTextDrawer.h index 1e00354671..208bf507b2 100644 --- a/VisualizationModules/LibRender/cvfTextDrawer.h +++ b/VisualizationModules/LibRender/cvfTextDrawer.h @@ -55,6 +55,7 @@ public: virtual ~TextDrawer(); void addText(const String& text, const Vec2f& pos); + void addText(const String& text, const Vec3f& pos); void removeAllTexts(); void setVerticalAlignment(Alignment alignment); @@ -63,16 +64,21 @@ public: void setBorderColor(const Color3f& color); void setDrawBackground(bool drawBackground); void setDrawBorder(bool drawBorder); + void setUseDepthBuffer(bool useDepthBuffer); Color3f textColor() const; Color3f backgroundColor() const; Color3f borderColor() const; bool drawBackground() const; bool drawBorder() const; + bool useDepthBuffer() const; + void render(OpenGLContext* oglContext, const MatrixState& matrixState); void renderSoftware(OpenGLContext* oglContext, const MatrixState& matrixState); + static bool pickText(const Vec3f& pickCoord2d, const String& text, const Vec3f& pos, Font* font); + private: void doRender2d(OpenGLContext* oglContext, const MatrixState& matrixState, bool softwareRendering); @@ -87,6 +93,7 @@ private: Color3f m_textColor; Color3f m_backgroundColor; Color3f m_borderColor; + bool m_useDepthBuffer; short m_verticalAlignment;// Vertical alignment for horizontal text }; diff --git a/VisualizationModules/LibRender/cvfUniform.h b/VisualizationModules/LibRender/cvfUniform.h index 17687287ad..7c7345cf8d 100644 --- a/VisualizationModules/LibRender/cvfUniform.h +++ b/VisualizationModules/LibRender/cvfUniform.h @@ -62,6 +62,7 @@ protected: private: CharArray m_name; + CVF_DISABLE_COPY_AND_ASSIGN(Uniform); }; @@ -85,6 +86,7 @@ public: private: IntArray m_data; + CVF_DISABLE_COPY_AND_ASSIGN(UniformInt); }; @@ -120,6 +122,7 @@ public: private: FloatArray m_data; + CVF_DISABLE_COPY_AND_ASSIGN(UniformFloat); }; @@ -129,7 +132,7 @@ private: // // //================================================================================================== -class UniformMatrixf: public Uniform +class UniformMatrixf : public Uniform { public: UniformMatrixf(const char* name); @@ -142,6 +145,7 @@ public: private: FloatArray m_data; + CVF_DISABLE_COPY_AND_ASSIGN(UniformMatrixf); }; diff --git a/VisualizationModules/LibViewing/cvfRendering.cpp b/VisualizationModules/LibViewing/cvfRendering.cpp index b29e6cc711..e5664f7397 100644 --- a/VisualizationModules/LibViewing/cvfRendering.cpp +++ b/VisualizationModules/LibViewing/cvfRendering.cpp @@ -308,6 +308,25 @@ void Rendering::renderOverlayItems(OpenGLContext* oglContext, bool useSoftwareRe item->render(oglContext, rect.min(), Vec2ui(static_cast(rect.width()), static_cast(rect.height()))); } } + + for (size_t i = 0; i < m_overlayItems.size(); i++) + { + OverlayItemLayout item = m_overlayItems.at(i); + if ((item.corner == OverlayItem::UNMANAGED) ) + { + Vec2ui size = item.overlayItem->sizeHint(); + Vec2i pos = item.overlayItem->unmanagedPosition(); + + if (useSoftwareRendering) + { + item.overlayItem->renderSoftware(oglContext, pos, size); + } + else + { + item.overlayItem->render(oglContext, pos, size); + } + } + } } @@ -904,6 +923,24 @@ OverlayItem* Rendering::overlayItemFromWindowCoordinates(int x, int y) } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Recti Rendering::overlayItemRect(OverlayItem* item) +{ + OverlayItemRectMap itemRectMap; + calculateOverlayItemLayout(&itemRectMap); + + OverlayItemRectMap::iterator it = itemRectMap.find(item); + if (it != itemRectMap.end()) + { + return it->second; + } + + return cvf::Recti(); +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -963,6 +1000,5 @@ String Rendering::debugString() const return str; } - } // namespace cvf diff --git a/VisualizationModules/LibViewing/cvfRendering.h b/VisualizationModules/LibViewing/cvfRendering.h index 7061de66b8..1875538b80 100644 --- a/VisualizationModules/LibViewing/cvfRendering.h +++ b/VisualizationModules/LibViewing/cvfRendering.h @@ -113,6 +113,7 @@ public: OverlayItem* overlayItem(size_t index, OverlayItem::LayoutCorner* corner, OverlayItem::LayoutDirection* direction); const OverlayItem* overlayItem(size_t index, OverlayItem::LayoutCorner* corner, OverlayItem::LayoutDirection* direction) const; OverlayItem* overlayItemFromWindowCoordinates(int x, int y); + Recti overlayItemRect(OverlayItem* item); void removeOverlayItem(const OverlayItem* overlayItem); void removeAllOverlayItems(); diff --git a/cafProjectDataModel/cafPdmDocument.cpp b/cafProjectDataModel/cafPdmDocument.cpp index 0e16c8a468..8bc3cac261 100644 --- a/cafProjectDataModel/cafPdmDocument.cpp +++ b/cafProjectDataModel/cafPdmDocument.cpp @@ -40,7 +40,6 @@ PdmObjectGroup::PdmObjectGroup() //-------------------------------------------------------------------------------------------------- PdmObjectGroup::~PdmObjectGroup() { - deleteObjects(); } //-------------------------------------------------------------------------------------------------- @@ -72,6 +71,33 @@ 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(); +} + + CAF_PDM_SOURCE_INIT(PdmDocument, "PdmDocument"); @@ -157,29 +183,6 @@ void PdmDocument::writeFile(QIODevice* xmlFile) xmlStream.writeEndDocument(); } -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]); - if (children[cIdx]) children[cIdx]->initAfterRead(); - } - - object->initAfterRead(); -} void PdmDocument::setupBeforeSaveTraversal(PdmObject * object) { @@ -199,7 +202,6 @@ void PdmDocument::setupBeforeSaveTraversal(PdmObject * object) for (cIdx = 0; cIdx < children.size(); ++cIdx) { PdmDocument::setupBeforeSaveTraversal(children[cIdx]); - if (children[cIdx]) children[cIdx]->setupBeforeSave(); } object->setupBeforeSave(); diff --git a/cafProjectDataModel/cafPdmDocument.h b/cafProjectDataModel/cafPdmDocument.h index 7289c654f8..8c58fe950f 100644 --- a/cafProjectDataModel/cafPdmDocument.h +++ b/cafProjectDataModel/cafPdmDocument.h @@ -44,7 +44,8 @@ public: void removeNullPtrs(); void addObject(PdmObject * obj); - // Needs renaming to objectsByType + static void initAfterReadTraversal(PdmObject * root); + template void objectsByType(std::vector >* typedObjects ) const { @@ -57,6 +58,38 @@ public: } } + template + void createCopyByType(std::vector >* copyOfTypedObjects) const + { + std::vector > sourceTypedObjects; + objectsByType(&sourceTypedObjects); + + QString encodedXml; + { + // Write original objects to XML file + PdmObjectGroup typedObjectGroup; + for (size_t i = 0; i < sourceTypedObjects.size(); i++) + { + typedObjectGroup.addObject(sourceTypedObjects[i]); + } + + QXmlStreamWriter xmlStream(&encodedXml); + xmlStream.setAutoFormatting(true); + + typedObjectGroup.writeFields(xmlStream); + } + + // Read back XML into object group, factory methods will be called that will create new objects + PdmObjectGroup destinationObjectGroup; + QXmlStreamReader xmlStream(encodedXml); + destinationObjectGroup.readFields(xmlStream); + + for (size_t it = 0; it < destinationObjectGroup.objects.size(); it++) + { + T* obj = dynamic_cast(destinationObjectGroup.objects[it]); + if (obj) copyOfTypedObjects->push_back(obj); + } + } }; //================================================================================================== @@ -78,7 +111,6 @@ class PdmDocument: public PdmObjectGroup void writeFile(QIODevice* device); private: - static void initAfterReadTraversal(PdmObject * root); static void setupBeforeSaveTraversal(PdmObject * root); }; diff --git a/cafProjectDataModel/cafPdmField.cpp b/cafProjectDataModel/cafPdmField.cpp index 7a398f8aaa..fb0f118c7b 100644 --- a/cafProjectDataModel/cafPdmField.cpp +++ b/cafProjectDataModel/cafPdmField.cpp @@ -59,13 +59,13 @@ bool PdmFieldHandle::assertValid() const { if (m_keyword == "UNDEFINED") { - std::cout << "Detected use of non-initialized field\n"; + std::cout << "PdmField: Detected use of non-initialized field. Did you forget to do CAF_PDM_InitField() on this field ?\n"; return false; } if (!PdmObject::isValidXmlElementName(m_keyword)) { - std::cout << "Detected keyword " << m_keyword.toStdString() << " which is an invalid Xml element name\n"; + std::cout << "PdmField: The supplied keyword: \"" << m_keyword.toStdString() << "\" is an invalid XML element name, and will break your file format!\n"; return false; } @@ -136,18 +136,40 @@ void PdmFieldReader::readFieldData(PdmField & field, QXmlStrea //-------------------------------------------------------------------------------------------------- /// Specialized read operation for Bool`s //-------------------------------------------------------------------------------------------------- -void operator >> (QTextStream& str, bool& value) +QTextStream& operator >> (QTextStream& str, bool& value) { QString text; str >> text; if (text == "True" || text == "true" || text == "1" || text == "Yes" || text == "yes") value = true; else value = false; + + return str; } -void operator << (QTextStream& str, const bool& value) +QTextStream& operator << (QTextStream& str, const bool& value) { if (value) str << "True "; else str << "False "; + + return str; } +//-------------------------------------------------------------------------------------------------- +/// Specialized read operation for QDateTimes`s +//-------------------------------------------------------------------------------------------------- +#include +QTextStream& operator >> (QTextStream& str, QDateTime& value) +{ + QString text; + str >> text; + value = QDateTime::fromString(text, "yyyy_MM_dd-HH:mm:ss"); + return str; +} + +QTextStream& operator << (QTextStream& str, const QDateTime& value) +{ + QString text = value.toString("yyyy_MM_dd-HH:mm:ss"); + str << text; + return str; +} diff --git a/cafProjectDataModel/cafPdmField.h b/cafProjectDataModel/cafPdmField.h index 0498119946..e3788c7120 100644 --- a/cafProjectDataModel/cafPdmField.h +++ b/cafProjectDataModel/cafPdmField.h @@ -46,6 +46,8 @@ public: PdmFieldHandle() : m_isIOReadable(true), m_isIOWritable(true) { m_ownerObject = NULL; m_keyword = "UNDEFINED"; } virtual ~PdmFieldHandle() { } + virtual void resetToDefaultValue() { }; + virtual void readFieldData(QXmlStreamReader& xmlStream) = 0; virtual void writeFieldData(QXmlStreamWriter& xmlStream) = 0; @@ -119,6 +121,7 @@ public: const DataType& defaultValue() const { return m_defaultFieldValue; } void setDefaultValue(const DataType& val) { m_defaultFieldValue = val; } + virtual void resetToDefaultValue() { m_fieldValue = m_defaultFieldValue; } // Gui generalized interface virtual QVariant uiValue() const; @@ -212,6 +215,8 @@ public: void push_back(DataType* pointer); void set(size_t index, DataType* pointer); void insert(size_t indexAfter, DataType* pointer); + void insert(size_t indexAfter, const std::vector >& objects); + size_t count(const DataType* pointer) const; void clear(); void erase(size_t index); diff --git a/cafProjectDataModel/cafPdmField.inl b/cafProjectDataModel/cafPdmField.inl index 12c7c9331d..6a7c2d0bc5 100644 --- a/cafProjectDataModel/cafPdmField.inl +++ b/cafProjectDataModel/cafPdmField.inl @@ -19,6 +19,7 @@ #include "cafPdmObject.h" #include +#include #include "cafPdmUiFieldEditorHandle.h" namespace caf @@ -226,26 +227,66 @@ template void caf::PdmField::readFieldData(QXmlStreamReader& xmlStream) { PdmFieldIOHelper::skipCharactersAndComments(xmlStream); - if (!xmlStream.isStartElement()) return; // Todo: Error handling - - QString className = xmlStream.name().toString(); - - if (m_fieldValue.isNull()) + if (!xmlStream.isStartElement()) { - m_fieldValue.setRawPtr(caf::PdmObjectFactory::instance()->create(className)); - if (m_fieldValue.notNull()) - { - m_fieldValue.rawPtr()->addParentField(this); - } + return; // This happens when the field is "shortcut" empty (written like: ) } - if (m_fieldValue.isNull()) return; // Warning: Unknown className read + QString className = xmlStream.name().toString(); + PdmObject* obj = NULL; - if (xmlStream.name() != m_fieldValue.rawPtr()->classKeyword()) return; // Error: Field contains different class type than on file + // Create an object if needed + if (m_fieldValue.isNull()) + { + obj = caf::PdmObjectFactory::instance()->create(className); - m_fieldValue.rawPtr()->readFields(xmlStream); + if (obj == NULL) + { + std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << this->keyword().toLatin1().data() << std::endl; + + xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read + xmlStream.skipCurrentElement(); // Skip to the endelement of this field + return; + } + else + { + if (dynamic_cast(obj) == NULL) + { + assert(false); // Inconsistency in the factory. It creates objects of wrong type from the ClassKeyword + + xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read + xmlStream.skipCurrentElement(); // Skip to the endelement of this field + + return; + } + + m_fieldValue.setRawPtr(obj); + obj->addParentField(this); + } + } + else + { + obj = m_fieldValue.rawPtr(); + } + + if (className != obj->classKeyword()) + { + // Error: Field contains different class type than on file + std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << this->keyword().toLatin1().data() << std::endl; + std::cout << " Expected class name: " << obj->classKeyword().toLatin1().data() << std::endl; + + xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read + xmlStream.skipCurrentElement(); // Skip to the endelement of this field + + return; + } + + // Everything seems ok, so read the contents of the object: + + obj->readFields(xmlStream); + + // Make stream point to endElement of this field - // Make stream point to end of element QXmlStreamReader::TokenType type; type = xmlStream.readNext(); PdmFieldIOHelper::skipCharactersAndComments(xmlStream); @@ -422,6 +463,45 @@ void PdmPointersField::insert(size_t indexAfter, DataType* pointer) if (pointer) pointer->addParentField(this); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmPointersField::insert(size_t indexAfter, const std::vector >& objects) +{ + m_pointers.insert(m_pointers.begin()+indexAfter, objects.begin(), objects.end()); + + typename std::vector< PdmPointer< DataType > >::iterator it; + for (it = m_pointers.begin()+indexAfter; it != m_pointers.end(); ++it) + { + if (!it->isNull()) + { + (*it)->addParentField(this); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +size_t PdmPointersField::count(const DataType* pointer) const +{ + size_t itemCount = 0; + + typename std::vector< PdmPointer< DataType > >::const_iterator it; + for (it = m_pointers.begin(); it != m_pointers.end(); ++it) + { + if (*it == pointer) + { + itemCount++; + } + } + + return itemCount; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -521,8 +601,17 @@ template { // Warning: Unknown className read // Skip to corresponding end element - xmlStream.skipCurrentElement(); + + std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << this->keyword().toLatin1().data() << std::endl; + + // Skip to EndElement of the object + xmlStream.skipCurrentElement(); + + // Jump off the end element, and head for next start element (or the final EndElement of the field) + QXmlStreamReader::TokenType type; + type = xmlStream.readNext(); PdmFieldIOHelper::skipCharactersAndComments(xmlStream); + continue; } @@ -530,18 +619,24 @@ template if (currentObject == NULL) { - // Warning: Inconsistency in factory !! Assert ? - // Skip to corresponding end element + assert(false); // There is an inconsistency in the factory. It creates objects of type not matching the ClassKeyword + + // Skip to EndElement of the object xmlStream.skipCurrentElement(); + + // Jump off the end element, and head for next start element (or the final EndElement of the field) + QXmlStreamReader::TokenType type; + type = xmlStream.readNext(); PdmFieldIOHelper::skipCharactersAndComments(xmlStream); + continue; } currentObject->readFields(xmlStream); this->push_back(currentObject); - // Skip comments and for some reason: Characters. The last bit should not be correct, - // but Qt reports a character token between EndElement and StartElement + // Jump off the end element, and head for next start element (or the final EndElement of the field) + // Qt reports a character token between EndElements and StartElements so skip it QXmlStreamReader::TokenType type; type = xmlStream.readNext(); diff --git a/cafProjectDataModel/cafPdmFieldImpl.h b/cafProjectDataModel/cafPdmFieldImpl.h index 33f04d52c0..ac3bb79c51 100644 --- a/cafProjectDataModel/cafPdmFieldImpl.h +++ b/cafProjectDataModel/cafPdmFieldImpl.h @@ -411,6 +411,24 @@ struct PdmFieldReader > > } // End of namespace caf +//================================================================================================== +/// QTextStream Stream operator overloading for bool`s +/// Prints bool`s as "True"/"False", and reads them too +//================================================================================================== + +QTextStream& operator >> (QTextStream& str, bool& value); +QTextStream& operator << (QTextStream& str, const bool& value); + + +//================================================================================================== +/// QTextStream Stream operator overloading for QDateTimes`s +/// +//================================================================================================== +//class QDateTime; +QTextStream& operator >> (QTextStream& str, QDateTime& value); +QTextStream& operator << (QTextStream& str, const QDateTime& value); + + //================================================================================================== /// QTextStream Stream operator overloading for std::vector of things. /// Makes automated IO of PdmField< std::vector< Whatever > possible as long as @@ -418,17 +436,18 @@ struct PdmFieldReader > > //================================================================================================== template < typename T > -void operator << (QTextStream& str, const std::vector& sobj) +QTextStream& operator << (QTextStream& str, const std::vector& sobj) { size_t i; for (i = 0; i < sobj.size(); ++i) { str << sobj[i] << " "; } + return str; } template < typename T > -void operator >> (QTextStream& str, std::vector& sobj) +QTextStream& operator >> (QTextStream& str, std::vector& sobj) { while (str.status() == QTextStream::Ok ) { @@ -436,13 +455,5 @@ void operator >> (QTextStream& str, std::vector& sobj) str >> d; if (str.status() == QTextStream::Ok ) sobj.push_back(d); } + return str; } - -//================================================================================================== -/// QTextStream Stream operator overloading for bool`s -/// Prints bool`s as "True"/"False", and reads them too -//================================================================================================== - -void operator >> (QTextStream& str, bool& value); -void operator << (QTextStream& str, const bool& value); - diff --git a/cafProjectDataModel/cafPdmObject.cpp b/cafProjectDataModel/cafPdmObject.cpp index 56eff83b56..d7d71f1ccd 100644 --- a/cafProjectDataModel/cafPdmObject.cpp +++ b/cafProjectDataModel/cafPdmObject.cpp @@ -30,36 +30,13 @@ namespace caf //-------------------------------------------------------------------------------------------------- /// Reads all the fields into this PdmObject -/// Assumes xmlStream points to the start element token of the containing object. +/// Assumes xmlStream points to the start element token of the PdmObject for which to read fields. /// ( and not first token of object content) /// This makes attribute based field storage possible. -/// Leaves the xmlStream pointing to the EndElement corresponding to the start element. +/// Leaves the xmlStream pointing to the EndElement of the PdmObject. //-------------------------------------------------------------------------------------------------- void PdmObject::readFields (QXmlStreamReader& xmlStream ) { - if (!xmlStream.isStartElement()) - { - // Error - return ; - } -/* - Attributes will not be used ... - - QXmlStreamAttributes attribs = xmlStream.attributes(); - int i; - for (i = 0; i < attribs.size(); ++i) - { - QString name = attribs[i].name().toString(); - - PdmFieldBase* field = findField(name); - - if (field) - { - //field->readFieldData(attribs[i].value().toString()); - } - } - */ - bool isObjectFinished = false; QXmlStreamReader::TokenType type; while(!isObjectFinished) @@ -71,6 +48,11 @@ void PdmObject::readFields (QXmlStreamReader& xmlStream ) case QXmlStreamReader::StartElement: { QString name = xmlStream.name().toString(); + if (name == QString("SimpleObjPtrField")) + { + int a; + a = 2 + 7; + } PdmFieldHandle* currentField = findField(name); if (currentField) { @@ -99,6 +81,7 @@ void PdmObject::readFields (QXmlStreamReader& xmlStream ) case QXmlStreamReader::EndElement: { // End of object. + QString name = xmlStream.name().toString(); // For debugging isObjectFinished = true; } break; @@ -254,7 +237,7 @@ void PdmObject::addFieldNoDefault(PdmFieldHandle* field, const QString& keyword, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmObject::uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) const +void PdmObject::uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) { this->defineUiOrdering(uiConfigName, uiOrdering); if (!uiOrdering.forgetRemainingFields()) diff --git a/cafProjectDataModel/cafPdmObject.h b/cafProjectDataModel/cafPdmObject.h index 660c4335f4..bf83a149c2 100644 --- a/cafProjectDataModel/cafPdmObject.h +++ b/cafProjectDataModel/cafPdmObject.h @@ -61,14 +61,16 @@ class PdmUiEditorAttribute; #define CAF_PDM_HEADER_INIT \ public: \ virtual QString classKeyword() { return classKeywordStatic(); } \ - static QString classKeywordStatic() + static QString classKeywordStatic(); \ + static bool Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class() /// CAF_PDM_SOURCE_INIT associates the file keyword used for storage with the class and initializes the factory /// Place this in the cpp file, preferably above the constructor #define CAF_PDM_SOURCE_INIT(ClassName, keyword) \ + bool ClassName::Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class() { return false;} \ QString ClassName::classKeywordStatic() { assert(PdmObject::isValidXmlElementName(keyword)); return keyword; } \ - static bool PDM_OBJECT_STRING_CONCATENATE(pdm_object_factory_init_, __LINE__) = caf::PdmObjectFactory::instance()->registerCreator() + static bool PDM_OBJECT_STRING_CONCATENATE(pdm_object_factory_init_, __LINE__) = caf::PdmObjectFactory::instance()->registerCreator() /// InitObject sets up the user interface related information for the object /// Placed in the constructor of your PdmObject @@ -86,6 +88,8 @@ public: \ #define CAF_PDM_InitField(field, keyword, default, uiName, iconResourceName, toolTip, whatsThis) \ { \ + static bool chekingThePresenceOfHeaderAndSourceInitMacros = Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class(); \ + \ static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \ addField(field, keyword, default, &objDescr); \ } @@ -94,6 +98,8 @@ public: \ #define CAF_PDM_InitFieldNoDefault(field, keyword, uiName, iconResourceName, toolTip, whatsThis) \ { \ + static bool chekingThePresenceOfHeaderAndSourceInitMacros = Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class(); \ + \ static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \ addFieldNoDefault(field, keyword, &objDescr); \ } @@ -126,9 +132,13 @@ public: /// void parentObjects(std::vector& objects) const; + /// + template + void parentObjectsOfType(std::vector& objects) const; + /// Method to be called from the Ui classes creating Auto Gui to get the group information /// supplied by the \sa defineUiOrdering method that can be reimplemented - void uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) const; + void uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) ; /// For a specific field, return editor specific parameters used to customize the editor behavior.. void editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute); @@ -159,7 +169,7 @@ protected: // Virtual /// Override to customize the order and grouping of the Gui. /// Fill up the uiOrdering object with groups and field references to create the gui structure /// If the uiOrdering is empty, it is interpreted as meaning all fields w/o grouping. - virtual void defineUiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) const {} + virtual void defineUiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) {} /// Override to provide editor specific data for the field and uiConfigName virtual void defineEditorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute) {} @@ -210,4 +220,24 @@ private: std::set m_pointersReferencingMe; }; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmObject::parentObjectsOfType(std::vector& objects) const +{ + std::vector parents; + this->parentObjects(parents); + + for (size_t i = 0; i < parents.size(); i++) + { + T* objectOfType = dynamic_cast(parents[i]); + if (objectOfType) + { + objects.push_back(objectOfType); + } + } +} + + } // End of namespace caf diff --git a/cafProjectDataModel/cafPdmUiItem.cpp b/cafProjectDataModel/cafPdmUiItem.cpp index ddaed700eb..256b15faa0 100644 --- a/cafProjectDataModel/cafPdmUiItem.cpp +++ b/cafProjectDataModel/cafPdmUiItem.cpp @@ -200,7 +200,7 @@ QString PdmUiItem::uiEditorTypeName(const QString& uiConfigName) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -Qt::Alignment PdmUiItem::labelAlignment(QString uiConfigName) const +PdmUiItemInfo::LabelPosType PdmUiItem::uiLabelPosition(QString uiConfigName) const { const PdmUiItemInfo* conInfo = configInfo(uiConfigName); const PdmUiItemInfo* defInfo = defaultInfo(); @@ -210,7 +210,7 @@ Qt::Alignment PdmUiItem::labelAlignment(QString uiConfigName) const if (defInfo) return defInfo->m_labelAlignment; if (sttInfo) return sttInfo->m_labelAlignment; - return Qt::AlignLeft; + return PdmUiItemInfo::LEFT; } //-------------------------------------------------------------------------------------------------- diff --git a/cafProjectDataModel/cafPdmUiItem.h b/cafProjectDataModel/cafPdmUiItem.h index d8d68c439b..36da02ef18 100644 --- a/cafProjectDataModel/cafPdmUiItem.h +++ b/cafProjectDataModel/cafPdmUiItem.h @@ -40,9 +40,11 @@ public: PdmUiItemInfo( QString uiName, QIcon icon = QIcon(), QString toolTip = "", QString whatsThis = "") : m_uiName(uiName), m_icon(icon), m_toolTip(toolTip), m_whatsThis(whatsThis), - m_editorTypeName(""), m_isHidden(false), m_isReadOnly(false), m_labelAlignment(Qt::AlignLeft) + m_editorTypeName(""), m_isHidden(false), m_isReadOnly(false), m_labelAlignment(LEFT) { } + enum LabelPosType { LEFT, TOP, HIDDEN }; + private: friend class PdmUiItem; QString m_uiName; @@ -52,7 +54,7 @@ private: QString m_editorTypeName; ///< Use this exact type of editor to edit this UiItem int m_isHidden; ///< UiItem should be hidden. -1 means not set int m_isReadOnly; ///< UiItem should be insensitive, or read only. -1 means not set. - Qt::Alignment m_labelAlignment; + LabelPosType m_labelAlignment; }; //================================================================================================== @@ -115,9 +117,10 @@ public: bool isUiReadOnly(QString uiConfigName = ""); void setUiReadOnly(bool isReadOnly, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_isReadOnly = isReadOnly; } - - Qt::Alignment labelAlignment(QString uiConfigName = "") const; - void setLabelAlignment(Qt::Alignment alignment, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_labelAlignment = alignment; } + + PdmUiItemInfo::LabelPosType + uiLabelPosition(QString uiConfigName = "") const; + void setUiLabelPosition(PdmUiItemInfo::LabelPosType alignment, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_labelAlignment = alignment; } QString uiEditorTypeName(const QString& uiConfigName) const; void setUiEditorTypeName(const QString& editorTypeName, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_editorTypeName = editorTypeName; } diff --git a/cafUserInterface/CMakeLists.txt b/cafUserInterface/CMakeLists.txt index b35796a516..16b28b4603 100644 --- a/cafUserInterface/CMakeLists.txt +++ b/cafUserInterface/CMakeLists.txt @@ -20,6 +20,7 @@ set( QOBJECT_HEADERS cafPdmUiListEditor.h cafPdmUiSliderEditor.h cafPdmUiDoubleSliderEditor.h + cafPdmUiTextEditor.h cafPdmUiColorEditor.h @@ -47,6 +48,7 @@ add_library( ${PROJECT_NAME} cafPdmUiSliderEditor.cpp cafPdmUiDoubleSliderEditor.cpp cafPdmUiColorEditor.cpp + cafPdmUiTextEditor.cpp cafPdmUiPropertyView.cpp ${MOC_FILES_CPP} diff --git a/cafUserInterface/cafPdmUiCheckBoxEditor.cpp b/cafUserInterface/cafPdmUiCheckBoxEditor.cpp index 50447083da..84a9cdd207 100644 --- a/cafUserInterface/cafPdmUiCheckBoxEditor.cpp +++ b/cafUserInterface/cafPdmUiCheckBoxEditor.cpp @@ -55,7 +55,6 @@ void PdmUiCheckBoxEditor::configureAndUpdateUi(const QString& uiConfigName) m_label->setText(field()->uiName(uiConfigName)); } - m_label->setVisible(!field()->isUiHidden(uiConfigName)); m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); m_label->setToolTip(field()->uiToolTip(uiConfigName)); diff --git a/cafUserInterface/cafPdmUiColorEditor.cpp b/cafUserInterface/cafPdmUiColorEditor.cpp index 5c4cb3d41d..450d8511f6 100644 --- a/cafUserInterface/cafPdmUiColorEditor.cpp +++ b/cafUserInterface/cafPdmUiColorEditor.cpp @@ -69,7 +69,6 @@ void PdmUiColorEditor::configureAndUpdateUi(const QString& uiConfigName) m_label->setText(field()->uiName(uiConfigName)); } - m_label->setVisible(!field()->isUiHidden(uiConfigName)); m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); field()->ownerObject()->editorAttribute(field(), uiConfigName, &m_attributes); diff --git a/cafUserInterface/cafPdmUiComboBoxEditor.cpp b/cafUserInterface/cafPdmUiComboBoxEditor.cpp index c18731d906..f0f68ac396 100644 --- a/cafUserInterface/cafPdmUiComboBoxEditor.cpp +++ b/cafUserInterface/cafPdmUiComboBoxEditor.cpp @@ -54,9 +54,7 @@ void PdmUiComboBoxEditor::configureAndUpdateUi(const QString& uiConfigName) m_label->setText(field()->uiName(uiConfigName)); } - m_label->setVisible(!field()->isUiHidden(uiConfigName)); m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_comboBox->setEnabled(!field()->isUiReadOnly(uiConfigName)); // Demo code for attribute retreival when becoming relevant diff --git a/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp b/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp index 58aeaa74f2..53ddc42b9c 100644 --- a/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp +++ b/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp @@ -153,6 +153,8 @@ void PdmUiDefaultObjectEditor::recursiveSetupFieldsAndGroups(const std::vector

isUiHidden(uiConfigName)) continue; + if (uiItems[i]->isUiGroup()) { PdmUiGroup* group = static_cast(uiItems[i]); @@ -197,100 +199,110 @@ void PdmUiDefaultObjectEditor::recursiveSetupFieldsAndGroups(const std::vector

(uiItems[i]); PdmUiFieldEditorHandle* fieldEditor = NULL; - if (!field->isUiHidden(uiConfigName)) + // Find or create FieldEditor + std::map::iterator it; + it = m_fieldViews.find(field->keyword()); + + if (it == m_fieldViews.end()) { - - // Find or create FieldEditor - std::map::iterator it; - it = m_fieldViews.find(field->keyword()); - - if (it == m_fieldViews.end()) + // If editor type is specified, find in factory + if ( !uiItems[i]->uiEditorTypeName(uiConfigName).isEmpty() ) { - // If editor type is specified, find in factory - if ( !uiItems[i]->uiEditorTypeName(uiConfigName).isEmpty() ) - { - fieldEditor = caf::Factory::instance()->create(field->uiEditorTypeName(uiConfigName)); - } - else - { - // Find the default field editor - - QString editorTypeName = qStringTypeName(*field); - - // Handle a single value field with valueOptions: Make a combobox - - if (field->uiValue().type() != QVariant::List) - { - bool useOptionsOnly = true; - QList options = field->valueOptions( &useOptionsOnly); - - if (!options.empty()) - { - editorTypeName = caf::PdmUiComboBoxEditor::uiEditorTypeName(); - } - } - - fieldEditor = caf::Factory::instance()->create(editorTypeName); - } - - if (fieldEditor) - { - m_fieldViews[field->keyword()] = fieldEditor; - fieldEditor->createWidgets(parent); - } + fieldEditor = caf::Factory::instance()->create(field->uiEditorTypeName(uiConfigName)); } else - { - fieldEditor = it->second; + { + // Find the default field editor + + QString editorTypeName = qStringTypeName(*field); + + // Handle a single value field with valueOptions: Make a combobox + + if (field->uiValue().type() != QVariant::List) + { + bool useOptionsOnly = true; + QList options = field->valueOptions( &useOptionsOnly); + + if (!options.empty()) + { + editorTypeName = caf::PdmUiComboBoxEditor::uiEditorTypeName(); + } + } + + fieldEditor = caf::Factory::instance()->create(editorTypeName); } if (fieldEditor) { - fieldEditor->setField(field); + m_fieldViews[field->keyword()] = fieldEditor; + fieldEditor->createWidgets(parent); + } + } + else + { + fieldEditor = it->second; + } - // Place the widget(s) into the correct parent and layout - QWidget* fieldCombinedWidget = fieldEditor->combinedWidget(); + if (fieldEditor) + { + fieldEditor->setField(field); - if (fieldCombinedWidget) + // Place the widget(s) into the correct parent and layout + QWidget* fieldCombinedWidget = fieldEditor->combinedWidget(); + + if (fieldCombinedWidget) + { + fieldCombinedWidget->setParent(parent); + parentLayout->addWidget(fieldCombinedWidget, currentRowIndex, 0, 1, 2); + } + else + { + + PdmUiItemInfo::LabelPosType labelPos = field->uiLabelPosition(uiConfigName); + bool labelOnTop = (labelPos == PdmUiItemInfo::TOP); + bool editorSpanBoth = labelOnTop; + + if (labelPos != PdmUiItemInfo::HIDDEN) { - fieldCombinedWidget->setParent(parent); - parentLayout->addWidget(fieldCombinedWidget, currentRowIndex, 0, 1, 2); - } - else - { - QWidget* fieldEditorWidget = fieldEditor->editorWidget(); QWidget* fieldLabelWidget = fieldEditor->labelWidget(); - - bool labelOnTop = field->labelAlignment(uiConfigName) & Qt::AlignTop; - - if (fieldLabelWidget) + if (fieldLabelWidget ) { fieldLabelWidget->setParent(parent); // Label widget will span two columns if aligned on top int colSpan = labelOnTop ? 2 : 1; parentLayout->addWidget(fieldLabelWidget, currentRowIndex, 0, 1, colSpan, Qt::AlignTop); + fieldLabelWidget->show(); if (labelOnTop) currentRowIndex++; } - - if (fieldEditorWidget) - { - fieldEditorWidget->setParent(parent); // To make sure this widget has the current group box as parent. - - // Label widget will span two columns if aligned on top - int colSpan = labelOnTop ? 2 : 1; - int colIndex = labelOnTop ? 0 : 1; - parentLayout->addWidget(fieldEditorWidget, currentRowIndex, colIndex, 1, colSpan, Qt::AlignTop); - } - + } + else + { + QWidget* fieldLabelWidget = fieldEditor->labelWidget(); + if (fieldLabelWidget ) fieldLabelWidget->hide(); + editorSpanBoth = true; // To span both columns when there is no label + } + + QWidget* fieldEditorWidget = fieldEditor->editorWidget(); + + if (fieldEditorWidget) + { + fieldEditorWidget->setParent(parent); // To make sure this widget has the current group box as parent. + + // Label widget will span two columns if aligned on top + int colSpan = editorSpanBoth ? 2 : 1; + int colIndex = editorSpanBoth ? 0 : 1; + parentLayout->addWidget(fieldEditorWidget, currentRowIndex, colIndex, 1, colSpan, Qt::AlignTop); } - fieldEditor->updateUi(uiConfigName); - - currentRowIndex++; } + + fieldEditor->updateUi(uiConfigName); + + currentRowIndex++; } + } } } diff --git a/cafUserInterface/cafPdmUiDoubleSliderEditor.cpp b/cafUserInterface/cafPdmUiDoubleSliderEditor.cpp index 15b632237b..0fb790dfa8 100644 --- a/cafUserInterface/cafPdmUiDoubleSliderEditor.cpp +++ b/cafUserInterface/cafPdmUiDoubleSliderEditor.cpp @@ -87,7 +87,6 @@ void PdmUiDoubleSliderEditor::configureAndUpdateUi(const QString& uiConfigName) m_label->setText(field()->uiName(uiConfigName)); } - m_label->setVisible(!field()->isUiHidden(uiConfigName)); m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); m_lineEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); diff --git a/cafUserInterface/cafPdmUiFilePathEditor.cpp b/cafUserInterface/cafPdmUiFilePathEditor.cpp index c6e581b718..ece3c61bcd 100644 --- a/cafUserInterface/cafPdmUiFilePathEditor.cpp +++ b/cafUserInterface/cafPdmUiFilePathEditor.cpp @@ -62,7 +62,6 @@ void PdmUiFilePathEditor::configureAndUpdateUi(const QString& uiConfigName) m_label->setText(field()->uiName(uiConfigName)); } - m_label->setVisible(!field()->isUiHidden(uiConfigName)); m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); m_lineEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); diff --git a/cafUserInterface/cafPdmUiLineEditor.cpp b/cafUserInterface/cafPdmUiLineEditor.cpp index 78c23ee291..0e9b59bc51 100644 --- a/cafUserInterface/cafPdmUiLineEditor.cpp +++ b/cafUserInterface/cafPdmUiLineEditor.cpp @@ -60,9 +60,7 @@ void PdmUiLineEditor::configureAndUpdateUi(const QString& uiConfigName) m_label->setText(field()->uiName(uiConfigName)); } - m_label->setVisible(!field()->isUiHidden(uiConfigName)); m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_lineEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); PdmUiLineEditorAttribute leab; diff --git a/cafUserInterface/cafPdmUiListEditor.cpp b/cafUserInterface/cafPdmUiListEditor.cpp index 993a38f0a4..0f49e05141 100644 --- a/cafUserInterface/cafPdmUiListEditor.cpp +++ b/cafUserInterface/cafPdmUiListEditor.cpp @@ -111,9 +111,7 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName) m_label->setText(uiName); } - m_label->setVisible(!field()->isUiHidden(uiConfigName)); m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_listView->setEnabled(!field()->isUiReadOnly(uiConfigName)); /// Demo code Not used yet diff --git a/cafUserInterface/cafPdmUiPushButtonEditor.cpp b/cafUserInterface/cafPdmUiPushButtonEditor.cpp index 400590dbc1..18aa383213 100644 --- a/cafUserInterface/cafPdmUiPushButtonEditor.cpp +++ b/cafUserInterface/cafPdmUiPushButtonEditor.cpp @@ -55,15 +55,42 @@ void PdmUiPushButtonEditor::configureAndUpdateUi(const QString& uiConfigName) m_label->setText(field()->uiName(uiConfigName)); } - m_label->setVisible(!field()->isUiHidden(uiConfigName)); - m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); + m_pushButton->setCheckable(true); - //m_checkBox->setEnabled(!field()->isUiReadOnly(uiConfigName)); + //m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); + m_pushButton->setEnabled(!field()->isUiReadOnly(uiConfigName)); PdmUiPushButtonEditorAttribute attributes; field()->ownerObject()->editorAttribute(field(), uiConfigName, &attributes); - //m_checkBox->setChecked(field()->uiValue().toBool()); + QVariant variantFieldValue = field()->uiValue(); + + if (!attributes.m_buttonIcon.isNull()) + { + m_pushButton->setIcon(attributes.m_buttonIcon); + } + else if (!attributes.m_buttonText.isEmpty()) + { + m_pushButton->setText(attributes.m_buttonText); + } + else + { + if (variantFieldValue.type() == QVariant::Bool) + { + m_pushButton->setText(variantFieldValue.toBool() ? "On" : "Off" ); + } + else + { + m_pushButton->setText(variantFieldValue.toString()); + } + } + + if (variantFieldValue.type() == QVariant::Bool) + { + m_pushButton->setChecked(field()->uiValue().toBool()); + } + + } @@ -72,7 +99,7 @@ void PdmUiPushButtonEditor::configureAndUpdateUi(const QString& uiConfigName) //-------------------------------------------------------------------------------------------------- QWidget* PdmUiPushButtonEditor::createEditorWidget(QWidget * parent) { - m_pushButton = new QPushButton("Ok", parent); + m_pushButton = new QPushButton("", parent); connect(m_pushButton, SIGNAL(clicked(bool)), this, SLOT(slotClicked(bool))); return m_pushButton; } @@ -91,9 +118,14 @@ QWidget* PdmUiPushButtonEditor::createLabelWidget(QWidget * parent) //-------------------------------------------------------------------------------------------------- void PdmUiPushButtonEditor::slotClicked(bool checked) { - QVariant v; - v = checked; - this->setValueToField(v); + + if (dynamic_cast *> (field())) + { + QVariant v; + v = checked; + this->setValueToField(v); + } + } diff --git a/cafUserInterface/cafPdmUiPushButtonEditor.h b/cafUserInterface/cafPdmUiPushButtonEditor.h index d12a3eb830..596f0a5b6b 100644 --- a/cafUserInterface/cafPdmUiPushButtonEditor.h +++ b/cafUserInterface/cafPdmUiPushButtonEditor.h @@ -34,7 +34,9 @@ namespace caf class PdmUiPushButtonEditorAttribute : public PdmUiEditorAttribute { - +public: + QIcon m_buttonIcon; + QString m_buttonText; }; diff --git a/cafUserInterface/cafPdmUiSliderEditor.cpp b/cafUserInterface/cafPdmUiSliderEditor.cpp index 61912dd990..22a6608cf8 100644 --- a/cafUserInterface/cafPdmUiSliderEditor.cpp +++ b/cafUserInterface/cafPdmUiSliderEditor.cpp @@ -56,9 +56,7 @@ void PdmUiSliderEditor::configureAndUpdateUi(const QString& uiConfigName) m_label->setText(field()->uiName(uiConfigName)); } - m_label->setVisible(!field()->isUiHidden(uiConfigName)); m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_lineEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); m_slider->setEnabled(!field()->isUiReadOnly(uiConfigName)); diff --git a/cafUserInterface/cafPdmUiTextEditor.cpp b/cafUserInterface/cafPdmUiTextEditor.cpp new file mode 100644 index 0000000000..c5758b7723 --- /dev/null +++ b/cafUserInterface/cafPdmUiTextEditor.cpp @@ -0,0 +1,130 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cafPdmUiTextEditor.h" + +#include "cafPdmUiDefaultObjectEditor.h" + +#include "cafPdmObject.h" +#include "cafPdmUiFieldEditorHandle.h" +#include "cafPdmUiOrdering.h" + +#include "cafPdmField.h" + +#include +#include +#include + +#include +#include "cafFactory.h" + + + +namespace caf +{ + +CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiTextEditor); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTextEditor::configureAndUpdateUi(const QString& uiConfigName) +{ + assert(!m_textEdit.isNull()); + assert(!m_label.isNull()); + + 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)); + + m_textEdit->setReadOnly(field()->isUiReadOnly(uiConfigName)); + //m_textEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); // Neccesary ? + + PdmUiTextEditorAttribute leab; + field()->ownerObject()->editorAttribute(field(), uiConfigName, &leab); + m_textMode = leab.textMode; + + m_textEdit->blockSignals(true); + switch (leab.textMode) + { + case PdmUiTextEditorAttribute::PLAIN: + m_textEdit->setPlainText(field()->uiValue().toString()); + break; + case PdmUiTextEditorAttribute::HTML: + m_textEdit->setHtml(field()->uiValue().toString()); + break; + } + m_textEdit->blockSignals(false); + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* PdmUiTextEditor::createEditorWidget(QWidget * parent) +{ + m_textEdit = new QTextEdit(parent); + connect(m_textEdit, SIGNAL(textChanged()), this, SLOT(slotTextChanged())); + return m_textEdit; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* PdmUiTextEditor::createLabelWidget(QWidget * parent) +{ + m_label = new QLabel(parent); + return m_label; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTextEditor::slotTextChanged() +{ + QVariant v; + QString textValue; + + switch (m_textMode) + { + case PdmUiTextEditorAttribute::PLAIN: + textValue = m_textEdit->toPlainText(); + break; + case PdmUiTextEditorAttribute::HTML: + textValue = m_textEdit->toHtml(); + break; + } + + v = textValue; + + this->setValueToField(v); +} + + +} // end namespace caf diff --git a/cafUserInterface/cafPdmUiTextEditor.h b/cafUserInterface/cafPdmUiTextEditor.h new file mode 100644 index 0000000000..f553ed9500 --- /dev/null +++ b/cafUserInterface/cafPdmUiTextEditor.h @@ -0,0 +1,81 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library 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. +// +// This library 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 "cafPdmUiFieldEditorHandle.h" +#include +#include +#include +#include +#include + +class QGridLayout; + +namespace caf +{ + +//================================================================================================== +/// An editor to show (and possibly edit?) formatted larger portions of text +//================================================================================================== + +class PdmUiTextEditorAttribute : public PdmUiEditorAttribute +{ +public: + PdmUiTextEditorAttribute() + { + textMode = PLAIN; + } + + enum TextMode + { + PLAIN, + HTML + }; + +public: + TextMode textMode; +}; + + +class PdmUiTextEditor : public PdmUiFieldEditorHandle +{ + Q_OBJECT + CAF_PDM_UI_FIELD_EDITOR_HEADER_INIT; + +public: + PdmUiTextEditor() { m_textMode = PdmUiTextEditorAttribute::PLAIN; } + virtual ~PdmUiTextEditor() {} + +protected: + virtual QWidget* createEditorWidget(QWidget * parent); + virtual QWidget* createLabelWidget(QWidget * parent); + virtual void configureAndUpdateUi(const QString& uiConfigName); + +protected slots: + void slotTextChanged(); + +private: + QPointer m_textEdit; + QPointer m_label; + + PdmUiTextEditorAttribute::TextMode m_textMode; +}; + + +} // end namespace caf diff --git a/cafUserInterface/cafUiTreeModelPdm.cpp b/cafUserInterface/cafUiTreeModelPdm.cpp index f9bc0a315e..fbd98a79b3 100644 --- a/cafUserInterface/cafUiTreeModelPdm.cpp +++ b/cafUserInterface/cafUiTreeModelPdm.cpp @@ -293,9 +293,9 @@ Qt::ItemFlags UiTreeModelPdm::flags(const QModelIndex &index) const } //-------------------------------------------------------------------------------------------------- -/// +/// TO BE DELETED //-------------------------------------------------------------------------------------------------- -bool UiTreeModelPdm::insertRows(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) +bool UiTreeModelPdm::insertRows_special(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) { PdmUiTreeItem* parentItem = getTreeItemFromIndex(parent); @@ -311,7 +311,7 @@ bool UiTreeModelPdm::insertRows(int position, int rows, const QModelIndex &paren //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool UiTreeModelPdm::removeRows(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) +bool UiTreeModelPdm::removeRows_special(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) { if (rows <= 0) return true; @@ -344,7 +344,7 @@ void UiTreeModelPdm::rebuildUiSubTree(PdmObject* root) QModelIndex item = getModelIndexFromPdmObject(root); if (item.isValid()) { - this->removeRows(0, rowCount(item), item); + this->removeRows_special(0, rowCount(item), item); PdmUiTreeItem* treeItem = getTreeItemFromIndex(item); @@ -380,18 +380,18 @@ PdmUiTreeItem* caf::UiTreeModelPdm::getTreeItemFromIndex(const QModelIndex& inde //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QModelIndex caf::UiTreeModelPdm::getModelIndexFromPdmObjectRecursive(const QModelIndex& root, const PdmObject * object) const +QModelIndex caf::UiTreeModelPdm::getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const { - if (root.internalPointer()) + if (currentIndex.internalPointer()) { - PdmUiTreeItem* treeItem = static_cast(root.internalPointer()); - if (treeItem->dataObject() == object) return root; + PdmUiTreeItem* treeItem = static_cast(currentIndex.internalPointer()); + if (treeItem->dataObject() == object) return currentIndex; } int row; - for (row = 0; row < rowCount(root); ++row) + for (row = 0; row < rowCount(currentIndex); ++row) { - QModelIndex foundIndex = getModelIndexFromPdmObjectRecursive(index(row, 0, root), object); + QModelIndex foundIndex = getModelIndexFromPdmObjectRecursive(index(row, 0, currentIndex), object); if (foundIndex.isValid()) return foundIndex; } return QModelIndex(); @@ -426,6 +426,7 @@ PdmUiTreeItem* UiTreeItemBuilderPdm::buildViewItems(PdmUiTreeItem* parentTreeIte return NULL; } + // NOTE: if position is -1, the item is appended to the parent tree item PdmUiTreeItem* objectTreeItem = new PdmUiTreeItem(parentTreeItem, position, object); std::vector fields; @@ -445,7 +446,8 @@ PdmUiTreeItem* UiTreeItemBuilderPdm::buildViewItems(PdmUiTreeItem* parentTreeIte caf::PdmObject* childObj = children[i]; assert(childObj); - UiTreeItemBuilderPdm::buildViewItems(objectTreeItem, position, childObj); + // NOTE: -1 as second argument indicates that child objects will be appended to collection + UiTreeItemBuilderPdm::buildViewItems(objectTreeItem, -1, childObj); } } diff --git a/cafUserInterface/cafUiTreeModelPdm.h b/cafUserInterface/cafUiTreeModelPdm.h index 77fcf07bd6..87b59fd043 100644 --- a/cafUserInterface/cafUiTreeModelPdm.h +++ b/cafUserInterface/cafUiTreeModelPdm.h @@ -62,11 +62,13 @@ public: virtual Qt::ItemFlags flags(const QModelIndex &index) const; virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - virtual bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); - virtual bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + // TO BE DELETED, NOT USED + virtual bool insertRows_special(int position, int rows, const QModelIndex &parent = QModelIndex()); -private: - QModelIndex getModelIndexFromPdmObjectRecursive(const QModelIndex& root, const PdmObject * object) const; + virtual bool removeRows_special(int position, int rows, const QModelIndex &parent = QModelIndex()); + +protected: + QModelIndex getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const; private: PdmUiTreeItem* m_root; diff --git a/cafViewer/cafCadNavigation.cpp b/cafViewer/cafCadNavigation.cpp index 03c0b67cd9..28b4023d91 100644 --- a/cafViewer/cafCadNavigation.cpp +++ b/cafViewer/cafCadNavigation.cpp @@ -83,7 +83,7 @@ bool caf::CadNavigation::handleInputEvent(QInputEvent* inputEvent) } m_trackball->startNavigation(cvf::ManipulatorTrackball::ROTATE, translatedMousePosX, translatedMousePosY); - //m_viewer->setCursor(RICursors::get(RICursors::ROTATE)); + //m_viewer->setCursor(RiuCursors::get(RiuCursors::ROTATE)); m_isRotating = true; isEventHandled = true; } @@ -98,7 +98,7 @@ bool caf::CadNavigation::handleInputEvent(QInputEvent* inputEvent) if (me->button() == Qt::MidButton) { m_trackball->endNavigation(); - //m_viewer->setCursor(RICursors::get(RICursors::PICK)); + //m_viewer->setCursor(RiuCursors::get(RiuCursors::PICK)); m_isRotating = false; isEventHandled = true; } diff --git a/cafViewer/cafCeetronNavigation.cpp b/cafViewer/cafCeetronNavigation.cpp index 4b09a40da2..e4a444ed20 100644 --- a/cafViewer/cafCeetronNavigation.cpp +++ b/cafViewer/cafCeetronNavigation.cpp @@ -237,19 +237,19 @@ void caf::CeetronNavigation::setCursorFromCurrentState() switch (navType) { case ManipulatorTrackball::PAN: - //m_viewer->setCursor(RICursors::get(RICursors::PAN)); + //m_viewer->setCursor(RiuCursors::get(RiuCursors::PAN)); return; case ManipulatorTrackball::WALK: - //m_viewer->setCursor(RICursors::get(RICursors::WALK)); + //m_viewer->setCursor(RiuCursors::get(RiuCursors::WALK)); return; case ManipulatorTrackball::ROTATE: - //m_viewer->setCursor(RICursors::get(RICursors::ROTATE)); + //m_viewer->setCursor(RiuCursors::get(RiuCursors::ROTATE)); return; default: break; } - // m_viewer->setCursor(RICursors::get(RICursors::PICK)); + // m_viewer->setCursor(RiuCursors::get(RiuCursors::PICK)); } //-------------------------------------------------------------------------------------------------- diff --git a/cafViewer/cafViewer.cpp b/cafViewer/cafViewer.cpp index 97ac316856..b1b7356911 100644 --- a/cafViewer/cafViewer.cpp +++ b/cafViewer/cafViewer.cpp @@ -26,6 +26,8 @@ #include "cvfRenderQueueSorter.h" #include "cvfScene.h" #include "cvfModel.h" +#include "cvfTextureImage.h" +#include "cvfOverlayImage.h" #include "cvfqtOpenGLContext.h" @@ -62,7 +64,8 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent) m_maxFarPlaneDistance(cvf::UNDEFINED_DOUBLE), m_releaseOGLResourcesEachFrame(false), m_paintCounter(0), - m_navigationPolicyEnabled(true) + m_navigationPolicyEnabled(true), + m_isOverlyPaintingEnabled(true) { m_layoutWidget = parentWidget(); @@ -89,6 +92,11 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent) this->setNavigationPolicy(new caf::CadNavigation); + m_overlayTextureImage = new cvf::TextureImage; + m_overlayImage = new cvf::OverlayImage(m_overlayTextureImage.p()); + m_overlayImage->setBlending(cvf::OverlayImage::TEXTURE_ALPHA); + m_overlayImage->setUnmanagedPosition(cvf::Vec2i(0,0)); + setupMainRendering(); setupRenderingSequence(); @@ -121,6 +129,8 @@ void caf::Viewer::setupMainRendering() { m_mainRendering->renderEngine()->enableForcedImmediateMode(true); } + + updateOverlayImagePresence(); } //-------------------------------------------------------------------------------------------------- @@ -358,6 +368,7 @@ void caf::Viewer::resizeGL(int width, int height) void caf::Viewer::enablePerfInfoHud(bool enable) { m_showPerfInfoHud = enable; + updateOverlayImagePresence(); } @@ -391,6 +402,66 @@ void caf::Viewer::paintEvent(QPaintEvent* event) return; } + // If Qt overlay painting is enabled, paint to an QImage, and set it to the cvf::OverlayImage + + if (m_isOverlyPaintingEnabled || m_showPerfInfoHud) + { + // Set up image to draw to, and painter + if (m_overlayPaintingQImage.size() != this->size()) + { + m_overlayPaintingQImage = QImage(this->size(), QImage::Format_ARGB32); + } + + m_overlayPaintingQImage.fill(Qt::transparent); + QPainter overlyPainter(&m_overlayPaintingQImage); + + // Call virtual method to allow subclasses to paint on the OpenGlCanvas + + if (m_isOverlyPaintingEnabled) + { + this->paintOverlayItems(&overlyPainter); + } + + // Draw performance overlay + + if (m_showPerfInfoHud ) + { + cvfqt::PerformanceInfoHud hud; + hud.addStrings(m_renderingSequence->performanceInfo()); + hud.addStrings(*m_mainCamera); + hud.addString(QString("PaintCount: %1").arg(m_paintCounter++)); + hud.draw(&overlyPainter, width(), height()); + } + + // Convert the QImage into the cvf::TextureImage, + // handling vertical mirroring and (possible) byteswapping + + if (((int)m_overlayTextureImage->height()) != this->height() || ((int)m_overlayTextureImage->width() != this->width())) + { + m_overlayTextureImage->allocate(this->width(), this->height()); + } + + int height = m_overlayTextureImage->height(); + int width = m_overlayTextureImage->width(); + +#pragma omp parallel for + for (int y = 0 ; y < height; ++y) + { + int negy = height - 1 - y; + for (int x = 0 ; x < width; ++x) + { + // Should probably do direct conversion on byte level. Would be faster + // QImage.bits() and cvf::TextureImage.ptr() (casting away const) + QRgb qtRgbaVal = m_overlayPaintingQImage.pixel(x, negy); + cvf::Color4ub cvfRgbVal(qRed(qtRgbaVal), qGreen(qtRgbaVal), qBlue(qtRgbaVal), qAlpha(qtRgbaVal)); + m_overlayTextureImage->setPixel(x, y, cvfRgbVal); + } + } + + m_overlayImage->setImage(m_overlayTextureImage.p()); + m_overlayImage->setPixelSize(cvf::Vec2ui(this->width(), this->height())); + } + #if QT_VERSION >= 0x040600 // Qt 4.6 painter.beginNativePainting(); @@ -417,17 +488,7 @@ void caf::Viewer::paintEvent(QPaintEvent* event) painter.endNativePainting(); #endif - // Call virtual method to allow subclasses to paint on the OpenGlCanvas - this->paintOverlayItems(&painter); - - if (m_showPerfInfoHud && isShadersSupported()) - { - cvfqt::PerformanceInfoHud hud; - hud.addStrings(m_renderingSequence->performanceInfo()); - hud.addStrings(*m_mainCamera); - hud.addString(QString("PaintCount: %1").arg(m_paintCounter++)); - hud.draw(&painter, width(), height()); - } + } //-------------------------------------------------------------------------------------------------- @@ -696,3 +757,35 @@ int caf::Viewer::currentFrameIndex() else return 0; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool caf::Viewer::isOverlyPaintingEnabled() const +{ + return m_isOverlyPaintingEnabled; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void caf::Viewer::enableOverlyPainting(bool val) +{ + m_isOverlyPaintingEnabled = val; + updateOverlayImagePresence(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void caf::Viewer::updateOverlayImagePresence() +{ + if (m_isOverlyPaintingEnabled || m_showPerfInfoHud) + { + m_mainRendering->addOverlayItem(m_overlayImage.p(), cvf::OverlayItem::UNMANAGED, cvf::OverlayItem::VERTICAL); + } + else + { + m_mainRendering->removeOverlayItem(m_overlayImage.p()); + } +} + diff --git a/cafViewer/cafViewer.h b/cafViewer/cafViewer.h index d3708ba00c..e9ad4bf13e 100644 --- a/cafViewer/cafViewer.h +++ b/cafViewer/cafViewer.h @@ -26,9 +26,6 @@ #include "cvfVector3.h" #include "cvfOpenGL.h" - -//#include "cvfManipulatorTrackball.h" - #include "cafOpenGLWidget.h" @@ -39,6 +36,8 @@ namespace cvf { class RenderSequence; class OverlayScalarMapperLegend; class HitItemCollection; + class OverlayImage; + class TextureImage; } namespace caf { @@ -100,6 +99,11 @@ public: bool rayPick(int winPosX, int winPosY, cvf::HitItemCollection* pickedPoints) ; + // QPainter based drawing on top of the OpenGL graphics + + bool isOverlyPaintingEnabled() const; + void enableOverlyPainting(bool val); + // Performance information for debugging etc. void enablePerfInfoHud(bool enable); bool isPerfInfoHudEnabled(); @@ -131,10 +135,9 @@ protected: virtual void paintEvent(QPaintEvent* event); // Support the navigation policy concept - virtual bool event( QEvent* e ); - cvf::ref - m_navigationPolicy; - bool m_navigationPolicyEnabled; + virtual bool event( QEvent* e ); + cvf::ref m_navigationPolicy; + bool m_navigationPolicyEnabled; // Actual rendering objects cvf::ref m_renderingSequence; @@ -142,31 +145,35 @@ protected: cvf::ref m_mainCamera; cvf::ref m_mainRendering; - double m_minNearPlaneDistance; - double m_maxFarPlaneDistance; + double m_minNearPlaneDistance; + double m_maxFarPlaneDistance; private: - void updateCamera(int width, int height); + void updateCamera(int width, int height); - void releaseOGlResourcesForCurrentFrame(); - void debugShowRenderingSequencePartNames(); + void releaseOGlResourcesForCurrentFrame(); + void debugShowRenderingSequencePartNames(); - bool m_showPerfInfoHud; - size_t m_paintCounter; - bool m_releaseOGLResourcesEachFrame; - QPointer m_layoutWidget; + bool m_showPerfInfoHud; + size_t m_paintCounter; + bool m_releaseOGLResourcesEachFrame; + QPointer m_layoutWidget; + bool m_isOverlyPaintingEnabled; + cvf::ref m_overlayTextureImage; + cvf::ref m_overlayImage; + QImage m_overlayPaintingQImage; + void updateOverlayImagePresence(); // System to make sure we share OpenGL resources - static Viewer* sharedWidget(); - static cvf::OpenGLContextGroup* contextGroup(); - static std::list - sm_viewers; + static Viewer* sharedWidget(); + static cvf::OpenGLContextGroup* contextGroup(); + static std::list sm_viewers; static cvf::ref - sm_openGLContextGroup; + sm_openGLContextGroup; - caf::FrameAnimationControl* m_animationControl; - cvf::Collection m_frameScenes; + caf::FrameAnimationControl* m_animationControl; + cvf::Collection m_frameScenes; }; } // End namespace caf diff --git a/debian/rules b/debian/rules old mode 100755 new mode 100644