Merge pull request #3832 from OPM/master

Merge master into patch branch
This commit is contained in:
Magne Sjaastad authored and GitHub committed 2018-12-10 12:22:48 +01:00
commit 15104ce097
2847 files changed
+181206 -66548

No files matched your search

+5 -5
View File
@@ -8,9 +8,9 @@ AlignConsecutiveDeclarations: true
AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Empty
AllowShortLoopsOnASingleLine: false
@@ -18,8 +18,8 @@ AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: true
AfterControlStatement: true
@@ -35,7 +35,7 @@ BraceWrapping:
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializersBeforeComma: true
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 130
+5
View File
@@ -0,0 +1,5 @@
---
Checks: '-*,modernize-use-nullptr,modernize-use-override'
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
...
+1
View File
@@ -68,3 +68,4 @@ Ankh.NoLoad
/Resinsight_Host.files
/Resinsight_Host.creator
/Resinsight_Host.config
*.RESINSIGHT_IDX
@@ -464,3 +464,10 @@ CRAVA is a software package for seismic inversion and conditioning of
This Source Code Form is subject to the terms of the Mozilla
Public License v. 2.0. If a copy of the MPL was not distributed
with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
===============================================================================
Notice for the Contour Line "conrec" code
===============================================================================
Adapted from work by Paul D. Bourke named "conrec"
http://paulbourke.net/papers/conrec/.
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,205 @@
// ResInsight version string : 2018.05.0
// Report generated : ti 22. mai 11:08:30 2018
//
//
AsciiDataCurve
CalcScript
CalculatedSummaryCase
CellEdgeResultSlot
CellFilter
CellPropertyFilter
CellPropertyFilters
CellRangeFilter
CellRangeFilterCollection
ChangeDataSourceFeatureUi
CmdAddItemExecData
CmdDeleteItemExecData
CmdFieldChangeExecData
CrossSection
CrossSectionCollection
EclipseCase
EclipseGeometrySelectionItem
Fault
Faults
FileSummaryCase
FishbonesCollection
FishbonesMultipleSubs
FishbonesPipeProperties
FlowCharacteristicsPlot
FlowDiagSolution
FlowPlotCollection
FormationNames
FormationNamesCollectionObject
FractureContainment
FractureDefinitionCollection
GeoMechGeometrySelectionItem
GeoMechPropertyFilter
GeoMechPropertyFilters
GeoMechResultDefinition
GeoMechResultSlot
GeoMechView
GridCollection
GridSummaryCase
GridTimeHistoryCurve
Intersection2dView
Intersection2dViewCollection
IntersectionBox
Legend
MainPlotCollection
MdiWindowController
MockModelSettings
MultiSnapshotDefinition
NoCommonAreaNNC
ObservedDataCollection
PdmDocument
PdmObjectCollection
PdmObjectGroup
Perforation
PerforationCollection
PropertyFilter
ResInsightAnalysisModels
ResInsightGeoMechCase
ResInsightGeoMechModels
ResInsightOilField
ResInsightProject
ReservoirCellResultStorage
ReservoirView
ResultDefinition
ResultSlot
ResultStorageEntryInfo
RftAddress
RiaPreferences
RiaRegressionTest
RicCaseAndFileExportSettingsUi
RicCellRangeUi
RicDeleteItemExecData
RicExportCarfinUi
RicExportCompletionDataSettingsUi
RicExportToLasFileObj
RicExportToLasFileResampleUi
RicLinkVisibleViewsFeatureUi
RicPasteAsciiDataToSummaryPlotFeatureUi
RicSaveEclipseInputVisibleCellsUi
RicSelectSummaryPlotUI
RicSelectViewUI
RicSummaryAddressSelection
RicSummaryCurveCalculator
RicSummaryCurveCreator
RicWellPathsUnitSystemSettingsUi
RifReaderSettings
Rim3dWellLogCurveCollection
Rim3dWellLogExtractionCurve
Rim3dWellLogFileCurve
Rim3dWellLogRftCurve
RimBinaryExportSettings
RimCaseCollection
RimCommandExecuteScript
RimCommandIssueFieldChanged
RimCommandObject
RimCsvUserData
RimCurveNameConfig
RimDialogData
RimEllipseFractureTemplate
RimEnsembleCurveSet
RimEnsembleCurveSetCollection
RimExportInputSettings
RimFaultResultSlot
RimFractureExportSettings
RimIdenticalGridCaseGroup
RimInputProperty
RimInputPropertyCollection
RimInputReservoir
RimNoCommonAreaNncCollection
RimObservedEclipseUserData
RimOilFieldEntry
RimOilRegionEntry
RimStatisticalCalculation
RimStatisticalCollection
RimStimPlanColors
RimStimPlanFractureTemplate
RimStimPlanLegendConfig
RimSummaryCalculation
RimSummaryCalculationCollection
RimSummaryCalculationVariable
RimSummaryCurveCollection
RimSummaryCurveCollectionModifier
RimTensorResults
RimTernaryLegendConfig
RimTimeStepFilter
RimViewLinkerCollection
RimVirtualPerforationResults
RimWellLogExtractionCurve
RimWellLogExtractionCurveNameConfig
RimWellLogFileCurveNameConfig
RimWellLogRftCurveNameConfig
RimWellPathEntry
RimWellPathImport
ScriptLocation
SimWellFracture
SimWellFractureCollection
SummaryAddress
SummaryCaseCollection
SummaryCaseSubCollection
SummaryCrossPlot
SummaryCrossPlotCollection
SummaryCurve
SummaryCurveAutoName
SummaryCurveFilter
SummaryFilterSettings
SummaryObservedDataFile
SummaryPageDownloadEntity
SummaryPlot
SummaryPlotCollection
SummaryTimeAxisProperties
SummaryYAxisProperties
TC2
TestCommand1
TofAccumulatedPhaseFractionsPlot
TotalWellAllocationPlot
View3dOverlayInfoConfig
ViewController
ViewLinker
Well
WellAllocationPlot
WellAllocationPlotLegend
WellFlowRateCurve
WellLogFile
WellLogFileChannel
WellLogFileCurve
WellLogPlot
WellLogPlotCollection
WellLogPlotTrack
WellLogRftCurve
WellPath
WellPathCompletion
WellPathCompletionCollection
WellPathCompletions
WellPathFracture
WellPathFractureCollection
WellPaths
WellPltPlot
WellPltPlotCollection
WellRftPlot
WellRftPlotCollection
Wells
closeProject
computeCaseGroupStatistics
exportMsw
exportMultiCaseSnapshots
exportProperty
exportSimWellFractureCompletions
exportSnapshots
exportWellPathCompletions
loadCase
openProject
replaceCase
replaceCaseImpl_no_support_for_command_file_text_parsing
replaceSourceCases
runOctaveScript
scaleFractureTemplate
setExportFolder
setFractureContainment
setMainWindowSize
setStartDir
setTimeStep
@@ -0,0 +1,163 @@
2018-10-18 : Based on list of unused functions from cppcheck on build server
Nothing to do
-------------
unchanged ApplicationCode\UnitTests\ListKeywordsForObjectsAndFields-Test.cpp 16 style unusedFunction false The function 'writeTextToFile' is never used.
unchanged ApplicationCode\Commands\SummaryPlotCommands\RicSummaryCurveCalculatorEditor.cpp 119 style unusedFunction false The function 'createWidget' is never used.
unchanged ApplicationCode\UserInterface\RiuRelativePermeabilityPlotPanel.cpp 656 style unusedFunction false The function 'contextMenuEvent' is never used.
unchanged ApplicationCode\Commands\WellPathCommands\PointTangentManipulator\RicPointTangentManipulator.cpp 715 style unusedFunction false The function 'configureAndUpdateUi' is never used.
unchanged ApplicationCode\Commands\WellPathCommands\PointTangentManipulator\RicPointTangentManipulator.cpp 847 style unusedFunction false The function 'cleanupBeforeSettingPdmObject' is never used.
unchanged ApplicationCode\UserInterface\RiuWellLogPlot.cpp 528 style unusedFunction false The function 'changeEvent' is never used.
unchanged ApplicationCode\GeoMech\GeoMechDataModel\RigFemPartGrid.cpp 480 style unusedFunction false The function 'cellMinMaxCordinates' is never used.
unchanged ApplicationCode\GeoMech\GeoMechDataModel\RigFemPartGrid.cpp 453 style unusedFunction false The function 'cellIJKFromCoordinate' is never used.
unchanged ApplicationCode\ReservoirDataModel\cvfGeometryTools.cpp 594 style unusedFunction false The function 'addMidEdgeNodes' is never used.
unchanged ApplicationCode\UserInterface\RiuViewer.cpp 814 style unusedFunction false The function 'leaveEvent' is never used.
unchanged ApplicationCode\Commands\SummaryPlotCommands\RicSummaryCurveCalculatorEditor.cpp 65 style unusedFunction false The function 'recursivelyConfigureAndUpdateTopLevelUiOrdering' is never used.
unchanged ApplicationCode\Application\RiaApplication.cpp 310 style unusedFunction false The function 'processNonGuiEvents' is never used.
unchanged ApplicationCode\ModelVisualization\RivCellEdgeEffectGenerator.cpp 135 style unusedFunction false The function 'updateForShaderBasedRendering' is never used.
unchanged ApplicationCode\ModelVisualization\RivCellEdgeEffectGenerator.cpp 281 style unusedFunction false The function 'updateForFixedFunctionRendering' is never used.
unchanged ApplicationCode\Commands\CrossSectionCommands\RicAppendIntersectionFeature.cpp 124 style unusedFunction false The function 'undo' is never used.
unchanged ApplicationCode\UserInterface\RiuViewer.cpp 356 style unusedFunction false The function 'paintOverlayItems' is never used.
unchanged ApplicationCode\Commands\WellPathCommands\PointTangentManipulator\RicPointTangentManipulator.cpp 648 style unusedFunction false The function 'onSelectionManagerSelectionChanged' is never used.
unchanged ApplicationCode\UserInterface\RiuDragDrop.cpp 565 style unusedFunction false The function 'onProposedDropActionUpdated' is never used.
unchanged ApplicationCode\Commands\SummaryPlotCommands\RicSummaryCurveCalculator.cpp 276 style unusedFunction false The function 'onEditorWidgetsCreated' is never used.
unchanged ApplicationCode\UserInterface\RiuDragDrop.cpp 342 style unusedFunction false The function 'onDragCanceled' is never used.
unchanged ApplicationCode\Commands\ApplicationCommands\RicCloseProjectFeature.cpp 38 style unusedFunction false The function 'onActionTriggered' is never used.
unchanged ApplicationCode\ProjectDataModel\Flow\RimWellPlotTools.cpp 449 style unusedFunction false The function 'timeStepFromWellLogFile' is never used.
unchanged ApplicationCode\ProjectDataModel\RimEclipseCaseCollection.cpp 100 style unusedFunction false The function 'moveEclipseCaseIntoCaseGroup' is never used.
unchanged ApplicationCode\UserInterface\RiuViewer.cpp 245 style unusedFunction false The function 'mouseReleaseEvent' is never used.
unchanged ApplicationCode\UserInterface\RiuViewer.cpp 508 style unusedFunction false The function 'mousePressEvent' is never used.
unchanged ApplicationCode\UserInterface\RiuDragDrop.cpp 126 style unusedFunction false The function 'supportedDropActions' is never used.
unchanged ApplicationCode\UserInterface\RiuFlowCharacteristicsPlot.cpp 275 style unusedFunction false The function 'minimumSizeHint' is never used.
unchanged ApplicationCode\GeoMech\GeoMechDataModel\RigFemPartGrid.cpp 396 style unusedFunction false The function 'minCoordinate' is never used.
unchanged ApplicationCode\UserInterface\RiuDragDrop.cpp 332 style unusedFunction false The function 'mimeTypes' is never used.
unchanged ApplicationCode\GeoMech\GeoMechDataModel\RigFemPartGrid.cpp 405 style unusedFunction false The function 'maxCoordinate' is never used.
unchanged ApplicationCode\ReservoirDataModel\RigSimulationWellCenterLineCalculator.cpp 1085 style unusedFunction false The function 'splitIntoBranches' is never used.
unchanged ApplicationCode\WellPathImportSsihub\RiuWellImportWizard.cpp 752 style unusedFunction false The function 'initializePage' is never used.
unchanged ApplicationCode\Application\Tools\RiaImageFileCompare.cpp 126 style unusedFunction false The function 'imagesEqual' is never used.
unchanged ApplicationCode\Commands\HoloLensCommands\VdeArrayDataPacket.cpp 173 style unusedFunction false The function 'imageComponentCount' is never used.
unchanged ApplicationCode\ProjectDataModel\RimMimeData.cpp 56 style unusedFunction false The function 'hasFormat' is never used.
unchanged ApplicationCode\UserInterface\RiuCadNavigation.cpp 49 style unusedFunction false The function 'handleInputEvent' is never used.
unchanged ApplicationCode\GeoMech\GeoMechDataModel\RigFemPartGrid.cpp 488 style unusedFunction false The function 'gridPointIndexFromIJK' is never used.
unchanged ApplicationCode\GeoMech\GeoMechDataModel\RigFemPartGrid.cpp 371 style unusedFunction false The function 'gridPointCountJ' is never used.
unchanged ApplicationCode\GeoMech\GeoMechDataModel\RigFemPartGrid.cpp 362 style unusedFunction false The function 'gridPointCountI' is never used.
unchanged ApplicationCode\GeoMech\GeoMechDataModel\RigFemPartGrid.cpp 497 style unusedFunction false The function 'gridPointCoordinate' is never used.
unchanged ApplicationCode\Commands\HoloLensCommands\VdeArrayDataPacket.cpp 221 style unusedFunction false The function 'fromRawPacketBuffer' is never used.
unchanged ApplicationCode\UserInterface\RiuWellLogPlot.cpp 520 style unusedFunction false The function 'showEvent' is never used.
unchanged ApplicationCode\ProjectDataModel\Flow\RimWellPltPlot.cpp 1056 style unusedFunction false The function 'setupBeforeSave' is never used.
unchanged ApplicationCode\Commands\ApplicationCommands\RicCloseProjectFeature.cpp 52 style unusedFunction false The function 'setupActionLook' is never used.
unchanged ApplicationCode\ProjectDataModel\Completions\RimPerforationInterval.cpp 103 style unusedFunction false The function 'enableCustomEndDate' is never used.
unchanged ApplicationCode\GeoMech\OdbReader\RifOdbReader.cpp 551 style unusedFunction false The function 'elementSet' is never used.
unchanged ApplicationCode\FileInterface\RifJsonEncodeDecode.cpp 45 style unusedFunction false The function 'dumpToFile' is never used.
unchanged ApplicationCode\FileInterface\RifEclipseSummaryTools.cpp 168 style unusedFunction false The function 'dumpMetaData' is never used.
unchanged ApplicationCode\UserInterface\RiuDragDrop.cpp 254 style unusedFunction false The function 'dropMimeData' is never used.
unchanged ApplicationCode\ProjectDataModel\RimWellPathAttribute.cpp 60 style unusedFunction false The function 'diameterInInches' is never used.
unchanged ApplicationCode\ProjectDataModel\RimSummaryCalculationVariable.cpp 170 style unusedFunction false The function 'defineObjectEditorAttribute' is never used.
unchanged ApplicationCode\Commands\FractureCommands\RicCreateMultipleFracturesUi.cpp 201 style unusedFunction
WIP
---
unchanged ApplicationCode\ProjectDataModel\Rim2dGridProjection.cpp 158 style unusedFunction false The function 'sampleSpacing' is never used.
unchanged ApplicationCode\UserInterface\RiuMultiCaseImportDialog.cpp 134 style unusedFunction false The function 'on_m_removeSearchFolderButton_clicked' is never used.
unchanged ApplicationCode\UserInterface\RiuMultiCaseImportDialog.cpp 252 style unusedFunction false The function 'on_m_removeEclipseCaseButton_clicked' is never used.
unchanged ApplicationCode\UserInterface\RiuMultiCaseImportDialog.cpp 110 style unusedFunction false The function 'on_m_addSearchFolderButton_clicked' is never used.
Candidate for later use
-----------------------
unchanged ApplicationCode\ModelVisualization\RivWellConnectionFactorGeometryGenerator.cpp 202 style unusedFunction false The function 'createStarGeometry' is never used.
unchanged ApplicationCode\GeoMech\GeoMechVisualization\RivFemPartGeometryGenerator.cpp 106 style unusedFunction false The function 'createOutlineMeshDrawable' is never used.
unchanged ApplicationCode\WellPathImportSsihub\RiuWellImportWizard.cpp 143 style unusedFunction false The function 'cancelDownload' is never used.
Issue on GitHub
----
unchanged ApplicationCode\Commands\CompletionExportCommands\RicMultiSegmentWellExportInfo.cpp 493 style unusedFunction false The function 'setTopWellBoreVolume' is never used.
Must be changed
----------------
unchanged ApplicationCode\CommandFileInterface\Core\RicfObjectCapability.cpp 186 style unusedFunction false The function 'writeFields' is never used.
Comment : Add unit test for writeObject
Deleted
-------
unchanged ApplicationCode\ProjectDataModel\Summary\RimObservedData.cpp 120 style unusedFunction false The function 'customWellGroupName' is never used.
unchanged ApplicationCode\ProjectDataModel\Flow\RimWellPltPlot.cpp 794 style unusedFunction false The function 'currentWellName' is never used.
unchanged ApplicationCode\Commands\RicFileHierarchyDialog.cpp 344 style unusedFunction false The function 'currentStatus' is never used.
unchanged ApplicationCode\ModelVisualization\Intersections\RivIntersectionPartMgr.cpp 856 style unusedFunction false The function 'createStdSurfacePart' is never used.
unchanged ApplicationCode\ModelVisualization\Intersections\RivIntersectionPartMgr.cpp 877 style unusedFunction false The function 'createStdLinePart' is never used.
unchanged ApplicationCode\ProjectDataModel\Summary\RimSummaryCaseMainCollection.cpp 374 style unusedFunction false The function 'createAndAddSummaryCasesFromFileInfos' is never used.
unchanged ApplicationCode\Application\Tools\RiaStdStringTools.cpp 98 style unusedFunction false The function 'containsOnlyLettersAndDigits' is never used.
unchanged ApplicationCode\GeoMech\OdbReader\RifOdbReader.cpp 685 style unusedFunction false The function 'componentIndex' is never used.
unchanged ApplicationCode\ModelVisualization\GridBox\RivPatchGenerator.cpp 79 style unusedFunction false The function 'setWindingCCW' is never used.
unchanged ApplicationCode\ProjectDataModel\Summary\RimSummaryObservedDataFile.cpp 49 style unusedFunction false The function 'setSummaryHeaderFilename' is never used.
unchanged ApplicationCode\ModelVisualization\GridBox\RivPatchGenerator.cpp 71 style unusedFunction false The function 'setQuads' is never used.
unchanged ApplicationCode\ProjectDataModel\RimIdenticalGridCaseGroup.cpp 520 style unusedFunction false The function 'canCaseBeAdded' is never used.
unchanged ApplicationCode\ProjectDataModel\RimWellLogCurveCommonDataSource.cpp 119 style unusedFunction false The function 'branchIndexToApply' is never used.
unchanged ApplicationCode\ProjectDataModel\Summary\RimObservedDataCollection.cpp 78 style unusedFunction false The function 'addObservedData' is never used.
unchanged ApplicationCode\ProjectDataModel\RimWellPathGeometryDef.cpp 237 style unusedFunction false The function 'addSmootheningTangentToNextToLastTargetIfSensible' is never used.
unchanged ApplicationCode\UserInterface\RiuViewer.cpp 518 style unusedFunction false The function 'allOverlayItems' is never used.
unchanged ApplicationCode\Application\Tools\RiaQDateTimeTools.cpp 268 style unusedFunction false The function 'biggerThan' is never used.
unchanged ApplicationCode\Application\Tools\RiaQDateTimeTools.cpp 277 style unusedFunction false The function 'biggerThanOrEqualTo' is never used.
unchanged ApplicationCode\ReservoirDataModel\RigEclipseResultInfo.cpp 108 style unusedFunction false The function 'setNeedsToBeStored' is never used.
unchanged ApplicationCode\ModelVisualization\RivPipeGeometryGenerator.cpp 65 style unusedFunction false The function 'setMinimumBendAngle' is never used.
unchanged ApplicationCode\Commands\ExportCommands\RicExportWellPathsUi.cpp 57 style unusedFunction false The function 'setMdStepSize' is never used.
unchanged ApplicationCode\UserInterface\RiuMultiCaseImportDialog.cpp 71 style unusedFunction false The function 'setItemsEditable' is never used.
unchanged ApplicationCode\ReservoirDataModel\RigEclipseResultInfo.cpp 140 style unusedFunction false The function 'setGridScalarResultIndex' is never used.
unchanged ApplicationCode\ProjectDataModel\Summary\RimSummaryPlot.cpp 1028 style unusedFunction false The function 'setCurveCollection' is never used.
unchanged ApplicationCode\UserInterface\RiuViewer.cpp 905 style unusedFunction false The function 'updateParallelProjectionSettings' is never used.
unchanged ApplicationCode\ProjectDataModel\Summary\RimSummaryFilter.cpp 467 style unusedFunction false The function 'setCompleteVarStringFilter' is never used.
unchanged ApplicationCode\ReservoirDataModel\cvfGeometryTools.cpp 987 style unusedFunction false The function 'setCenterNode' is never used.
unchanged ApplicationCode\ModelVisualization\RivPipeGeometryGenerator.cpp 75 style unusedFunction false The function 'setBendScalingFactor' is never used.
unchanged ApplicationCode\Commands\WellLogCommands\RicNewPltPlotFeature.cpp 144 style unusedFunction false The function 'selectedWellLogPlotTrack' is never used.
unchanged ApplicationCode\ReservoirDataModel\RigCaseCellResultsData.cpp 550 style unusedFunction false The function 'reportStepNumbers' is never used.
unchanged ApplicationCode\Commands\RicSummaryCaseRestartDialog.cpp 70 style unusedFunction false The function 'removeCommonRootPath' is never used.
unchanged ApplicationCode\ProjectDataModel\Flow\RimWellPlotTools.cpp 413 style unusedFunction false The function 'timeStepsFromRftCase' is never used.
unchanged ApplicationCode\ReservoirDataModel\RigGeoMechBoreHoleStressCalculator.cpp 48 style unusedFunction false The function 'principleStressesAtWall' is never used.
unchanged ApplicationCode\ProjectDataModel\Flow\RimWellPlotTools.cpp 430 style unusedFunction false The function 'timeStepsFromGridCase' is never used.
unchanged ApplicationCode\ReservoirDataModel\Completions\RigCompletionData.cpp 399 style unusedFunction false The function 'onlyOneIsDefaulted' is never used.
unchanged ApplicationCode\ReservoirDataModel\RigCaseCellResultsData.cpp 478 style unusedFunction false The function 'timeStepDate' is never used.
unchanged ApplicationCode\FileInterface\RifSummaryCaseRestartSelector.cpp 320 style unusedFunction false The function 'summaryFilesWithErrors' is never used.
unchanged ApplicationCode\ProjectDataModel\Summary\RimDerivedEnsembleCase.cpp 220 style unusedFunction false The function 'lookupCachedData' is never used.
unchanged ApplicationCode\Application\Tools\RiaQDateTimeTools.cpp 259 style unusedFunction false The function 'lessThanOrEqualTo' is never used.
unchanged ApplicationCode\FileInterface\RifEclipseRestartDataAccess.cpp 56 style unusedFunction false The function 'keywordsWithItemCountFactorOf' is never used.
unchanged ApplicationCode\ProjectDataModel\Summary\RimSummaryCase.cpp 124 style unusedFunction false The function 'isEnsembleCase' is never used.
unchanged ApplicationCode\ReservoirDataModel\RigStimPlanFractureDefinition.cpp 495 style unusedFunction false The function 'sortPolygon' is never used.
unchanged ApplicationCode\UserInterface\RiuMainWindow.cpp 1287 style unusedFunction false The function 'slotUseShaders' is never used.
unchanged ApplicationCode\UserInterface\RiuMainWindow.cpp 1295 style unusedFunction false The function 'slotShowPerformanceInfo' is never used.
unchanged ApplicationCode\Application\Tools\RiaTimeHistoryCurveMerger.cpp 82 style unusedFunction false The function 'interploatedCurveCount' is never used.
unchanged ApplicationCode\FileInterface\RifEclipseSummaryTools.cpp 92 style unusedFunction false The function 'hasSummaryFiles' is never used.
unchanged ApplicationCode\FileInterface\RifEclipseUserDataParserTools.cpp 538 style unusedFunction false The function 'hasCompleteDataForAllHeaderColumns' is never used.
unchanged ApplicationCode\ReservoirDataModel\RigSimulationWellCenterLineCalculator.cpp 435 style unusedFunction false The function 'hasAnyResultCells' is never used.
unchanged ApplicationCode\Application\RiaDefines.cpp 419 style unusedFunction false The function 'wellPathCasingShoeSizeChannelName' is never used.
unchanged ApplicationCode\ProjectDataModel\Completions\RimStimPlanFractureTemplate.cpp 390 style unusedFunction false The function 'getUnitForStimPlanParameter' is never used.
unchanged ApplicationCode\FileInterface\RifSummaryCaseRestartSelector.cpp 350 style unusedFunction false The function 'getSummaryFilesFromGridFiles' is never used.
unchanged ApplicationCode\FileInterface\RifHdf5Reader.cpp 403 style unusedFunction false The function 'getStepTimeValues' is never used.
unchanged ApplicationCode\ProjectDataModel\Completions\RimSimWellFracture.cpp 118 style unusedFunction false The function 'wellDipAtFracturePosition' is never used.
unchanged ApplicationCode\UserInterface\RiuMainWindow.cpp 1316 style unusedFunction false The function 'slotFramerateChanged' is never used.
unchanged ApplicationCode\ProjectDataModel\RimWellLogCurveCommonDataSource.cpp 135 style unusedFunction false The function 'branchDetectionToApply' is never used.
unchanged ApplicationCode\FileInterface\RifReaderEclipseSummary.cpp 474 style unusedFunction false The function 'getStartDate' is never used.
unchanged ApplicationCode\Commands\FractureCommands\RicCreateMultipleFracturesFeature.cpp 166 style unusedFunction false The function 'slotCancel' is never used.
unchanged ApplicationCode\ProjectDataModel\Flow\RimWellRftPlot.cpp 590 style unusedFunction false The function 'simWellOrWellPathName' is never used.
unchanged ApplicationCode\ProjectDataModel\Summary\RimEnsembleCurveSet.cpp 748 style unusedFunction false The function 'getOptionsForSummaryAddresses' is never used.
unchanged ApplicationCode\FileInterface\RifSummaryReaderInterface.cpp 48 style unusedFunction false The function 'fromTimeT' is never used.
unchanged ApplicationCode\ProjectDataModel\RimWellLogTrack.cpp 1209 style unusedFunction false The function 'showWellPathAttributesBothSides' is never used.
unchanged ApplicationCode\ProjectDataModel\RimWellLogTrack.cpp 1585 style unusedFunction false The function 'formationNameIndexToName' is never used.
unchanged ApplicationCode\Commands\CompletionCommands\RicExportFishbonesLateralsFeature.cpp 118 style unusedFunction false The function 'formatNumber' is never used.
unchanged ApplicationCode\Commands\CompletionExportCommands\RicWellPathFractureTextReportFeatureImpl.cpp 57 style unusedFunction false The function 'floatWithThreeDigits' is never used.
unchanged ApplicationCode\FileInterface\RifEclipseSummaryTools.cpp 105 style unusedFunction false The function 'findSummaryDataFiles' is never used.
unchanged ApplicationCode\FileInterface\RifEclipseUserDataParserTools.cpp 159 style unusedFunction false The function 'findFirstNonEmptyEntryIndex' is never used.
unchanged ApplicationCode\ReservoirDataModel\RigWellLogFile.cpp 271 style unusedFunction false The function 'exportToLasFile' is never used.
unchanged ApplicationCode\Application\Tools\RiaQDateTimeTools.cpp 242 style unusedFunction false The function 'equalTo' is never used.
unchanged ApplicationCode\UserInterface\RiuSummaryQwtPlot.cpp 171 style unusedFunction false The function 'setZoomWindow' is never used.
unchanged ApplicationCode\ProjectDataModel\Flow\RimWellFlowRateCurve.cpp 119 style unusedFunction false The function 'doFillCurve' is never used.
unchanged ApplicationCode\ProjectDataModel\RimWellLogCurve.cpp 62 style unusedFunction false The function 'depthRange' is never used.
unchanged ApplicationCode\ProjectDataModel\Summary\RimSummaryCaseCollection.cpp 88 style unusedFunction false The function 'deleteAllCases' is never used.
unchanged ApplicationCode\Commands\EclipseCommands\EclipseWell\RicEclipseWellFeatureImpl.cpp 56 style unusedFunction false The function 'wellCollectionFromSelection' is never used.
unchanged ApplicationCode\UserInterface\RiuSummaryVectorDescriptionMap.cpp 87 style unusedFunction false The function 'vectorCategory' is never used.
Backlog
-------
@@ -1,26 +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()
set (SOURCE_GROUP_HEADER_FILES
${CEE_CURRENT_LIST_DIR}RiaApplication.h
${CEE_CURRENT_LIST_DIR}RiaDefines.h
${CEE_CURRENT_LIST_DIR}RiaPreferences.h
${CEE_CURRENT_LIST_DIR}RiaPorosityModel.h
${CEE_CURRENT_LIST_DIR}RiaSummaryCurveDefinition.h
${CEE_CURRENT_LIST_DIR}RiaRftPltCurveDefinition.h
${CMAKE_CURRENT_LIST_DIR}/RiaApplication.h
${CMAKE_CURRENT_LIST_DIR}/RiaCompletionTypeCalculationScheduler.h
${CMAKE_CURRENT_LIST_DIR}/RiaDefines.h
${CMAKE_CURRENT_LIST_DIR}/RiaFractureDefines.h
${CMAKE_CURRENT_LIST_DIR}/RiaPreferences.h
${CMAKE_CURRENT_LIST_DIR}/RiaPorosityModel.h
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryCurveDefinition.h
${CMAKE_CURRENT_LIST_DIR}/RiaCurveSetDefinition.h
${CMAKE_CURRENT_LIST_DIR}/RiaRftPltCurveDefinition.h
${CMAKE_CURRENT_LIST_DIR}/RiaViewRedrawScheduler.h
${CMAKE_CURRENT_LIST_DIR}/RiaMemoryCleanup.h
)
set (SOURCE_GROUP_SOURCE_FILES
${CEE_CURRENT_LIST_DIR}RiaApplication.cpp
${CEE_CURRENT_LIST_DIR}RiaDefines.cpp
${CEE_CURRENT_LIST_DIR}RiaMain.cpp
${CEE_CURRENT_LIST_DIR}RiaPreferences.cpp
${CEE_CURRENT_LIST_DIR}RiaPorosityModel.cpp
${CEE_CURRENT_LIST_DIR}RiaSummaryCurveDefinition.cpp
${CEE_CURRENT_LIST_DIR}RiaRftPltCurveDefinition.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaApplication.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaCompletionTypeCalculationScheduler.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaDefines.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaFractureDefines.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaMain.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaPreferences.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaPorosityModel.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryCurveDefinition.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaCurveSetDefinition.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaRftPltCurveDefinition.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaViewRedrawScheduler.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaMemoryCleanup.cpp
)
list(APPEND CODE_HEADER_FILES
@@ -33,8 +38,10 @@ ${SOURCE_GROUP_SOURCE_FILES}
set (QT_MOC_HEADERS
${QT_MOC_HEADERS}
${CEE_CURRENT_LIST_DIR}RiaApplication.h
${CMAKE_CURRENT_LIST_DIR}/RiaApplication.h
${CMAKE_CURRENT_LIST_DIR}/RiaCompletionTypeCalculationScheduler.h
${CMAKE_CURRENT_LIST_DIR}/RiaViewRedrawScheduler.h
)
source_group( "Application" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CEE_CURRENT_LIST_DIR}CMakeLists_files.cmake )
source_group( "Application" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )
File diff suppressed because it is too large. Load diff
+33 -54
View File
@@ -48,15 +48,16 @@ class RigEclipseCaseData;
class RimCommandObject;
class RimEclipseCase;
class RimEclipseView;
class RimGridView;
class RimProject;
class RimSummaryPlot;
class RimView;
class Rim3dView;
class RimViewWindow;
class RimWellLogPlot;
class RimWellAllocationPlot;
class RiuMainWindowBase;
class RiuMainPlotWindow;
class RiuPlotMainWindow;
class RiuRecentFileActionProvider;
class RiaArgumentParser;
@@ -91,23 +92,19 @@ public:
public:
RiaApplication(int& argc, char** argv);
~RiaApplication();
~RiaApplication() override;
static RiaApplication* instance();
int parseArgumentsAndRunUnitTestsIfRequested();
bool parseArguments();
int parseArgumentsAndRunUnitTestsIfRequested();
bool parseArguments();
void executeRegressionTests(const QString& regressionTestPath, QStringList* testFilter = nullptr);
void setActiveReservoirView(Rim3dView*);
Rim3dView* activeReservoirView();
const Rim3dView* activeReservoirView() const;
RimGridView* activeGridView();
void setActiveReservoirView(RimView*);
RimView* activeReservoirView();
const RimView* activeReservoirView() const;
RimViewWindow* activePlotWindow() const;
void scheduleDisplayModelUpdateAndRedraw(RimView* resViewToUpdate);
void scheduleRecalculateCompletionTypeAndRedrawAllViews();
void scheduleRecalculateCompletionTypeAndRedrawEclipseCase(RimEclipseCase* eclipseCase);
RimViewWindow* activePlotWindow() const;
RimProject* project();
@@ -118,12 +115,13 @@ public:
void createInputMockModel();
QString lastUsedDialogDirectory(const QString& dialogName);
QString lastUsedDialogDirectoryWithFallbackToProjectFolder(const QString& dialogName);
QString lastUsedDialogDirectoryWithFallback(const QString& dialogName, const QString& fallbackDirectory);
void setLastUsedDialogDirectory(const QString& dialogName, const QString& directory);
bool openFile(const QString& fileName);
bool openOdbCaseFromFile(const QString& fileName);
bool openOdbCaseFromFile(const QString& fileName, bool applyTimeStepFilter = false);
QString currentProjectPath() const;
QString createAbsolutePathFromProjectRelativePath(QString projectRelativePath);
@@ -142,16 +140,13 @@ public:
void addWellLogsToModel(const QList<QString>& wellLogFilePaths);
void runMultiCaseSnapshots(const QString& templateProjectFileName, std::vector<QString> gridFileNames, const QString& snapshotFolderName);
void runRegressionTest(const QString& testRootPath, QStringList* testFilter = nullptr);
void processNonGuiEvents();
static const char* getVersionStringApp(bool includeCrtInfo);
void setUseShaders(bool enable);
bool useShaders() const;
void setShowPerformanceInfo(bool enable);
bool showPerformanceInfo() const;
RINavigationPolicy navigationPolicy() const;
@@ -181,13 +176,12 @@ public:
void addCommandObject(RimCommandObject* commandObject);
void executeCommandObjects();
bool isRunningRegressionTests() const;
int launchUnitTests();
int launchUnitTestsWithConsole();
RiuMainPlotWindow* getOrCreateAndShowMainPlotWindow();
RiuMainPlotWindow* mainPlotWindow();
RiuPlotMainWindow* getOrCreateMainPlotWindow();
RiuPlotMainWindow* getOrCreateAndShowMainPlotWindow();
RiuPlotMainWindow* mainPlotWindow();
RiuMainWindowBase* mainWindowByID(int mainWindowID);
static RimViewWindow* activeViewWindow();
@@ -205,49 +199,35 @@ public:
static std::vector<QString> readFileListFromTextFile(QString listFileName);
void clearViewsScheduledForUpdate();
void waitUntilCommandObjectsHasBeenProcessed();
void saveWinGeoAndDockToolBarLayout();
static bool enableDevelopmentFeatures();
static void clearAllSelections();
private:
void onProjectOpenedOrClosed();
void setWindowCaptionFromAppState();
void onProjectOpenedOrClosed();
void setWindowCaptionFromAppState();
void createMainPlotWindow();
void deleteMainPlotWindow();
void createMainPlotWindow();
void deleteMainPlotWindow();
void loadAndUpdatePlotData();
void loadAndUpdatePlotData();
void storeTreeViewState();
void storeTreeViewState();
void resizeMaximizedPlotWindows();
void updateRegressionTest(const QString& testRootPath);
void regressionTestConfigureProject();
static QSize regressionDefaultImageSize();
friend RiaArgumentParser;
void setHelpText(const QString& helpText);
void setHelpText(const QString& helpText);
bool notify(QObject *, QEvent *) override;
private slots:
void slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void slotUpdateScheduledDisplayModels();
void slotRecalculateCompletionType();
// Friend classes required to have access to slotUpdateScheduledDisplayModels
// As snapshots are produced fast in sequence, the feature must have access to force redraw
// of scheduled redraws
friend class RimView;
friend class RicExportMultipleSnapshotsFeature;
friend class RiaArgumentParser;
private:
caf::PdmPointer<RimView> m_activeReservoirView;
caf::PdmPointer<Rim3dView> m_activeReservoirView;
caf::PdmPointer<RimProject> m_project;
std::vector<caf::PdmPointer<RimView> > m_resViewsToUpdate;
QTimer* m_resViewUpdateTimer;
std::vector<caf::PdmPointer<RimEclipseCase> > m_eclipseCasesToRecalculate;
QTimer* m_recalculateCompletionTypeTimer;
RiaSocketServer* m_socketServer;
caf::UiProcess* m_workerProcess;
@@ -271,11 +251,10 @@ private:
QMutex m_commandQueueLock;
QString m_helpText;
bool m_runningRegressionTests;
bool m_runningWorkerProcess;
RiuMainPlotWindow* m_mainPlotWindow;
RiuPlotMainWindow* m_mainPlotWindow;
std::unique_ptr<RiuRecentFileActionProvider> m_recentFileActionProvider;
};
@@ -0,0 +1,168 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaCompletionTypeCalculationScheduler.h"
#include "RiaApplication.h"
#include "RigEclipseCaseData.h"
#include "RigCaseCellResultsData.h"
#include "RimEclipseCase.h"
#include "RimEclipseCaseCollection.h"
#include "RimEclipseView.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RiuMainWindow.h"
#include "RiuViewer.h"
#include "cafPdmUiTreeView.h"
#include <QTimer>
#include <QTreeView>
#include <set>
#include "cafProgressState.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaCompletionTypeCalculationScheduler* RiaCompletionTypeCalculationScheduler::instance()
{
static RiaCompletionTypeCalculationScheduler theInstance;
return &theInstance;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaCompletionTypeCalculationScheduler::scheduleRecalculateCompletionTypeAndRedrawAllViews()
{
std::vector<RimEclipseCase*> eclipseCases =
RiaApplication::instance()->project()->activeOilField()->analysisModels->cases().childObjects();
scheduleRecalculateCompletionTypeAndRedrawAllViews(eclipseCases);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaCompletionTypeCalculationScheduler::scheduleRecalculateCompletionTypeAndRedrawAllViews(RimEclipseCase* eclipseCase)
{
std::vector<RimEclipseCase*> eclipseCases;
eclipseCases.push_back(eclipseCase);
scheduleRecalculateCompletionTypeAndRedrawAllViews(eclipseCases);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaCompletionTypeCalculationScheduler::scheduleRecalculateCompletionTypeAndRedrawAllViews(
const std::vector<RimEclipseCase*>& eclipseCases)
{
for (RimEclipseCase* eclipseCase : eclipseCases)
{
CVF_ASSERT(eclipseCase);
if (eclipseCase->eclipseCaseData())
{
eclipseCase->eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->clearScalarResult(RiaDefines::DYNAMIC_NATIVE, RiaDefines::completionTypeResultName());
// Delete virtual perforation transmissibilities, as these are the basis for the computation of completion type
eclipseCase->eclipseCaseData()->setVirtualPerforationTransmissibilities(nullptr);
}
m_eclipseCasesToRecalculate.push_back(eclipseCase);
}
startTimer();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaCompletionTypeCalculationScheduler::slotRecalculateCompletionType()
{
if ( caf::ProgressState::isActive() )
{
startTimer();
return;
}
std::set<RimEclipseCase*> uniqueCases(m_eclipseCasesToRecalculate.begin(), m_eclipseCasesToRecalculate.end());
Rim3dView* activeView = RiaApplication::instance()->activeReservoirView();
QModelIndex mi = RiuMainWindow::instance()->projectTreeView()->treeView()->currentIndex();
for (RimEclipseCase* eclipseCase : uniqueCases)
{
if (eclipseCase)
{
for (const auto& w : eclipseCase->views())
{
RimEclipseView* eclView = dynamic_cast<RimEclipseView*>(w);
if (eclView)
{
eclView->calculateCompletionTypeAndRedrawIfRequired();
}
}
}
}
m_eclipseCasesToRecalculate.clear();
// Recalculation of completion type causes active view to be set to potentially a different view
// Also current index in project tree is changed. Restore both to initial state.
if (activeView && activeView->viewer())
{
RiaApplication::instance()->setActiveReservoirView(activeView);
RiuMainWindow::instance()->setActiveViewer(activeView->viewer()->layoutWidget());
}
if (mi.isValid())
{
RiuMainWindow::instance()->projectTreeView()->treeView()->setCurrentIndex(mi);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaCompletionTypeCalculationScheduler::~RiaCompletionTypeCalculationScheduler()
{
delete m_recalculateCompletionTypeTimer;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaCompletionTypeCalculationScheduler::startTimer()
{
if (!m_recalculateCompletionTypeTimer)
{
m_recalculateCompletionTypeTimer = new QTimer(this);
m_recalculateCompletionTypeTimer->setSingleShot(true);
connect(m_recalculateCompletionTypeTimer, SIGNAL(timeout()), this, SLOT(slotRecalculateCompletionType()));
}
m_recalculateCompletionTypeTimer->start(1500);
}
@@ -0,0 +1,57 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmPointer.h"
#include <QObject>
#include <vector>
class QTimer;
class RimEclipseCase;
class RiaCompletionTypeCalculationScheduler : public QObject
{
Q_OBJECT;
public:
static RiaCompletionTypeCalculationScheduler* instance();
void scheduleRecalculateCompletionTypeAndRedrawAllViews();
void scheduleRecalculateCompletionTypeAndRedrawAllViews(RimEclipseCase* eclipseCase);
private slots:
void slotRecalculateCompletionType();
private:
RiaCompletionTypeCalculationScheduler() : m_recalculateCompletionTypeTimer(nullptr) {}
~RiaCompletionTypeCalculationScheduler() override;
RiaCompletionTypeCalculationScheduler(const RiaCompletionTypeCalculationScheduler& o) = delete;
void operator=(const RiaCompletionTypeCalculationScheduler& o) = delete;
void scheduleRecalculateCompletionTypeAndRedrawAllViews(const std::vector<RimEclipseCase*>& eclipseCases);
void startTimer();
private:
std::vector<caf::PdmPointer<RimEclipseCase> > m_eclipseCasesToRecalculate;
QTimer* m_recalculateCompletionTypeTimer;
};
@@ -0,0 +1,71 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaCurveSetDefinition.h"
#include "RifSummaryReaderInterface.h"
#include "RimSummaryCaseCollection.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaCurveSetDefinition::RiaCurveSetDefinition() :
m_ensemble(nullptr)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaCurveSetDefinition::RiaCurveSetDefinition(RimSummaryCaseCollection* ensemble, const RifEclipseSummaryAddress& summaryAddress) :
m_ensemble(ensemble),
m_summaryAddress(summaryAddress)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCaseCollection* RiaCurveSetDefinition::ensemble() const
{
return m_ensemble;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RifEclipseSummaryAddress& RiaCurveSetDefinition::summaryAddress() const
{
return m_summaryAddress;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaCurveSetDefinition::operator<(const RiaCurveSetDefinition& other) const
{
if (m_ensemble != other.ensemble())
{
return (m_ensemble < other.ensemble());
}
return (m_summaryAddress < other.summaryAddress());
}
@@ -0,0 +1,48 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RifEclipseSummaryAddress.h"
#include <QString>
#include <utility>
#include <vector>
class RimSummaryCaseCollection;
//==================================================================================================
///
//==================================================================================================
class RiaCurveSetDefinition
{
public:
RiaCurveSetDefinition();
explicit RiaCurveSetDefinition(RimSummaryCaseCollection* emsemble,
const RifEclipseSummaryAddress& summaryAddress);
RimSummaryCaseCollection* ensemble() const;
const RifEclipseSummaryAddress& summaryAddress() const;
bool operator < (const RiaCurveSetDefinition& other) const;
private:
RimSummaryCaseCollection * m_ensemble;
RifEclipseSummaryAddress m_summaryAddress;
};
+97 -3
View File
@@ -60,18 +60,22 @@ namespace caf
}
template<>
void caf::AppEnum< RiaDefines::CompletionType >::setUp()
void caf::AppEnum< RiaDefines::WellPathComponentType >::setUp()
{
addItem(RiaDefines::WELL_PATH, "WELL_PATH", "Well Path");
addItem(RiaDefines::PERFORATION_INTERVAL, "PERFORATION_INTERVAL", "Perforation Interval");
addItem(RiaDefines::FISHBONES, "FISHBONES", "Fishbones");
addItem(RiaDefines::FRACTURE, "FRACTURE", "Fracture");
addItem(RiaDefines::ICD, "ICD", "ICD");
addItem(RiaDefines::AICD, "AICD", "AICD");
addItem(RiaDefines::ICV, "ICV", "ICV");
addItem(RiaDefines::CASING, "CASING", "Casing");
addItem(RiaDefines::LINER, "LINER", "Liner");
addItem(RiaDefines::PACKER, "PACKER", "Packer");
setDefault(RiaDefines::WELL_PATH);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -289,6 +293,22 @@ QString RiaDefines::combinedRiAreaNormTranResultName()
return "riTRANXYZbyArea";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::riCellVolumeResultName()
{
return "riCELLVOLUME";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::riOilVolumeResultName()
{
return "riOILVOLUME";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -353,6 +373,80 @@ QString RiaDefines::activeFormationNamesResultName()
return "Active Formation Names";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathAzimuthResultName()
{
return "Azimuth";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathInclinationResultName()
{
return "Inclination";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathPPResultName()
{
return "PP";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathSHResultName()
{
return "SH";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathOBGResultName()
{
return "OBG";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathFGResultName()
{
return "FG";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::wellPathSFGResultName()
{
return "SFG";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RiaDefines::wellPathAngleResultNames()
{
return { RiaDefines::wellPathAzimuthResultName(), RiaDefines::wellPathInclinationResultName() };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RiaDefines::wellPathStabilityResultNames()
{
return { RiaDefines::wellPathFGResultName(), RiaDefines::wellPathOBGResultName(),
RiaDefines::wellPathPPResultName(), RiaDefines::wellPathSFGResultName(),
RiaDefines::wellPathSHResultName() };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
+29 -2
View File
@@ -21,6 +21,7 @@
#pragma once
#include <QString>
#include <vector>
namespace RiaDefines
{
@@ -34,14 +35,25 @@ namespace RiaDefines
FORMATION_NAMES,
FLOW_DIAGNOSTICS,
INJECTION_FLOODING,
REMOVED
REMOVED,
UNDEFINED = 999
};
enum CompletionType {
enum WellPathComponentType {
// Production Tube
WELL_PATH,
// Well path flow completions
PERFORATION_INTERVAL,
FISHBONES,
FRACTURE,
ICD,
AICD,
ICV,
// Well path construction features
CASING,
LINER,
PACKER
};
bool isPerCellFaceResult(const QString& resultName);
@@ -72,6 +84,8 @@ namespace RiaDefines
QString riAreaNormTranZResultName();
QString combinedRiAreaNormTranResultName();
QString riCellVolumeResultName();
QString riOilVolumeResultName();
QString mobilePoreVolumeName();
QString completionTypeResultName();
@@ -85,6 +99,19 @@ namespace RiaDefines
QString activeFormationNamesResultName();
// Well path derived results
QString wellPathAzimuthResultName();
QString wellPathInclinationResultName();
QString wellPathPPResultName();
QString wellPathSHResultName();
QString wellPathOBGResultName();
QString wellPathFGResultName();
QString wellPathSFGResultName();
// List of well path derived results
std::vector<QString> wellPathAngleResultNames();
std::vector<QString> wellPathStabilityResultNames();
//Units and conversions
enum DepthUnitType
{
@@ -0,0 +1,63 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaFractureDefines.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::conductivityResultName()
{
return "CONDUCTIVITY";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::unitStringConductivity(RiaEclipseUnitTools::UnitSystem unitSystem)
{
switch (unitSystem)
{
case RiaEclipseUnitTools::UNITS_METRIC:
return "md-m";
case RiaEclipseUnitTools::UNITS_FIELD:
return "md-ft";
default:
return "";
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaDefines::nonDarcyFlowAlpha(RiaEclipseUnitTools::UnitSystem unitSystem)
{
switch (unitSystem)
{
case RiaEclipseUnitTools::UNITS_METRIC:
return 2.24460e-10;
case RiaEclipseUnitTools::UNITS_FIELD:
return 6.83352e-8;
case RiaEclipseUnitTools::UNITS_LAB:
return 5.41375E-11;
// case RiaEclipseUnitTools::PVT_METRIC: return 2.25533E-10;
default:
return 0.0;
}
}
@@ -0,0 +1,31 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiaEclipseUnitTools.h"
#include <QString>
namespace RiaDefines
{
QString conductivityResultName();
QString unitStringConductivity(RiaEclipseUnitTools::UnitSystem unitSystem);
double nonDarcyFlowAlpha(RiaEclipseUnitTools::UnitSystem unitSystem);
}; // namespace RiaDefines
+17 -1
View File
@@ -41,6 +41,7 @@ int main(int argc, char *argv[])
QString platform = cvf::System::is64Bit() ? "(64bit)" : "(32bit)";
window.setWindowTitle("ResInsight " + platform);
window.setDefaultWindowSize();
window.setDefaultToolbarVisibility();
window.loadWinGeoAndDockToolBarLayout();
window.showWindow();
@@ -49,7 +50,22 @@ int main(int argc, char *argv[])
RiaLogging::setLoggerInstance(new RiuMessagePanelLogger(window.messagePanel()));
RiaLogging::loggerInstance()->setLevel(RI_LL_DEBUG);
int exitCode = app.exec();
int exitCode = 0;
try
{
exitCode = app.exec();
}
catch (std::exception& exep )
{
std::cout << "A standard c++ exception that terminated ResInsight caught in RiaMain.cpp: " << exep.what() << std::endl;
throw;
}
catch(...)
{
std::cout << "An unknown exception that terminated ResInsight caught in RiaMain.cpp. " << std::endl;
throw;
}
RiaLogging::deleteLoggerInstance();
return exitCode;
@@ -0,0 +1,318 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaMemoryCleanup.h"
#include "RiaApplication.h"
#include "RigCaseCellResultsData.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigGeoMechCaseData.h"
#include "Rim3dView.h"
#include "RimEclipseCase.h"
#include "RimEclipseResultDefinition.h"
#include "RimGeoMechCase.h"
#include "RimGeoMechResultDefinition.h"
#include "RimProject.h"
#include "cafPdmUiListEditor.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"
//==================================================================================================
///
///
//==================================================================================================
CAF_PDM_SOURCE_INIT(RiaMemoryCleanup, "RiaMemoryCleanup");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaMemoryCleanup::RiaMemoryCleanup()
{
// clang-format off
CAF_PDM_InitFieldNoDefault(&m_case, "DataCase", "Case", "", "", "");
m_case = nullptr;
CAF_PDM_InitFieldNoDefault(&m_resultsToDelete, "ResultsToDelete", "Results In Memory", "", "", "");
m_resultsToDelete.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP);
m_resultsToDelete.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&m_performDelete, "ClearSelectedData", "", "", "", "");
caf::PdmUiPushButtonEditor::configureEditorForField(&m_performDelete);
// clang-format on
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaMemoryCleanup::setPropertiesFromView(Rim3dView* view)
{
if (!view) return;
m_case = view->ownerCase();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaMemoryCleanup::clearSelectedResultsFromMemory()
{
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(m_case());
RimGeoMechCase* geoMechCase = dynamic_cast<RimGeoMechCase*>(m_case());
if (eclipseCase)
{
RigCaseCellResultsData* caseData = eclipseCase->results(RiaDefines::MATRIX_MODEL);
if (caseData)
{
std::vector<RigEclipseResultInfo> resultsToDelete = selectedEclipseResults();
for (const RigEclipseResultInfo& resultInfo : resultsToDelete)
{
caseData->clearScalarResult(resultInfo);
}
}
}
else if (geoMechCase)
{
RigGeoMechCaseData* data = geoMechCase->geoMechData();
if (data)
{
RigFemPartResultsCollection* resultsCollection = data->femPartResults();
if (resultsCollection)
{
std::vector<RigFemResultAddress> resultsToDelete = selectedGeoMechResults();
for (RigFemResultAddress result : resultsToDelete)
{
resultsCollection->deleteResult(result);
}
}
}
}
m_resultsToDelete.v().clear();
m_eclipseResultAddresses.clear();
m_geomResultAddresses.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigFemResultAddress> RiaMemoryCleanup::selectedGeoMechResults() const
{
std::vector<RigFemResultAddress> results;
if (dynamic_cast<const RimGeoMechCase*>(m_case()))
{
for (size_t index : m_resultsToDelete())
{
CVF_ASSERT(index < m_geomResultAddresses.size());
results.push_back(m_geomResultAddresses[index]);
}
}
return results;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigEclipseResultInfo> RiaMemoryCleanup::selectedEclipseResults() const
{
std::vector<RigEclipseResultInfo> results;
if (dynamic_cast<const RimEclipseCase*>(m_case()))
{
for (size_t index : m_resultsToDelete())
{
CVF_ASSERT(index < m_eclipseResultAddresses.size());
results.push_back(m_eclipseResultAddresses[index]);
}
}
return results;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RigFemResultAddress> RiaMemoryCleanup::findGeoMechCaseResultsInUse() const
{
std::set<RigFemResultAddress> resultsInUse;
RimGeoMechCase* geoMechCase = dynamic_cast<RimGeoMechCase*>(m_case());
if (geoMechCase)
{
std::vector<RimFemResultObserver*> geoMechResults;
geoMechCase->descendantsIncludingThisOfType(geoMechResults);
for (RimFemResultObserver* resultDef : geoMechResults)
{
caf::PdmField<bool>* field = dynamic_cast<caf::PdmField<bool>*>(resultDef->objectToggleField());
if (!field || (*field)())
{
std::vector<RigFemResultAddress> required = resultDef->observedResults();
resultsInUse.insert(required.begin(), required.end());
}
}
}
return resultsInUse;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RigEclipseResultInfo> RiaMemoryCleanup::findEclipseResultsInUse() const
{
std::set<RigEclipseResultInfo> resultsInUse;
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(m_case());
if (eclipseCase)
{
std::vector<RimEclipseResultDefinition*> eclipseResultDefs;
eclipseCase->descendantsIncludingThisOfType(eclipseResultDefs);
for (RimEclipseResultDefinition* resultDef : eclipseResultDefs)
{
RigEclipseResultInfo resultInfo(resultDef->resultType(), resultDef->resultVariable());
resultsInUse.insert(resultInfo);
}
}
return resultsInUse;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaMemoryCleanup::fieldChangedByUi(const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue)
{
if (changedField == &m_case)
{
m_resultsToDelete.uiCapability()->updateConnectedEditors();
}
else if (changedField == &m_performDelete)
{
clearSelectedResultsFromMemory();
m_resultsToDelete.uiCapability()->updateConnectedEditors();
m_performDelete = false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RiaMemoryCleanup::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly)
{
QList<caf::PdmOptionItemInfo> options;
if (fieldNeedingOptions == &m_case)
{
RimProject* proj = RiaApplication::instance()->project();
if (proj)
{
std::vector<RimEclipseCase*> eclipseCases = proj->eclipseCases();
for (RimEclipseCase* c : eclipseCases)
{
options.push_back(caf::PdmOptionItemInfo(c->caseUserDescription(), c, false, c->uiIcon()));
}
std::vector<RimGeoMechCase*> geoMechCases = proj->geoMechCases();
for (RimGeoMechCase* c : geoMechCases)
{
options.push_back(caf::PdmOptionItemInfo(c->caseUserDescription(), c, false, c->uiIcon()));
}
}
}
else if (fieldNeedingOptions == &m_resultsToDelete)
{
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(m_case());
RimGeoMechCase* geoMechCase = dynamic_cast<RimGeoMechCase*>(m_case());
if (eclipseCase)
{
std::set<RigEclipseResultInfo> resultsInUse = findEclipseResultsInUse();
RigCaseCellResultsData* caseData = eclipseCase->results(RiaDefines::MATRIX_MODEL);
if (caseData)
{
m_eclipseResultAddresses = caseData->infoForEachResultIndex();
for (size_t i = 0; i < m_eclipseResultAddresses.size(); ++i)
{
const RigEclipseResultInfo& result = m_eclipseResultAddresses[i];
if (caseData->isResultLoaded(result))
{
bool inUse = resultsInUse.count(result);
QString posText = caf::AppEnum<RiaDefines::ResultCatType>::uiTextFromIndex(result.resultType());
QString resultsText = QString("%1, %2").arg(posText).arg(result.resultName());
if (inUse)
{
resultsText += QString(" [used in view]");
}
options.push_back(caf::PdmOptionItemInfo(resultsText, (qulonglong)i, inUse));
}
}
}
}
else if (geoMechCase)
{
std::set<RigFemResultAddress> resultsInUse = findGeoMechCaseResultsInUse();
RigGeoMechCaseData* caseData = geoMechCase->geoMechData();
if (caseData)
{
RigFemPartResultsCollection* results = caseData->femPartResults();
m_geomResultAddresses = results->loadedResults();
for (size_t i = 0; i < m_geomResultAddresses.size(); ++i)
{
const RigFemResultAddress& result = m_geomResultAddresses[i];
bool inUse = resultsInUse.count(result);
QString posText = caf::AppEnum<RigFemResultPosEnum>::uiTextFromIndex(result.resultPosType);
QString resultsText = QString("%1, %2").arg(posText).arg(QString::fromStdString(result.fieldName));
if (!result.componentName.empty())
{
resultsText += QString(", %1").arg(QString::fromStdString(result.componentName));
}
if (inUse)
{
resultsText += QString(" [used in view]");
}
options.push_back(caf::PdmOptionItemInfo(resultsText, (qulonglong) i, inUse));
}
}
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaMemoryCleanup::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
uiOrdering.add(&m_case);
uiOrdering.add(&m_resultsToDelete);
uiOrdering.add(&m_performDelete);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaMemoryCleanup::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
{
if (field == &m_performDelete)
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>(attribute);
if (attrib)
{
attrib->m_buttonText = "Clear Checked Data From Memory";
}
}
}
@@ -0,0 +1,59 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemResultAddress.h"
#include "RigEclipseResultInfo.h"
#include "cafPdmField.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmPtrField.h"
#include "cafPdmObject.h"
#include "cafPdmUiItem.h"
class RimCase;
class Rim3dView;
class RiaMemoryCleanup : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RiaMemoryCleanup();
void setPropertiesFromView(Rim3dView* view);
void clearSelectedResultsFromMemory();
protected:
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
private:
std::vector<RigFemResultAddress> selectedGeoMechResults() const;
std::vector<RigEclipseResultInfo> selectedEclipseResults() const;
std::set<RigFemResultAddress> findGeoMechCaseResultsInUse() const;
std::set<RigEclipseResultInfo> findEclipseResultsInUse() const;
QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly) override;
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override;
private:
caf::PdmPtrField<RimCase*> m_case;
caf::PdmField<std::vector<size_t>> m_resultsToDelete;
std::vector<RigFemResultAddress> m_geomResultAddresses;
std::vector<RigEclipseResultInfo> m_eclipseResultAddresses;
caf::PdmField<bool> m_performDelete;
};
+110 -14
View File
@@ -27,6 +27,19 @@
#include "cafPdmUiFieldHandle.h"
#include "cafPdmUiFilePathEditor.h"
namespace caf
{
template<>
void RiaPreferences::SummaryRestartFilesImportModeType::setUp()
{
addItem(RiaPreferences::IMPORT, "IMPORT", "Unified");
addItem(RiaPreferences::SEPARATE_CASES, "SEPARATE_CASES", "Separate Cases");
addItem(RiaPreferences::NOT_IMPORT, "NOT_IMPORT", "Skip");
setDefault(RiaPreferences::IMPORT);
}
}
CAF_PDM_SOURCE_INIT(RiaPreferences, "RiaPreferences");
//--------------------------------------------------------------------------------------------------
///
@@ -68,12 +81,16 @@ RiaPreferences::RiaPreferences(void)
useShaders.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitField(&showHud, "showHud", false, "Show 3D Information", "", "", "");
showHud.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitField(&appendClassNameToUiText, "appendClassNameToUiText", false, "Show Class Names", "", "", "");
appendClassNameToUiText.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitField(&appendFieldKeywordToToolTipText, "appendFieldKeywordToToolTipText", false, "Show Field Keyword in ToolTip", "", "", "");
appendFieldKeywordToToolTipText.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitField(&includeFractureDebugInfoFile, "includeFractureDebugInfoFile", false, "Include Fracture Debug Info for Completion Export", "", "", "");
includeFractureDebugInfoFile.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitField(&m_appendClassNameToUiText, "appendClassNameToUiText", false, "Show Class Names", "", "", "");
m_appendClassNameToUiText.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitField(&m_appendFieldKeywordToToolTipText, "appendFieldKeywordToToolTipText", false, "Show Field Keyword in ToolTip", "", "", "");
m_appendFieldKeywordToToolTipText.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitField(&m_showTestToolbar, "showTestToolbar", false, "Enable Test Toolbar", "", "", "");
m_showTestToolbar.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitField(&m_includeFractureDebugInfoFile, "includeFractureDebugInfoFile", false, "Include Fracture Debug Info for Completion Export", "", "", "");
m_includeFractureDebugInfoFile.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitField(&showLegendBackground, "showLegendBackground", true, "Enable Legend Background", "", "", "");
CAF_PDM_InitFieldNoDefault(&lastUsedProjectFileName,"lastUsedProjectFileName", "Last Used Project File", "", "", "");
lastUsedProjectFileName.uiCapability()->setUiHidden(true);
@@ -84,13 +101,24 @@ RiaPreferences::RiaPreferences(void)
CAF_PDM_InitField(&loadAndShowSoil, "loadAndShowSoil", true, "Load and Show SOIL", "", "", "");
loadAndShowSoil.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
CAF_PDM_InitFieldNoDefault(&summaryRestartFilesShowImportDialog, "summaryRestartFilesShowImportDialog", "Show Import Dialog", "", "", "");
CAF_PDM_InitField(&summaryImportMode, "summaryImportMode", SummaryRestartFilesImportModeType(RiaPreferences::IMPORT), "Default Summary Import Option", "", "", "");
CAF_PDM_InitField(&gridImportMode, "gridImportMode", SummaryRestartFilesImportModeType(RiaPreferences::NOT_IMPORT), "Default Grid Import Option", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_holoLensExportFolder, "holoLensExportFolder", "HoloLens Export Folder", "", "", "");
m_holoLensExportFolder.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP);
m_holoLensExportFolder.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&m_readerSettings, "readerSettings", "Reader Settings", "", "", "");
m_readerSettings = new RifReaderSettings;
m_tabNames << "General";
m_tabNames << "Eclipse";
m_tabNames << "Octave";
m_tabNames << "System";
if (RiaApplication::enableDevelopmentFeatures())
{
m_tabNames << "System";
}
}
//--------------------------------------------------------------------------------------------------
@@ -122,9 +150,10 @@ void RiaPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QSt
field == &loadAndShowSoil ||
field == &useShaders ||
field == &showHud ||
field == &appendClassNameToUiText ||
field == &appendFieldKeywordToToolTipText ||
field == &includeFractureDebugInfoFile ||
field == &m_appendClassNameToUiText ||
field == &m_appendFieldKeywordToToolTipText ||
field == &m_showTestToolbar ||
field == &m_includeFractureDebugInfoFile ||
field == &showLasCurveWithoutTvdWarning)
{
caf::PdmUiCheckBoxEditorAttribute* myAttr = dynamic_cast<caf::PdmUiCheckBoxEditorAttribute*>(attribute);
@@ -133,6 +162,14 @@ void RiaPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QSt
myAttr->m_useNativeCheckBoxLabel = true;
}
}
else if (field == &m_holoLensExportFolder)
{
caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast<caf::PdmUiFilePathEditorAttribute*>(attribute);
if (myAttr)
{
myAttr->m_selectDirectory = true;
}
}
}
//--------------------------------------------------------------------------------------------------
@@ -150,6 +187,7 @@ void RiaPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering&
defaultSettingsGroup->add(&defaultWellLabelColor);
defaultSettingsGroup->add(&fontSizeInScene);
defaultSettingsGroup->add(&defaultScaleFactorZ);
defaultSettingsGroup->add(&showLegendBackground);
caf::PdmUiGroup* viewsGroup = uiOrdering.addNewGroup("3D Views");
viewsGroup->add(&navigationPolicy);
@@ -169,6 +207,13 @@ void RiaPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering&
newCaseBehaviourGroup->add(&loadAndShowSoil);
m_readerSettings->defineUiOrdering(uiConfigName, *newCaseBehaviourGroup);
caf::PdmUiGroup* restartBehaviourGroup = uiOrdering.addNewGroup("Origin Files");
restartBehaviourGroup->add(&summaryRestartFilesShowImportDialog);
caf::PdmUiGroup* summaryImportOptionGroup = restartBehaviourGroup->addNewGroup("Origin Summary Files");
summaryImportOptionGroup->add(&summaryImportMode);
caf::PdmUiGroup* gridImportOptionGroup = restartBehaviourGroup->addNewGroup("Origin Grid Files");
gridImportOptionGroup->add(&gridImportMode);
}
else if (uiConfigName == m_tabNames[2])
{
@@ -180,11 +225,13 @@ void RiaPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering&
scriptGroup->add(&scriptDirectories);
scriptGroup->add(&scriptEditorExecutable);
}
else if (uiConfigName == m_tabNames[3])
else if (RiaApplication::enableDevelopmentFeatures() && uiConfigName == m_tabNames[3])
{
uiOrdering.add(&appendClassNameToUiText);
uiOrdering.add(&appendFieldKeywordToToolTipText);
uiOrdering.add(&includeFractureDebugInfoFile);
uiOrdering.add(&m_appendClassNameToUiText);
uiOrdering.add(&m_appendFieldKeywordToToolTipText);
uiOrdering.add(&m_showTestToolbar);
uiOrdering.add(&m_includeFractureDebugInfoFile);
uiOrdering.add(&m_holoLensExportFolder);
}
uiOrdering.skipRemainingFields(true);
@@ -212,6 +259,15 @@ QList<caf::PdmOptionItemInfo> RiaPreferences::calculateValueOptions(const caf::P
options.push_back(caf::PdmOptionItemInfo(fontSizes[oIdx], fontSizes[oIdx]));
}
}
else if (fieldNeedingOptions == &gridImportMode)
{
// Manual option handling in order to one only a subset of the enum values
SummaryRestartFilesImportModeType skip(RiaPreferences::NOT_IMPORT);
SummaryRestartFilesImportModeType separate(RiaPreferences::SEPARATE_CASES);
options.push_back(caf::PdmOptionItemInfo(skip.uiText(), RiaPreferences::NOT_IMPORT));
options.push_back(caf::PdmOptionItemInfo(separate.uiText(), RiaPreferences::SEPARATE_CASES));
}
return options;
}
@@ -232,3 +288,43 @@ const RifReaderSettings* RiaPreferences::readerSettings() const
return m_readerSettings;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaPreferences::appendClassNameToUiText() const
{
return RiaApplication::enableDevelopmentFeatures() && m_appendClassNameToUiText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaPreferences::appendFieldKeywordToToolTipText() const
{
return RiaApplication::enableDevelopmentFeatures() && m_appendFieldKeywordToToolTipText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaPreferences::showTestToolbar() const
{
return RiaApplication::enableDevelopmentFeatures() && m_showTestToolbar();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaPreferences::includeFractureDebugInfoFile() const
{
return RiaApplication::enableDevelopmentFeatures() && m_includeFractureDebugInfoFile();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaPreferences::holoLensExportFolder() const
{
return m_holoLensExportFolder();
}
+25 -9
View File
@@ -37,13 +37,23 @@ class RiaPreferences : public caf::PdmObject
CAF_PDM_HEADER_INIT;
public:
enum SummaryRestartFilesImportMode { IMPORT, NOT_IMPORT, SEPARATE_CASES };
typedef caf::AppEnum<SummaryRestartFilesImportMode> SummaryRestartFilesImportModeType;
RiaPreferences(void);
virtual ~RiaPreferences(void);
~RiaPreferences(void) override;
QStringList tabNames();
const RifReaderSettings* readerSettings() const;
// Debug settings
bool appendClassNameToUiText() const;
bool appendFieldKeywordToToolTipText() const;
bool showTestToolbar() const;
bool includeFractureDebugInfoFile() const;
QString holoLensExportFolder() const;
public: // Pdm Fields
caf::PdmField<caf::AppEnum< RiaApplication::RINavigationPolicy > > navigationPolicy;
@@ -63,25 +73,31 @@ public: // Pdm Fields
caf::PdmField<cvf::Color3f> defaultWellLabelColor;
caf::PdmField<bool> showLasCurveWithoutTvdWarning;
caf::PdmField<QString> fontSizeInScene;
caf::PdmField<bool> showLegendBackground;
caf::PdmField<bool> useShaders;
caf::PdmField<bool> showHud;
caf::PdmField<bool> appendClassNameToUiText;
caf::PdmField<bool> appendFieldKeywordToToolTipText;
caf::PdmField<bool> includeFractureDebugInfoFile;
caf::PdmField<bool> showHud;
caf::PdmField<QString> lastUsedProjectFileName;
caf::PdmField<bool> autocomputeDepthRelatedProperties;
caf::PdmField<bool> loadAndShowSoil;
caf::PdmField<bool> summaryRestartFilesShowImportDialog;
caf::PdmField<SummaryRestartFilesImportModeType> summaryImportMode;
caf::PdmField<SummaryRestartFilesImportModeType> gridImportMode;
protected:
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute);
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering);
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly);
void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override;
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override;
private:
caf::PdmChildField<RifReaderSettings*> m_readerSettings;
caf::PdmField<bool> m_appendClassNameToUiText;
caf::PdmField<bool> m_appendFieldKeywordToToolTipText;
caf::PdmField<bool> m_showTestToolbar;
caf::PdmField<bool> m_includeFractureDebugInfoFile;
caf::PdmField<QString> m_holoLensExportFolder;
QStringList m_tabNames;
};
@@ -20,13 +20,29 @@
#include "RifSummaryReaderInterface.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaSummaryCurveDefinition::RiaSummaryCurveDefinition()
: m_summaryCase(nullptr)
, m_ensemble(nullptr)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaSummaryCurveDefinition::RiaSummaryCurveDefinition(RimSummaryCase* summaryCase, const RifEclipseSummaryAddress& summaryAddress)
RiaSummaryCurveDefinition::RiaSummaryCurveDefinition(RimSummaryCase* summaryCase,
const RifEclipseSummaryAddress& summaryAddress,
RimSummaryCaseCollection* ensemble)
: m_summaryCase(summaryCase)
, m_ensemble(ensemble)
, m_summaryAddress(summaryAddress)
{
m_curveDefinition = std::make_pair(summaryCase, summaryAddress);
}
//--------------------------------------------------------------------------------------------------
@@ -34,7 +50,15 @@ RiaSummaryCurveDefinition::RiaSummaryCurveDefinition(RimSummaryCase* summaryCase
//--------------------------------------------------------------------------------------------------
RimSummaryCase* RiaSummaryCurveDefinition::summaryCase() const
{
return m_curveDefinition.first;
return m_summaryCase;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCaseCollection* RiaSummaryCurveDefinition::ensemble() const
{
return m_ensemble;
}
//--------------------------------------------------------------------------------------------------
@@ -42,9 +66,18 @@ RimSummaryCase* RiaSummaryCurveDefinition::summaryCase() const
//--------------------------------------------------------------------------------------------------
const RifEclipseSummaryAddress& RiaSummaryCurveDefinition::summaryAddress() const
{
return m_curveDefinition.second;
return m_summaryAddress;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaSummaryCurveDefinition::isEnsembleCurve() const
{
return m_ensemble != nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -82,21 +115,22 @@ const std::vector<time_t>& RiaSummaryCurveDefinition::timeSteps(const RiaSummary
//--------------------------------------------------------------------------------------------------
QString RiaSummaryCurveDefinition::curveDefinitionText() const
{
return RiaSummaryCurveDefinition::curveDefinitionText(summaryCase(), summaryAddress());
QString caseName;
if (summaryCase() ) caseName = summaryCase()->caseName();
else if (ensemble()) caseName = ensemble()->name();
return RiaSummaryCurveDefinition::curveDefinitionText(caseName, summaryAddress());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaSummaryCurveDefinition::curveDefinitionText(RimSummaryCase* summaryCase, const RifEclipseSummaryAddress& summaryAddress)
QString RiaSummaryCurveDefinition::curveDefinitionText(const QString& caseName, const RifEclipseSummaryAddress& summaryAddress)
{
QString txt;
if (summaryCase)
{
txt += summaryCase->caseName();
txt += ", ";
}
txt += caseName;
txt += ", ";
txt += QString::fromStdString(summaryAddress.uiText());
@@ -108,11 +142,28 @@ QString RiaSummaryCurveDefinition::curveDefinitionText(RimSummaryCase* summaryCa
//--------------------------------------------------------------------------------------------------
bool RiaSummaryCurveDefinition::operator<(const RiaSummaryCurveDefinition& other) const
{
if (m_curveDefinition.first == other.summaryCase())
if (m_summaryCase != other.summaryCase())
{
return (m_curveDefinition.second < other.summaryAddress());
// Try comparing the dereferenced objects first. They have a predictable sorting operator.
if (m_summaryCase && other.summaryCase())
{
return *m_summaryCase < *other.summaryCase();
}
// Sorting by pointer address, which may appear random to the user.
return m_summaryCase < other.summaryCase();
}
return (m_curveDefinition.first < other.summaryCase());
if (m_ensemble != other.ensemble())
{
// Try comparing the dereferenced objects first. They have a predictable sorting operator.
if (m_ensemble && other.ensemble())
{
return *m_ensemble < *other.ensemble();
}
// Sorting by pointer address, which may appear random to the user.
return (m_ensemble < other.ensemble());
}
return (m_summaryAddress < other.summaryAddress());
}
@@ -26,6 +26,7 @@
#include <vector>
class RimSummaryCase;
class RimSummaryCaseCollection;
//==================================================================================================
///
@@ -33,10 +34,15 @@ class RimSummaryCase;
class RiaSummaryCurveDefinition
{
public:
explicit RiaSummaryCurveDefinition(RimSummaryCase* summaryCase, const RifEclipseSummaryAddress& summaryAddress);
RiaSummaryCurveDefinition();
explicit RiaSummaryCurveDefinition(RimSummaryCase* summaryCase,
const RifEclipseSummaryAddress& summaryAddress,
RimSummaryCaseCollection* ensemble = nullptr);
RimSummaryCase* summaryCase() const;
const RifEclipseSummaryAddress& summaryAddress() const;
RimSummaryCaseCollection* ensemble() const;
bool isEnsembleCurve() const;
bool operator < (const RiaSummaryCurveDefinition& other) const;
@@ -46,10 +52,12 @@ public:
QString curveDefinitionText() const;
static QString curveDefinitionText(RimSummaryCase* summaryCase, const RifEclipseSummaryAddress& summaryAddress);
static QString curveDefinitionText(const QString& caseName, const RifEclipseSummaryAddress& summaryAddress);
private:
private:
std::pair<RimSummaryCase*, RifEclipseSummaryAddress> m_curveDefinition;
RimSummaryCase* m_summaryCase;
RifEclipseSummaryAddress m_summaryAddress;
RimSummaryCaseCollection* m_ensemble;
};
@@ -0,0 +1,145 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaViewRedrawScheduler.h"
#include "Rim3dView.h"
#include <QTimer>
#include <QCoreApplication>
#include <set>
#include "cafProgressState.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaViewRedrawScheduler* RiaViewRedrawScheduler::instance()
{
static RiaViewRedrawScheduler theInstance;
return &theInstance;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaViewRedrawScheduler::clearViewsScheduledForUpdate()
{
if (m_resViewUpdateTimer)
{
while (m_resViewUpdateTimer->isActive())
{
QCoreApplication::processEvents();
}
}
m_resViewsToUpdate.clear();
}
//--------------------------------------------------------------------------------------------------
/// Schedule a creation of the Display model and redraw of the reservoir view
/// The redraw will happen as soon as the event loop is entered
//--------------------------------------------------------------------------------------------------
void RiaViewRedrawScheduler::scheduleDisplayModelUpdateAndRedraw(Rim3dView* resViewToUpdate)
{
m_resViewsToUpdate.push_back(resViewToUpdate);
startTimer(0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaViewRedrawScheduler::startTimer(int msecs)
{
if (!m_resViewUpdateTimer)
{
m_resViewUpdateTimer = new QTimer(this);
connect(m_resViewUpdateTimer, SIGNAL(timeout()), this, SLOT(slotUpdateAndRedrawScheduledViewsWhenReady()));
}
if (!m_resViewUpdateTimer->isActive())
{
m_resViewUpdateTimer->setSingleShot(true);
m_resViewUpdateTimer->start(msecs);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaViewRedrawScheduler::updateAndRedrawScheduledViews()
{
// Compress to remove duplicates
// and update dependent views after independent views
std::set<Rim3dView*> independent3DViewsToUpdate;
std::set<Rim3dView*> dependent3DViewsToUpdate;
for (size_t i = 0; i < m_resViewsToUpdate.size(); ++i)
{
if (!m_resViewsToUpdate[i]) continue;
if (m_resViewsToUpdate[i]->viewController())
dependent3DViewsToUpdate.insert(m_resViewsToUpdate[i]);
else
independent3DViewsToUpdate.insert(m_resViewsToUpdate[i]);
}
for (std::set<Rim3dView*>::iterator it = independent3DViewsToUpdate.begin(); it != independent3DViewsToUpdate.end(); ++it )
{
if (*it)
{
(*it)->createDisplayModelAndRedraw();
}
}
for (std::set<Rim3dView*>::iterator it = dependent3DViewsToUpdate.begin(); it != dependent3DViewsToUpdate.end(); ++it)
{
if (*it)
{
(*it)->createDisplayModelAndRedraw();
}
}
m_resViewsToUpdate.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaViewRedrawScheduler::slotUpdateAndRedrawScheduledViewsWhenReady()
{
if ( caf::ProgressState::isActive() )
{
startTimer(100);
return;
}
updateAndRedrawScheduledViews();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaViewRedrawScheduler::~RiaViewRedrawScheduler()
{
delete m_resViewUpdateTimer;
}
@@ -0,0 +1,54 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QObject>
#include <vector>
#include "cafPdmPointer.h"
class QTimer;
class Rim3dView;
class RiaViewRedrawScheduler : public QObject
{
Q_OBJECT;
public:
static RiaViewRedrawScheduler* instance();
void scheduleDisplayModelUpdateAndRedraw(Rim3dView* resViewToUpdate);
void clearViewsScheduledForUpdate();
void updateAndRedrawScheduledViews();
private slots:
void slotUpdateAndRedrawScheduledViewsWhenReady();
private:
void startTimer(int msecs);
RiaViewRedrawScheduler() : m_resViewUpdateTimer(nullptr) {}
~RiaViewRedrawScheduler() override;
RiaViewRedrawScheduler(const RiaViewRedrawScheduler& o) = delete;
void operator=(const RiaViewRedrawScheduler& o) = delete;
std::vector<caf::PdmPointer<Rim3dView> > m_resViewsToUpdate;
QTimer* m_resViewUpdateTimer;
};
@@ -1,52 +1,81 @@
# 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()
set (SOURCE_GROUP_HEADER_FILES
${CEE_CURRENT_LIST_DIR}RiaArgumentParser.h
${CEE_CURRENT_LIST_DIR}RiaDateStringParser.h
${CEE_CURRENT_LIST_DIR}RiaColorTables.h
${CEE_CURRENT_LIST_DIR}RiaColorTools.h
${CEE_CURRENT_LIST_DIR}RiaEclipseUnitTools.h
${CEE_CURRENT_LIST_DIR}RiaImageCompareReporter.h
${CEE_CURRENT_LIST_DIR}RiaImageFileCompare.h
${CEE_CURRENT_LIST_DIR}RiaLogging.h
${CEE_CURRENT_LIST_DIR}RiaProjectModifier.h
${CEE_CURRENT_LIST_DIR}RiaRegressionTest.h
${CEE_CURRENT_LIST_DIR}RiaImportEclipseCaseTools.h
${CEE_CURRENT_LIST_DIR}RiaQDateTimeTools.h
${CEE_CURRENT_LIST_DIR}RiaSummaryTools.h
${CEE_CURRENT_LIST_DIR}RiaWellNameComparer.h
${CEE_CURRENT_LIST_DIR}RiaStdStringTools.h
${CEE_CURRENT_LIST_DIR}RiaSummaryCurveAnalyzer.h
${CEE_CURRENT_LIST_DIR}RiaSimWellBranchTools.h
${CEE_CURRENT_LIST_DIR}RiaProjectFileVersionTools.h
${CEE_CURRENT_LIST_DIR}RiaStringEncodingTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaArgumentParser.h
${CMAKE_CURRENT_LIST_DIR}/RiaDateStringParser.h
${CMAKE_CURRENT_LIST_DIR}/RiaColorTables.h
${CMAKE_CURRENT_LIST_DIR}/RiaColorTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaEclipseUnitTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaImageCompareReporter.h
${CMAKE_CURRENT_LIST_DIR}/RiaImageFileCompare.h
${CMAKE_CURRENT_LIST_DIR}/RiaLogging.h
${CMAKE_CURRENT_LIST_DIR}/RiaProjectModifier.h
${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTest.h
${CMAKE_CURRENT_LIST_DIR}/RiaImportEclipseCaseTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaQDateTimeTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaWellNameComparer.h
${CMAKE_CURRENT_LIST_DIR}/RiaStdStringTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryCurveAnalyzer.h
${CMAKE_CURRENT_LIST_DIR}/RiaSimWellBranchTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaProjectFileVersionTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaStringEncodingTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaTextStringTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaTextFileCompare.h
${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTestRunner.h
${CMAKE_CURRENT_LIST_DIR}/RiaExtractionTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaFilePathTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveMerger.h
${CMAKE_CURRENT_LIST_DIR}/RiaCurveDataTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveResampler.h
${CMAKE_CURRENT_LIST_DIR}/RiaStatisticsTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaOffshoreSphericalCoords.h
${CMAKE_CURRENT_LIST_DIR}/RiaWeightedMeanCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RiaWeightedMeanCalculator.inl
${CMAKE_CURRENT_LIST_DIR}/RiaWeightedGeometricMeanCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RiaWeightedHarmonicMeanCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RiaOptionItemFactory.h
${CMAKE_CURRENT_LIST_DIR}/RiaGitDiff.h
${CMAKE_CURRENT_LIST_DIR}/RiaQIconTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaCellDividingTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaFieldHandleTools.h
)
set (SOURCE_GROUP_SOURCE_FILES
${CEE_CURRENT_LIST_DIR}RiaArgumentParser.cpp
${CEE_CURRENT_LIST_DIR}RiaDateStringParser.cpp
${CEE_CURRENT_LIST_DIR}RiaColorTables.cpp
${CEE_CURRENT_LIST_DIR}RiaColorTools.cpp
${CEE_CURRENT_LIST_DIR}RiaEclipseUnitTools.cpp
${CEE_CURRENT_LIST_DIR}RiaImageCompareReporter.cpp
${CEE_CURRENT_LIST_DIR}RiaImageFileCompare.cpp
${CEE_CURRENT_LIST_DIR}RiaLogging.cpp
${CEE_CURRENT_LIST_DIR}RiaProjectModifier.cpp
${CEE_CURRENT_LIST_DIR}RiaRegressionTest.cpp
${CEE_CURRENT_LIST_DIR}RiaImportEclipseCaseTools.cpp
${CEE_CURRENT_LIST_DIR}RiaQDateTimeTools.cpp
${CEE_CURRENT_LIST_DIR}RiaSummaryTools.cpp
${CEE_CURRENT_LIST_DIR}RiaWellNameComparer.cpp
${CEE_CURRENT_LIST_DIR}RiaStdStringTools.cpp
${CEE_CURRENT_LIST_DIR}RiaSummaryCurveAnalyzer.cpp
${CEE_CURRENT_LIST_DIR}RiaSimWellBranchTools.cpp
${CEE_CURRENT_LIST_DIR}RiaProjectFileVersionTools.cpp
${CEE_CURRENT_LIST_DIR}RiaStringEncodingTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaArgumentParser.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaDateStringParser.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaColorTables.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaColorTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaEclipseUnitTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaImageCompareReporter.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaImageFileCompare.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaLogging.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaProjectModifier.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTest.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaImportEclipseCaseTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaQDateTimeTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaWellNameComparer.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaStdStringTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryCurveAnalyzer.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaSimWellBranchTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaProjectFileVersionTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaStringEncodingTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaTextStringTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaTextFileCompare.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTestRunner.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaExtractionTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaFilePathTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveMerger.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaCurveDataTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveResampler.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaStatisticsTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaWeightedGeometricMeanCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaWeightedHarmonicMeanCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaOptionItemFactory.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGitDiff.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaQIconTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaCellDividingTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaFieldHandleTools.cpp
)
list(APPEND CODE_HEADER_FILES
@@ -62,4 +91,4 @@ ${QT_MOC_HEADERS}
)
source_group( "Application\\Tools" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CEE_CURRENT_LIST_DIR}CMakeLists_files.cmake )
source_group( "Application\\Tools" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )
@@ -18,16 +18,17 @@
#include "RiaArgumentParser.h"
#include "RiaProjectModifier.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "RiaImportEclipseCaseTools.h"
#include "RiaBaseDefs.h"
#include "RiaImportEclipseCaseTools.h"
#include "RiaPreferences.h"
#include "RiaProjectModifier.h"
#include "RiaRegressionTestRunner.h"
#include "RimProject.h"
#include "RiuMainWindow.h"
#include "RiuMainPlotWindow.h"
#include "RiuPlotMainWindow.h"
#include "RicfMessages.h"
#include "RicfCommandFileExecutor.h"
@@ -70,6 +71,7 @@ bool RiaArgumentParser::parseArguments()
progOpt.registerOption("regressiontest", "<folder>", "System command", cvf::ProgramOptions::SINGLE_VALUE);
progOpt.registerOption("updateregressiontestbase", "<folder>", "System command", cvf::ProgramOptions::SINGLE_VALUE);
progOpt.registerOption("unittest", "", "System command");
progOpt.registerOption("ignoreArgs", "", "Ignore all arguments. Mostly for testing purposes");
progOpt.setOptionPrefix(cvf::ProgramOptions::DOUBLE_DASH);
@@ -104,11 +106,17 @@ bool RiaArgumentParser::parseArguments()
// Handling of the actual command line options
// --------------------------------------------------------
if (cvf::Option o = progOpt.option("ignoreArgs"))
{
return true;
}
if (cvf::Option o = progOpt.option("regressiontest"))
{
CVF_ASSERT(o.valueCount() == 1);
QString regressionTestPath = cvfqt::Utils::toQString(o.value(0));
RiaApplication::instance()->executeRegressionTests(regressionTestPath);
RiaRegressionTestRunner::instance()->executeRegressionTests(regressionTestPath, QStringList());
return false;
}
@@ -116,7 +124,7 @@ bool RiaArgumentParser::parseArguments()
{
CVF_ASSERT(o.valueCount() == 1);
QString regressionTestPath = cvfqt::Utils::toQString(o.value(0));
RiaApplication::instance()->updateRegressionTest(regressionTestPath);
RiaRegressionTestRunner::instance()->updateRegressionTest(regressionTestPath);
return false;
}
@@ -264,21 +272,21 @@ bool RiaArgumentParser::parseArguments()
if (caf::Utils::fileExists(caseName) &&
(fileExtension == "EGRID" || fileExtension == "GRID"))
{
RiaImportEclipseCaseTools::openEclipseCaseFromFile(caseName);
RiaImportEclipseCaseTools::openEclipseCasesFromFile(QStringList({ caseName }), nullptr, true);
}
else
{
QString caseFileNameWithExt = caseName + ".EGRID";
if (caf::Utils::fileExists(caseFileNameWithExt))
{
RiaImportEclipseCaseTools::openEclipseCaseFromFile(caseFileNameWithExt);
RiaImportEclipseCaseTools::openEclipseCasesFromFile(QStringList({ caseFileNameWithExt }), nullptr, true);
}
else
{
caseFileNameWithExt = caseName + ".GRID";
if (caf::Utils::fileExists(caseFileNameWithExt))
{
RiaImportEclipseCaseTools::openEclipseCaseFromFile(caseFileNameWithExt);
RiaImportEclipseCaseTools::openEclipseCasesFromFile(QStringList({ caseFileNameWithExt }), nullptr, true);
}
}
}
@@ -0,0 +1,208 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaCellDividingTools.h"
#include "cvfAssert.h"
#include <cmath>
#include <limits>
//--------------------------------------------------------------------------------------------------
/// Internal functions
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
/// Splits a line in a number of equal parts
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> splitLine(cvf::Vec3d ptStart, cvf::Vec3d ptEnd, size_t partCount);
//--------------------------------------------------------------------------------------------------
/// Calculates all points on a face described by edge points from all four edges.
/// The result is a grid of points including the given edge points
///
/// edgeXPtsHigh
/// |-------------|
/// | |
/// edgeYPtsLow | | edgeYPtsHigh
/// | |
/// |-------------|
/// edgeXPtsLow
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<cvf::Vec3d>> calcFacePoints(const std::vector<cvf::Vec3d> edgeXPtsLow,
const std::vector<cvf::Vec3d> edgeXPtsHigh,
const std::vector<cvf::Vec3d> edgeYPtsLow,
const std::vector<cvf::Vec3d> edgeYPtsHigh);
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d>
RiaCellDividingTools::createHexCornerCoords(std::array<cvf::Vec3d, 8> mainCellCorners, size_t nx, size_t ny, size_t nz)
{
std::array<std::pair<size_t, size_t>, 12> edgeCorners = {
std::make_pair(0, 1),
std::make_pair(3, 2),
std::make_pair(4, 5),
std::make_pair(7, 6), // X
std::make_pair(0, 3),
std::make_pair(4, 7),
std::make_pair(1, 2),
std::make_pair(5, 6), // Y
std::make_pair(0, 4),
std::make_pair(1, 5),
std::make_pair(3, 7),
std::make_pair(2, 6), // Z
};
std::array<size_t, 3> nxyz = {nx, ny, nz};
std::array<std::vector<cvf::Vec3d>, 12> edgePoints;
for (int i = 0; i < 12; i++)
{
int partCountsIndex = i / 4;
edgePoints[i] =
splitLine(mainCellCorners[edgeCorners[i].first], mainCellCorners[edgeCorners[i].second], nxyz[partCountsIndex]);
}
// lowIJ, highIJ, lowJK, highKJ,
std::vector<std::vector<std::vector<cvf::Vec3d>>> nodes;
nodes.reserve((nx + 1) * (ny + 1) * (nz + 1));
auto xyFacePtsLow = calcFacePoints(edgePoints[0], edgePoints[1], edgePoints[4], edgePoints[6]);
auto xyFacePtsHigh = calcFacePoints(edgePoints[2], edgePoints[3], edgePoints[5], edgePoints[7]);
auto yzFacePtsLow = calcFacePoints(edgePoints[4], edgePoints[5], edgePoints[8], edgePoints[10]);
auto yzFacePtsHigh = calcFacePoints(edgePoints[6], edgePoints[7], edgePoints[9], edgePoints[11]);
auto xzFacePtsLow = calcFacePoints(edgePoints[0], edgePoints[2], edgePoints[8], edgePoints[9]);
auto xzFacePtsHigh = calcFacePoints(edgePoints[1], edgePoints[3], edgePoints[10], edgePoints[11]);
nodes.push_back(xyFacePtsLow);
for (size_t z = 1; z < nz; z++)
{
auto xyFacePoints = calcFacePoints(xzFacePtsLow[z], xzFacePtsHigh[z], yzFacePtsLow[z], yzFacePtsHigh[z]);
nodes.push_back(xyFacePoints);
}
nodes.push_back(xyFacePtsHigh);
std::vector<cvf::Vec3d> coords;
coords.reserve(nx * ny * nz * 8);
for (size_t z = 1; z < nz + 1; z++)
{
for (size_t y = 1; y < ny + 1; y++)
{
for (size_t x = 1; x < nx + 1; x++)
{
std::array<cvf::Vec3d, 8> cs;
cs[0] = nodes[z - 1][y - 1][x - 1];
cs[1] = nodes[z - 1][y - 1][x];
cs[2] = nodes[z - 1][y][x];
cs[3] = nodes[z - 1][y][x - 1];
cs[4] = nodes[z][y - 1][x - 1];
cs[5] = nodes[z][y - 1][x];
cs[6] = nodes[z][y][x];
cs[7] = nodes[z][y][x - 1];
coords.insert(coords.end(), cs.begin(), cs.end());
}
}
}
return coords;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaCellDividingTools::computeFlowDistance(const std::array<cvf::Vec3d, 8>& cellVertices,
const cvf::Vec3d& areaCenter)
{
auto subCellCorners = createHexCornerCoords(cellVertices, 2, 2, 2);
double weightedDistanceTotal = 0.0;
double weightTotal = 0.0;
for (size_t c = 0; c < 8; c++)
{
double weight = 1.0;
weightTotal += weight;
cvf::Vec3d centerOfSubCell = cvf::Vec3d::ZERO;
{
cvf::Vec3d vertexSum = cvf::Vec3d::ZERO;
for (size_t v = 0; v < 8; v++) vertexSum += subCellCorners[c * 8 + v];
centerOfSubCell = vertexSum / 8;
}
auto dist = (centerOfSubCell - areaCenter).length();
weightedDistanceTotal += (dist * weight);
}
return weightedDistanceTotal / weightTotal;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> splitLine(cvf::Vec3d ptStart, cvf::Vec3d ptEnd, size_t partCount)
{
std::vector<cvf::Vec3d> pts = {ptStart};
for (size_t i = 1; i < partCount; i++)
{
pts.push_back(cvf::Vec3d(ptStart.x() + (ptEnd.x() - ptStart.x()) * i / partCount,
ptStart.y() + (ptEnd.y() - ptStart.y()) * i / partCount,
ptStart.z() + (ptEnd.z() - ptStart.z()) * i / partCount));
}
pts.push_back(ptEnd);
return pts;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<cvf::Vec3d>> calcFacePoints(const std::vector<cvf::Vec3d> edgeXPtsLow,
const std::vector<cvf::Vec3d> edgeXPtsHigh,
const std::vector<cvf::Vec3d> edgeYPtsLow,
const std::vector<cvf::Vec3d> edgeYPtsHigh)
{
CVF_ASSERT(edgeXPtsLow.size() == edgeXPtsHigh.size() && edgeYPtsLow.size() == edgeYPtsHigh.size());
size_t xSize = edgeXPtsLow.size();
size_t ySize = edgeYPtsLow.size();
std::vector<std::vector<cvf::Vec3d>> pts;
// Add low edge points
pts.push_back(edgeXPtsLow);
// Interior points
for (size_t y = 1; y < ySize - 1; y++)
{
auto interiorPts = splitLine(edgeYPtsLow[y], edgeYPtsHigh[y], xSize - 1);
pts.push_back(interiorPts);
}
// Add low edge points
pts.push_back(edgeXPtsHigh);
return pts;
}
@@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <cvfBase.h>
#include <cvfVector3.h>
#include <vector>
#include <array>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaCellDividingTools
{
public:
static std::vector<cvf::Vec3d>
createHexCornerCoords(std::array<cvf::Vec3d, 8> mainCellCorners, size_t nx, size_t ny, size_t nz);
static double computeFlowDistance(const std::array<cvf::Vec3d, 8>& cellVertices, const cvf::Vec3d& areaCenter);
};
@@ -158,35 +158,53 @@ const caf::ColorTable& RiaColorTables::redWhiteBluePaletteColors()
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::categoryPaletteColors()
{
// Based on http://stackoverflow.com/questions/470690/how-to-automatically-generate-n-distinct-colors
// and Kelly Colors and sorted by hue
// See also http://www.w3schools.com/colors/ for palettes etc.
static caf::ColorTable colorTable = caf::ColorTable(categoryColors());
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::tensorWhiteGrayBlackPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub(128, 62, 117), // hwb(310, 24%, 50%) strong_purple
cvf::Color3ub(212, 28, 132), // hwb(326, 11%, 17%) strong_purplish_red
cvf::Color3ub(246, 118, 142), // hwb(349, 46%, 4%) strong_purplish_pink
cvf::Color3ub(193, 0, 32), // hwb(350, 0%, 24%) vivid_red
cvf::Color3ub(127, 24, 13), // hwb( 6, 5%, 50%) strong_reddish_brown
cvf::Color3ub(241, 58, 19), // hwb( 11, 7%, 5%) vivid_reddish_orange
cvf::Color3ub(255, 122, 92), // hwb( 11, 36%, 0%) strong_yellowish_pink
cvf::Color3ub(129, 112, 102), // hwb( 22, 40%, 49%) medium_gray
cvf::Color3ub(255, 104, 0), // hwb( 24, 0%, 0%) vivid_orange
cvf::Color3ub( 89, 51, 21), // hwb( 26, 8%, 65%) deep_yellowish_brown
cvf::Color3ub(255, 142, 0), // hwb( 33, 0%, 0%) vivid_orange_yellow
cvf::Color3ub(206, 162, 98), // hwb( 36, 38%, 19%) grayish_yellow
cvf::Color3ub(244, 200, 0), // hwb( 49, 0%, 4%) vivid_greenish_yellow
cvf::Color3ub(147, 170, 0), // hwb( 68, 0%, 33%) vivid_yellowish_green
cvf::Color3ub( 59, 84, 23), // hwb( 85, 9%, 67%) dark_olive_green
cvf::Color3ub( 0, 125, 52), // hwb(145, 0%, 51%) vivid_green
cvf::Color3ub( 54, 125, 123), // hwb(178, 21%, 51%) vivid_blueish_green
cvf::Color3ub( 0, 83, 138), // hwb(204, 0%, 46%) strong_blue
cvf::Color3ub(166, 189, 215), // hwb(212, 65%, 16%) very_light_blue
cvf::Color3ub( 46, 76, 224) // hwb(230, 18%, 12%) medium_blue
cvf::Color3ub::WHITE,
cvf::Color3ub::LIGHT_GRAY,
cvf::Color3ub::BLACK,
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::tensorOrangeBlueWhitePaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub(236, 118, 0), // Orange
cvf::Color3ub(56, 56, 255), // Vivid Blue
cvf::Color3ub(210, 248, 250), // White Turquoiseish
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::tensorsMagentaBrownGrayPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub(248, 0, 170), // Magenta
cvf::Color3ub::BROWN,
cvf::Color3ub::LIGHT_GRAY,
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
@@ -383,7 +401,6 @@ const caf::ColorTable& RiaColorTables::summaryCurveNoneRedGreenBlueBrownPaletteC
const caf::ColorTable& RiaColorTables::wellLogPlotPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::black)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::darkBlue)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::darkRed)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::darkGreen)),
@@ -397,7 +414,8 @@ const caf::ColorTable& RiaColorTables::wellLogPlotPaletteColors()
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::yellow)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::magenta)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::cyan)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::gray))
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::gray)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::black))
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
@@ -451,3 +469,126 @@ const caf::ColorTable& RiaColorTables::timestepsPaletteColors()
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::editableWellPathsPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub( 204, 0, 204), // Dark magenta
cvf::Color3ub( 173, 23, 212), // Strong Purple
cvf::Color3ub( 143, 46, 219), //Purple
cvf::Color3ub( 102, 76, 230), // Gray Blue
cvf::Color3ub( 71, 99, 237), // Lighter Gray Blue
cvf::Color3ub( 31, 130, 247), // Strong Blue
cvf::Color3ub( 0, 153, 255), // Dark Turquise
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::wellPathsPaletteColors()
{
// Use inverted category colors to avoid identical colors if we have few sim wells and few well paths
static caf::ColorTable colorTable = caf::ColorTable(invertedCategoryColors());
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3f RiaColorTables::undefinedCellColor()
{
return cvf::Color3::GRAY;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaColorTables::WellPathComponentColors RiaColorTables::wellPathComponentColors()
{
return {{RiaDefines::WELL_PATH, cvf::Color3::CEETRON},
{RiaDefines::PERFORATION_INTERVAL, cvf::Color3::DARK_MAGENTA},
{RiaDefines::FISHBONES, cvf::Color3::DARK_GREEN},
{RiaDefines::FRACTURE, cvf::Color3::CRIMSON},
{RiaDefines::ICD, cvf::Color3::DARK_ORANGE},
{RiaDefines::AICD, cvf::Color3::INDIGO},
{RiaDefines::ICV, cvf::Color3::ORCHID},
{RiaDefines::CASING, cvf::Color3::SEA_GREEN},
{RiaDefines::LINER, cvf::Color3::OLIVE},
{RiaDefines::PACKER, cvf::Color3::GRAY}};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Color3ub> RiaColorTables::categoryColors()
{
// Based on http://stackoverflow.com/questions/470690/how-to-automatically-generate-n-distinct-colors
// and Kelly Colors and sorted by hue
// See also http://www.w3schools.com/colors/ for palettes etc.
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub(128, 62, 117), // hwb(310, 24%, 50%) strong_purple
cvf::Color3ub(212, 28, 132), // hwb(326, 11%, 17%) strong_purplish_red
cvf::Color3ub(246, 118, 142), // hwb(349, 46%, 4%) strong_purplish_pink
cvf::Color3ub(193, 0, 32), // hwb(350, 0%, 24%) vivid_red
cvf::Color3ub(127, 24, 13), // hwb( 6, 5%, 50%) strong_reddish_brown
cvf::Color3ub(241, 58, 19), // hwb( 11, 7%, 5%) vivid_reddish_orange
cvf::Color3ub(255, 122, 92), // hwb( 11, 36%, 0%) strong_yellowish_pink
cvf::Color3ub(129, 112, 102), // hwb( 22, 40%, 49%) medium_gray
cvf::Color3ub(255, 104, 0), // hwb( 24, 0%, 0%) vivid_orange
cvf::Color3ub( 89, 51, 21), // hwb( 26, 8%, 65%) deep_yellowish_brown
cvf::Color3ub(255, 142, 0), // hwb( 33, 0%, 0%) vivid_orange_yellow
cvf::Color3ub(206, 162, 98), // hwb( 36, 38%, 19%) grayish_yellow
cvf::Color3ub(244, 200, 0), // hwb( 49, 0%, 4%) vivid_greenish_yellow
cvf::Color3ub(147, 170, 0), // hwb( 68, 0%, 33%) vivid_yellowish_green
cvf::Color3ub( 59, 84, 23), // hwb( 85, 9%, 67%) dark_olive_green
cvf::Color3ub( 0, 125, 52), // hwb(145, 0%, 51%) vivid_green
cvf::Color3ub( 54, 125, 123), // hwb(178, 21%, 51%) vivid_blueish_green
cvf::Color3ub( 0, 83, 138), // hwb(204, 0%, 46%) strong_blue
cvf::Color3ub(166, 189, 215), // hwb(212, 65%, 16%) very_light_blue
cvf::Color3ub( 46, 76, 224) // hwb(230, 18%, 12%) medium_blue
};
return colors;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Color3ub> RiaColorTables::invertedCategoryColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub( 46, 76, 224), // hwb(230, 18%, 12%) medium_blue
cvf::Color3ub(166, 189, 215), // hwb(212, 65%, 16%) very_light_blue
cvf::Color3ub( 0, 83, 138), // hwb(204, 0%, 46%) strong_blue
cvf::Color3ub( 54, 125, 123), // hwb(178, 21%, 51%) vivid_blueish_green
cvf::Color3ub( 0, 125, 52), // hwb(145, 0%, 51%) vivid_green
cvf::Color3ub( 59, 84, 23), // hwb( 85, 9%, 67%) dark_olive_green
cvf::Color3ub(147, 170, 0), // hwb( 68, 0%, 33%) vivid_yellowish_green
cvf::Color3ub(244, 200, 0), // hwb( 49, 0%, 4%) vivid_greenish_yellow
cvf::Color3ub(206, 162, 98), // hwb( 36, 38%, 19%) grayish_yellow
cvf::Color3ub(255, 142, 0), // hwb( 33, 0%, 0%) vivid_orange_yellow
cvf::Color3ub( 89, 51, 21), // hwb( 26, 8%, 65%) deep_yellowish_brown
cvf::Color3ub(255, 104, 0), // hwb( 24, 0%, 0%) vivid_orange
cvf::Color3ub(129, 112, 102), // hwb( 22, 40%, 49%) medium_gray
cvf::Color3ub(255, 122, 92), // hwb( 11, 36%, 0%) strong_yellowish_pink
cvf::Color3ub(241, 58, 19), // hwb( 11, 7%, 5%) vivid_reddish_orange
cvf::Color3ub(127, 24, 13), // hwb( 6, 5%, 50%) strong_reddish_brown
cvf::Color3ub(193, 0, 32), // hwb(350, 0%, 24%) vivid_red
cvf::Color3ub(246, 118, 142), // hwb(349, 46%, 4%) strong_purplish_pink
cvf::Color3ub(212, 28, 132), // hwb(326, 11%, 17%) strong_purplish_red
cvf::Color3ub(128, 62, 117) // hwb(310, 24%, 50%) strong_purple
};
return colors;
}
@@ -18,8 +18,9 @@
#pragma once
#include "RiaDefines.h"
#include "cafColorTable.h"
#include <map>
//==================================================================================================
///
@@ -28,6 +29,8 @@
class RiaColorTables
{
public:
typedef std::map<RiaDefines::WellPathComponentType, cvf::Color3::ColorIdent> WellPathComponentColors;
static const caf::ColorTable& normalPaletteColors();
static const caf::ColorTable& normalPaletteOppositeOrderingColors();
static const caf::ColorTable& blackWhitePaletteColors();
@@ -37,6 +40,9 @@ public:
static const caf::ColorTable& blueWhiteRedPaletteColors();
static const caf::ColorTable& redWhiteBluePaletteColors();
static const caf::ColorTable& categoryPaletteColors();
static const caf::ColorTable& tensorWhiteGrayBlackPaletteColors();
static const caf::ColorTable& tensorOrangeBlueWhitePaletteColors();
static const caf::ColorTable& tensorsMagentaBrownGrayPaletteColors();
static const caf::ColorTable& angularPaletteColors();
static const caf::ColorTable& stimPlanPaletteColors();
static const caf::ColorTable& faultsPaletteColors();
@@ -50,5 +56,14 @@ public:
static const caf::ColorTable& wellLogPlotPaletteColors();
static const caf::ColorTable& selectionPaletteColors();
static const caf::ColorTable& timestepsPaletteColors();
static const caf::ColorTable& editableWellPathsPaletteColors();
static const caf::ColorTable& wellPathsPaletteColors();
static cvf::Color3f undefinedCellColor();
static WellPathComponentColors wellPathComponentColors();
private:
static std::vector<cvf::Color3ub> categoryColors();
static std::vector<cvf::Color3ub> invertedCategoryColors();
};
@@ -17,6 +17,8 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RiaColorTools.h"
#include "cvfMath.h"
#include <algorithm>
//--------------------------------------------------------------------------------------------------
///
@@ -31,6 +33,33 @@ bool RiaColorTools::isBrightnessAboveThreshold(cvf::Color3f backgroundColor)
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3f RiaColorTools::computeOffsetColor(cvf::Color3f color, float offsetFactor)
{
float gridR = 0.0;
float gridG = 0.0;
float gridB = 0.0;
if (isBrightnessAboveThreshold(color))
{
gridR = color.r() - (color.r() * offsetFactor);
gridG = color.g() - (color.g() * offsetFactor);
gridB = color.b() - (color.b() * offsetFactor);
}
else
{
gridR = color.r() + (1.0f - color.r()) * offsetFactor;
gridG = color.g() + (1.0f - color.g()) * offsetFactor;
gridB = color.b() + (1.0f - color.b()) * offsetFactor;
}
return cvf::Color3f(cvf::Math::clamp(gridR, 0.0f, 1.0f),
cvf::Math::clamp(gridG, 0.0f, 1.0f),
cvf::Math::clamp(gridB, 0.0f, 1.0f));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -59,3 +88,21 @@ cvf::Color3f RiaColorTools::constrastColor(cvf::Color3f backgroundColor)
return brightContrastColor();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QColor RiaColorTools::toQColor(cvf::Color3f color, float alpha)
{
QColor qcolor(color.rByte(), color.gByte(), color.bByte());
qcolor.setAlphaF(alpha);
return qcolor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QColor RiaColorTools::toQColor(cvf::Color4f color)
{
return toQColor(color.toColor3f(), color.a());
}
@@ -21,6 +21,7 @@
#include "cvfBase.h"
#include "cvfArray.h"
#include <QColor>
//==================================================================================================
///
@@ -30,8 +31,11 @@ class RiaColorTools
{
public:
static bool isBrightnessAboveThreshold(cvf::Color3f backgroundColor);
static cvf::Color3f computeOffsetColor(cvf::Color3f color, float offsetFactor);
static cvf::Color3f darkContrastColor();
static cvf::Color3f brightContrastColor();
static cvf::Color3f constrastColor(cvf::Color3f backgroundColor);
static QColor toQColor(cvf::Color3f color, float alpha = 1.0f);
static QColor toQColor(cvf::Color4f color);
};
@@ -17,7 +17,7 @@
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigCurveDataTools.h"
#include "RiaCurveDataTools.h"
#include <cmath> // Needed for HUGE_VAL on Linux
@@ -26,7 +26,7 @@
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigCurveDataTools::CurveIntervals RigCurveDataTools::calculateIntervalsOfValidValues(const std::vector<double>& values,
RiaCurveDataTools::CurveIntervals RiaCurveDataTools::calculateIntervalsOfValidValues(const std::vector<double>& values,
bool includePositiveValuesOnly)
{
CurveIntervals intervals;
@@ -37,7 +37,7 @@ RigCurveDataTools::CurveIntervals RigCurveDataTools::calculateIntervalsOfValidVa
size_t valueCount = values.size();
while (vIdx < valueCount)
{
bool isValid = RigCurveDataTools::isValidValue(values[vIdx], includePositiveValuesOnly);
bool isValid = RiaCurveDataTools::isValidValue(values[vIdx], includePositiveValuesOnly);
if (!isValid)
{
@@ -67,7 +67,7 @@ RigCurveDataTools::CurveIntervals RigCurveDataTools::calculateIntervalsOfValidVa
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::pair<size_t, size_t>> RigCurveDataTools::computePolyLineStartStopIndices(const CurveIntervals& intervals)
std::vector<std::pair<size_t, size_t>> RiaCurveDataTools::computePolyLineStartStopIndices(const CurveIntervals& intervals)
{
std::vector<std::pair<size_t, size_t>> lineStartAndStopIndices;
@@ -90,7 +90,7 @@ std::vector<std::pair<size_t, size_t>> RigCurveDataTools::computePolyLineStartSt
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigCurveDataTools::isValidValue(double value, bool allowPositiveValuesOnly)
bool RiaCurveDataTools::isValidValue(double value, bool allowPositiveValuesOnly)
{
if (value == HUGE_VAL || value == -HUGE_VAL || value != value)
{
@@ -32,7 +32,7 @@ class QDateTime;
//==================================================================================================
///
//==================================================================================================
class RigCurveDataTools
class RiaCurveDataTools
{
public:
typedef std::vector<std::pair<size_t, size_t>> CurveIntervals;
@@ -60,8 +60,6 @@ public:
static std::vector<std::pair<size_t, size_t>> computePolyLineStartStopIndices(const CurveIntervals& intervals);
public:
// Helper methods, available as public to be able to access from unit tests
static bool isValidValue(double value, bool allowPositiveValuesOnly);
};
@@ -139,7 +139,7 @@ bool RiaDateStringParser::tryParseMonthFirst(const std::string& s, int& year, in
//--------------------------------------------------------------------------------------------------
bool RiaDateStringParser::tryParseYear(const std::string& s, int &year)
{
if (containsAlphabetic(s)) return false;
if (RiaStdStringTools::containsAlphabetic(s)) return false;
auto today = QDate::currentDate();
int y = RiaStdStringTools::toInt(s);
@@ -158,10 +158,13 @@ bool RiaDateStringParser::tryParseYear(const std::string& s, int &year)
//--------------------------------------------------------------------------------------------------
bool RiaDateStringParser::tryParseMonth(const std::string& s, int &month)
{
if (containsAlphabetic(s))
if (RiaStdStringTools::containsAlphabetic(s))
{
auto sMonth = s;
sMonth = trimString(sMonth);
std::transform(sMonth.begin(), sMonth.end(), sMonth.begin(),
[](const char c) -> char { return (char)::tolower(c); });
for (int i = 0; i < 12; i++)
{
if (MONTH_NAMES[i].compare(0, sMonth.size(), sMonth) == 0)
@@ -190,7 +193,7 @@ bool RiaDateStringParser::tryParseMonth(const std::string& s, int &month)
//--------------------------------------------------------------------------------------------------
bool RiaDateStringParser::tryParseDay(const std::string& s, int &day)
{
if (containsAlphabetic(s)) return false;
if (RiaStdStringTools::containsAlphabetic(s)) return false;
int d = RiaStdStringTools::toInt(s);
if (d >= 1 && d <= 31)
@@ -203,14 +206,6 @@ bool RiaDateStringParser::tryParseDay(const std::string& s, int &day)
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaDateStringParser::containsAlphabetic(const std::string& s)
{
return std::find_if(s.begin(), s.end(), [](char c) { return isalpha(c); }) != s.end();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -218,8 +213,5 @@ std::string RiaDateStringParser::trimString(const std::string& s)
{
auto sCopy = s.substr(0, s.find_last_not_of(' ') + 1);
sCopy = sCopy.substr(sCopy.find_first_not_of(' '));
std::transform(sCopy.begin(), sCopy.end(), sCopy.begin(), ::tolower);
return sCopy;
}
@@ -42,7 +42,6 @@ private:
static bool tryParseMonth(const std::string& s, int &month);
static bool tryParseDay(const std::string& s, int &day);
static bool containsAlphabetic(const std::string& s);
static std::string trimString(const std::string& s);
};
@@ -124,3 +124,66 @@ QString RiaEclipseUnitTools::unitStringPressure(UnitSystem unitSystem)
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaEclipseUnitTools::convertToMeter(double sourceValue, const QString& sourceValueUnitText)
{
QString timmed = sourceValueUnitText.trimmed();
if (timmed.compare("m", Qt::CaseInsensitive) == 0 || timmed.compare("md-m", Qt::CaseInsensitive) == 0)
{
return sourceValue;
}
else if (timmed.compare("cm", Qt::CaseInsensitive) == 0)
{
return sourceValue / 100.0;
}
else if (timmed.compare("mm", Qt::CaseInsensitive) == 0)
{
return sourceValue / 1000.0;
}
else if (timmed.compare("in", Qt::CaseInsensitive) == 0)
{
return RiaEclipseUnitTools::inchToMeter(sourceValue);
}
else if (timmed.compare("ft", Qt::CaseInsensitive) == 0 || timmed.compare("md-ft", Qt::CaseInsensitive) == 0)
{
return RiaEclipseUnitTools::feetToMeter(sourceValue);
}
return HUGE_VAL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaEclipseUnitTools::convertToFeet(double sourceValue, const QString& sourceValueUnitText)
{
QString timmed = sourceValueUnitText.trimmed();
if (timmed.compare("ft", Qt::CaseInsensitive) == 0 || timmed.compare("md-ft", Qt::CaseInsensitive) == 0)
{
return sourceValue;
}
else if (timmed.compare("in", Qt::CaseInsensitive) == 0)
{
return RiaEclipseUnitTools::inchToFeet(sourceValue);
}
else if (timmed.compare("cm", Qt::CaseInsensitive) == 0)
{
double meter = sourceValue / 100.0;
return RiaEclipseUnitTools::meterToFeet(meter);
}
else if (timmed.compare("mm", Qt::CaseInsensitive) == 0)
{
double meter = sourceValue / 1000.0;
return RiaEclipseUnitTools::meterToFeet(meter);
}
else if (timmed.compare("m", Qt::CaseInsensitive) == 0 || timmed.compare("md-m", Qt::CaseInsensitive) == 0)
{
return RiaEclipseUnitTools::meterToFeet(sourceValue);
}
return HUGE_VAL;
}
@@ -51,5 +51,8 @@ public:
static double convertSurfaceGasFlowRateToOilEquivalents(UnitSystem, double eclGasFlowRate);
static QString unitStringPressure(UnitSystem unitSystem);
static double convertToMeter(double sourceValue, const QString& unitText);
static double convertToFeet(double sourceValue, const QString& unitText);
};
@@ -0,0 +1,92 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaExtractionTools.h"
#include "RiaApplication.h"
#include "RigWellPath.h"
#include "RimEclipseCase.h"
#include "RimMainPlotCollection.h"
#include "RimProject.h"
#include "RimSimWellInView.h"
#include "RimWellLogPlotCollection.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigEclipseWellLogExtractor* RiaExtractionTools::wellLogExtractorEclipseCase(RimWellPath* wellPath, RimEclipseCase* eclipseCase)
{
auto wlPlotCollection = wellLogPlotCollection();
if (!wlPlotCollection) return nullptr;
return wlPlotCollection->findOrCreateExtractor(wellPath, eclipseCase);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigGeoMechWellLogExtractor* RiaExtractionTools::wellLogExtractorGeoMechCase(RimWellPath* wellPath, RimGeoMechCase* geomCase)
{
auto wlPlotCollection = wellLogPlotCollection();
if (!wlPlotCollection) return nullptr;
return wlPlotCollection->findOrCreateExtractor(wellPath, geomCase);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigEclipseWellLogExtractor* RiaExtractionTools::findOrCreateSimWellExtractor(const RimSimWellInView* simWell,
const RigWellPath* wellPathGeom)
{
auto wlPlotCollection = wellLogPlotCollection();
if (!wlPlotCollection) return nullptr;
if (!(simWell && wellPathGeom))
{
return nullptr;
}
RimEclipseCase* eclipseCase = nullptr;
simWell->firstAncestorOrThisOfType(eclipseCase);
if (!(eclipseCase && eclipseCase->eclipseCaseData()))
{
return nullptr;
}
QString caseUserDescription = eclipseCase->caseUserDescription();
return wlPlotCollection->findOrCreateSimWellExtractor(
simWell->name, caseUserDescription, wellPathGeom, eclipseCase->eclipseCaseData());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogPlotCollection* RiaExtractionTools::wellLogPlotCollection()
{
auto proj = RiaApplication::instance()->project();
if (!proj) return nullptr;
auto plotCollection = proj->mainPlotCollection();
if (!plotCollection) return nullptr;
auto wellLogPlotCollection = plotCollection->wellLogPlotCollection();
return wellLogPlotCollection;
}
@@ -0,0 +1,44 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
class RigEclipseWellLogExtractor;
class RigGeoMechWellLogExtractor;
class RigWellPath;
class RimEclipseCase;
class RimGeoMechCase;
class RimSimWellInView;
class RimWellLogPlotCollection;
class RimWellPath;
class QString;
//==================================================================================================
//
//==================================================================================================
namespace RiaExtractionTools
{
RigEclipseWellLogExtractor* wellLogExtractorEclipseCase(RimWellPath* wellPath, RimEclipseCase* eclipseCase);
RigGeoMechWellLogExtractor* wellLogExtractorGeoMechCase(RimWellPath* wellPath, RimGeoMechCase* geomCase);
RigEclipseWellLogExtractor* findOrCreateSimWellExtractor(const RimSimWellInView* simWell, const RigWellPath* wellPathGeom);
RimWellLogPlotCollection* wellLogPlotCollection();
}; // namespace RiaExtractionTools
@@ -0,0 +1,44 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Equinor ASA
// Copyright (C) 2018- Ceetron Solutions AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaFieldHandleTools.h"
#include "cafPdmFieldHandle.h"
#include "cafPdmUiFieldHandle.h"
#include "cafPdmXmlFieldHandle.h"
#include "cvfAssert.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaFieldhandleTools::disableWriteAndSetFieldHidden(caf::PdmFieldHandle* fieldHandle)
{
CVF_ASSERT(fieldHandle);
if (fieldHandle->uiCapability())
{
fieldHandle->uiCapability()->setUiHidden(true);
}
if (fieldHandle->xmlCapability())
{
fieldHandle->xmlCapability()->setIOWritable(false);
}
}
@@ -0,0 +1,34 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Equinor ASA
// Copyright (C) 2018- Ceetron Solutions AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
namespace caf
{
class PdmFieldHandle;
}
//==================================================================================================
//
//==================================================================================================
class RiaFieldhandleTools
{
public:
static void disableWriteAndSetFieldHidden(caf::PdmFieldHandle* fieldHandle);
};
@@ -0,0 +1,114 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaFilePathTools.h"
#include <QDir>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QChar RiaFilePathTools::SEPARATOR = '/';
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaFilePathTools::toInternalSeparator(const QString& path)
{
QString currNativeSep = QDir::separator();
if (currNativeSep == "/")
{
// On Linux like system -> Do not convert separators
return path;
}
// On other systems (i.e. Windows) -> Convert to internal separator (/)
QString output = path;
return output.replace(QString("\\"), SEPARATOR);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString& RiaFilePathTools::appendSeparatorIfNo(QString& path)
{
if (!path.endsWith(SEPARATOR))
{
path.append(SEPARATOR);
}
return path;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaFilePathTools::relativePath(const QString& rootDir, const QString& dir)
{
if (dir.startsWith(rootDir))
{
QString relPath = dir;
relPath.remove(0, rootDir.size());
if (relPath.startsWith(SEPARATOR)) relPath.remove(0, 1);
return appendSeparatorIfNo(relPath);
}
else
{
return dir;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaFilePathTools::equalPaths(const QString& path1, const QString& path2)
{
QString p1 = path1;
QString p2 = path2;
appendSeparatorIfNo(p1);
appendSeparatorIfNo(p2);
return p1 == p2;
}
//--------------------------------------------------------------------------------------------------
/// Own canonicalPath method since the QDir::canonicalPath seems to not work
//--------------------------------------------------------------------------------------------------
QString RiaFilePathTools::canonicalPath(const QString& path)
{
return QDir(path).absolutePath();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<QString, QString> RiaFilePathTools::toFolderAndFileName(const QString& absFileName)
{
auto absFN = toInternalSeparator(absFileName);
int lastSep = absFN.lastIndexOf(SEPARATOR);
if (lastSep > 0)
{
return std::make_pair(absFN.left(lastSep), absFN.mid(lastSep+1));
}
else
{
return std::make_pair("", absFN);
}
}
@@ -0,0 +1,43 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QString>
#include <QByteArray>
#include <string>
//==================================================================================================
//
//
//
//==================================================================================================
class RiaFilePathTools
{
public:
static const QChar SEPARATOR;
static QString toInternalSeparator(const QString& path);
static QString& appendSeparatorIfNo(QString& path);
static QString relativePath(const QString& rootDir, const QString& dir);
static bool equalPaths(const QString& path1, const QString& path2);
static QString canonicalPath(const QString& path);
static std::pair<QString, QString> toFolderAndFileName(const QString& absFileName);
};
@@ -0,0 +1,124 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaGitDiff.h"
#include "cafUtils.h"
#include <QDir>
#include <QProcess>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaGitDiff::RiaGitDiff(const QString& pathToDiffTool)
: m_pathToGitTool(pathToDiffTool)
{
reset();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaGitDiff::~RiaGitDiff() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaGitDiff::reset()
{
m_lastError = IC_NO_ERROR;
m_errorMsg.clear();
m_errorDetails.clear();
m_diffOutput.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaGitDiff::executeDiff(const QString& baseFolder)
{
reset();
QString fullFilePath = "git";
if (!m_pathToGitTool.isEmpty())
{
fullFilePath = m_pathToGitTool + "/" + fullFilePath;
}
QString incomingCurrentPath = QDir::currentPath();
QDir::setCurrent(baseFolder);
QString args = "diff";
QString completeCommand = QString("\"%1\" %2").arg(fullFilePath).arg(args);
// Launch process and wait
QProcess proc;
proc.start(completeCommand);
proc.waitForFinished(30000);
QDir::setCurrent(incomingCurrentPath);
QProcess::ProcessError procError = proc.error();
if (procError != QProcess::UnknownError)
{
m_lastError = SEVERE_ERROR;
m_errorMsg = "Error running 'git' tool process";
m_errorDetails = completeCommand;
return false;
}
QByteArray stdErr = proc.readAllStandardError();
QByteArray stdOut = proc.readAllStandardOutput();
m_diffOutput = stdOut;
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaGitDiff::ErrorType RiaGitDiff::error() const
{
return m_lastError;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaGitDiff::errorMessage() const
{
return m_errorMsg;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaGitDiff::errorDetails() const
{
return m_errorDetails;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaGitDiff::diffOutput() const
{
return m_diffOutput;
}
@@ -0,0 +1,57 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QString>
//==================================================================================================
//
// Use external tool 'git' to produce a text string representing the diff
//
//==================================================================================================
class RiaGitDiff
{
public:
enum ErrorType
{
IC_NO_ERROR, // No error occurred
IC_ERROR, // An error occurred
SEVERE_ERROR // Severe error occurred, it is likely that another call to compare() will also fail
};
public:
explicit RiaGitDiff(const QString& pathToGitTool);
~RiaGitDiff();
bool executeDiff(const QString& baseFolder);
ErrorType error() const;
QString errorMessage() const;
QString errorDetails() const;
QString diffOutput() const;
private:
void reset();
private:
const QString m_pathToGitTool;
ErrorType m_lastError;
QString m_errorMsg;
QString m_errorDetails;
QString m_diffOutput;
};
@@ -55,7 +55,7 @@ std::string removeCommonStart(const std::string& mask, const std::string& filena
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaImageCompareReporter::generateHTMLReport(const std::string& fileName)
void RiaImageCompareReporter::generateHTMLReport(const std::string& fileName, const std::string& diff2htmlHeaderText)
{
if (m_directorySets.size() == 0) return;
@@ -70,16 +70,18 @@ void RiaImageCompareReporter::generateHTMLReport(const std::string& fileName)
html += "<html>\n";
html += "<head>\n";
html += "<title>Regression-Test Report</title>\n";
if (m_showInteractiveDiff)
{
html += cssString();
}
html += diff2htmlHeaderText;
html += "</head>\n";
html += "\n";
html += "<body>\n";
html += "<title>Regression-Test Report</title>\n";
html += "\n";
for (size_t dsIdx = 0; dsIdx < m_directorySets.size(); ++dsIdx)
@@ -177,36 +179,36 @@ std::string RiaImageCompareReporter::cssString() const
html += "";
html += ".image-slider {";
html += "position:relative;";
html += "display: inline-block;";
html += "line-height: 0;";
html += "position:relative;";
html += "display: inline-block;";
html += "line-height: 0;";
html += "}";
html += ".image-slider > div {";
html += "position: absolute;";
html += "top: 0; bottom: 0; left: 0;";
html += "width: 25px;";
html += "max-width: 100%;";
html += "overflow: hidden;";
html += "resize: horizontal;";
html += "position: absolute;";
html += "top: 0; bottom: 0; left: 0;";
html += "width: 25px;";
html += "max-width: 100%;";
html += "overflow: hidden;";
html += "resize: horizontal;";
html += "}";
html += ".image-slider > div:before {";
html += "content: '';";
html += "position: absolute;";
html += "right: 0; bottom: 0;";
html += "width: 23px; height: 23px;";
html += "padding: 5px;";
html += "background: linear-gradient(-45deg, gray 50%, transparent 0);";
html += "background-clip: content-box;";
html += "cursor: ew-resize;";
html += "-webkit-filter: drop-shadow(0 0 6px black);";
html += "filter: drop-shadow(0 0 6px black);";
html += "content: '';";
html += "position: absolute;";
html += "right: 0; bottom: 0;";
html += "width: 23px; height: 23px;";
html += "padding: 5px;";
html += "background: linear-gradient(-45deg, gray 50%, transparent 0);";
html += "background-clip: content-box;";
html += "cursor: ew-resize;";
html += "-webkit-filter: drop-shadow(0 0 6px black);";
html += "filter: drop-shadow(0 0 6px black);";
html += "}";
html += ".image-slider img {";
html += "user-select: none;";
html += "max-width: 1000px;";
html += "user-select: none;";
html += "max-width: 1000px;";
html += "}";
html += "</style>";
@@ -28,7 +28,7 @@ public:
virtual ~RiaImageCompareReporter();
void addImageDirectoryComparisonSet(const std::string& title, const std::string& baseImageDir, const std::string& newImagesDir, const std::string& diffImagesDir );
void generateHTMLReport(const std::string& filenName);
void generateHTMLReport(const std::string& filenName, const std::string& pathToDiff2html);
void showInteractiveOnly();
@@ -21,8 +21,12 @@
#include "../SummaryPlotCommands/RicNewSummaryPlotFeature.h"
#include "RiaApplication.h"
#include "RiaLogging.h"
#include "RiaPreferences.h"
#include "RifEclipseSummaryTools.h"
#include "RifSummaryCaseRestartSelector.h"
#include "RigGridManager.h"
#include "RimCaseCollection.h"
@@ -30,26 +34,138 @@
#include "RimEclipseCellColors.h"
#include "RimEclipseResultCase.h"
#include "RimEclipseView.h"
#include "RimFileSummaryCase.h"
#include "RimFractureTemplateCollection.h"
#include "RimGridSummaryCase.h"
#include "RimIdenticalGridCaseGroup.h"
#include "RimMainPlotCollection.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryCaseMainCollection.h"
#include "RimSummaryCurve.h"
#include "RimSummaryCurveCollection.h"
#include "RimSummaryCurveFilter.h"
#include "RimSummaryPlotCollection.h"
#include "RiuMainPlotWindow.h"
#include "RiuMainWindow.h"
#include "RiuPlotMainWindow.h"
#include "RiuPlotMainWindowTools.h"
#include "cafUtils.h"
#include "cafProgressInfo.h"
#include <QFileInfo>
#include <QMessageBox>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaImportEclipseCaseTools::openEclipseCasesFromFile(const QStringList& fileNames, QStringList* openedFiles, bool noDialog)
{
RiaApplication* app = RiaApplication::instance();
RimProject* project = app->project();
// Get list of files to import
RifSummaryCaseRestartSelector selector;
if(noDialog) selector.showDialog(false);
selector.determineFilesToImportFromGridFiles(fileNames);
std::vector<RifSummaryCaseFileResultInfo> summaryFileInfos = selector.summaryFileInfos();
// Import eclipse case files
for (const QString& gridCaseFile : selector.gridCaseFiles())
{
if (RiaImportEclipseCaseTools::openEclipseCaseFromFile(gridCaseFile))
{
if(openedFiles) openedFiles->push_back(gridCaseFile);
}
}
// Import summary cases
if (!summaryFileInfos.empty())
{
RimSummaryCaseMainCollection* sumCaseColl = project->activeOilField() ? project->activeOilField()->summaryCaseMainCollection() : nullptr;
if (sumCaseColl)
{
std::vector<RimSummaryCase*> newSumCases = sumCaseColl->createSummaryCasesFromFileInfos(summaryFileInfos);
for (RimSummaryCase* newSumCase : newSumCases)
{
RimSummaryCaseCollection* existingCollection = nullptr;
QString gridCaseFile = RifEclipseSummaryTools::findGridCaseFileFromSummaryHeaderFile(newSumCase->summaryHeaderFilename());
RimEclipseCase* gridCase = project->eclipseCaseFromGridFileName(gridCaseFile);
if (gridCase)
{
RimSummaryCase* existingSummaryCase = sumCaseColl->findSummaryCaseFromFileName(newSumCase->summaryHeaderFilename());
RimGridSummaryCase* existingGridSummaryCase = dynamic_cast<RimGridSummaryCase*>(existingSummaryCase);
RimFileSummaryCase* existingFileSummaryCase = dynamic_cast<RimFileSummaryCase*>(existingSummaryCase);
if (existingGridSummaryCase)
{
delete newSumCase; // No need to add anything new. Already have one.
continue;
}
else if (existingFileSummaryCase)
{
existingFileSummaryCase->firstAncestorOrThisOfType(existingCollection);
// Replace all occurrences of file sum with ecl sum
std::vector<RimSummaryCurve*> objects;
existingFileSummaryCase->objectsWithReferringPtrFieldsOfType(objects);
// UI settings of a curve filter is updated based
// on the new case association for the curves in the curve filter
// UI is updated by loadDataAndUpdate()
for (RimSummaryCurve* summaryCurve : objects)
{
if (summaryCurve)
{
RimSummaryCurveCollection* parentCollection = nullptr;
summaryCurve->firstAncestorOrThisOfType(parentCollection);
if (parentCollection)
{
parentCollection->loadDataAndUpdate(true);
parentCollection->updateConnectedEditors();
break;
}
}
}
// Remove existing case
sumCaseColl->removeCase(existingFileSummaryCase);
delete existingFileSummaryCase;
}
}
if (existingCollection)
{
existingCollection->addCase(newSumCase);
}
else
{
sumCaseColl->addCase(newSumCase);
}
sumCaseColl->updateAllRequiredEditors();
}
}
}
if (selector.foundErrors())
{
QString errorMessage = selector.createCombinedErrorMessage();
RiaLogging::error(errorMessage);
}
project->activeOilField()->fractureDefinitionCollection()->setDefaultUnitSystemBasedOnLoadedCases();
RiuPlotMainWindowTools::refreshToolbars();
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -92,8 +208,12 @@ bool RiaImportEclipseCaseTools::openEclipseCaseShowTimeStepFilterImpl(const QStr
RiaApplication* app = RiaApplication::instance();
RimProject* project = app->project();
RimEclipseCaseCollection* analysisModels = project->activeOilField() ? project->activeOilField()->analysisModels() : NULL;
if (analysisModels == NULL) return false;
RimEclipseCaseCollection* analysisModels = project->activeOilField() ? project->activeOilField()->analysisModels() : nullptr;
if (analysisModels == nullptr)
{
delete rimResultReservoir;
return false;
}
RiuMainWindow::instance()->show();
@@ -110,76 +230,8 @@ bool RiaImportEclipseCaseTools::openEclipseCaseShowTimeStepFilterImpl(const QStr
RimEclipseView* riv = rimResultReservoir->createAndAddReservoirView();
// Select SOIL as default result variable
riv->cellResult()->setResultType(RiaDefines::DYNAMIC_NATIVE);
if (app->preferences()->loadAndShowSoil)
{
riv->cellResult()->setResultVariable("SOIL");
}
riv->hasUserRequestedAnimation = true;
riv->loadDataAndUpdate();
// Add a corresponding summary case if it exists
{
RimSummaryCaseMainCollection* sumCaseColl = project->activeOilField() ? project->activeOilField()->summaryCaseMainCollection() : NULL;
if (sumCaseColl)
{
{
RiuMainPlotWindow* mainPlotWindow = app->mainPlotWindow();
if (sumCaseColl->summaryCaseCount() == 0 && mainPlotWindow)
{
mainPlotWindow->hide();
}
}
if (!sumCaseColl->findSummaryCaseFromEclipseResultCase(rimResultReservoir))
{
RimSummaryCase* newSumCase = sumCaseColl->createAndAddSummaryCaseFromEclipseResultCase(rimResultReservoir);
if (newSumCase)
{
RimSummaryCase* existingFileSummaryCase = sumCaseColl->findSummaryCaseFromFileName(newSumCase->summaryHeaderFilename());
if (existingFileSummaryCase)
{
// Replace all occurrences of file sum with ecl sum
std::vector<caf::PdmObjectHandle*> referringObjects;
existingFileSummaryCase->objectsWithReferringPtrFields(referringObjects);
// UI settings of a curve filter is updated based
// on the new case association for the curves in the curve filter
// UI is updated by loadDataAndUpdate()
for (caf::PdmObjectHandle* objHandle : referringObjects)
{
RimSummaryCurve* summaryCurve = dynamic_cast<RimSummaryCurve*>(objHandle);
if (summaryCurve)
{
RimSummaryCurveCollection* parentCollection = nullptr;
summaryCurve->firstAncestorOrThisOfType(parentCollection);
if (parentCollection)
{
parentCollection->loadDataAndUpdate(true);
parentCollection->updateConnectedEditors();
break;
}
}
}
sumCaseColl->removeCase(existingFileSummaryCase);
delete existingFileSummaryCase;
}
sumCaseColl->updateAllRequiredEditors();
}
}
}
}
if (!riv->cellResult()->hasResult())
{
riv->cellResult()->setResultVariable(RiaDefines::undefinedResultName());
@@ -202,9 +254,9 @@ bool RiaImportEclipseCaseTools::addEclipseCases(const QStringList& fileNames)
// 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
RimEclipseResultCase* mainResultCase = NULL;
RimEclipseResultCase* mainResultCase = nullptr;
std::vector< std::vector<int> > mainCaseGridDimensions;
RimIdenticalGridCaseGroup* gridCaseGroup = NULL;
RimIdenticalGridCaseGroup* gridCaseGroup = nullptr;
RiaApplication* app = RiaApplication::instance();
RimProject* project = app->project();
@@ -27,7 +27,7 @@ class QStringList;
class RiaImportEclipseCaseTools
{
public:
static bool openEclipseCaseFromFile(const QString& fileName);
static bool openEclipseCasesFromFile(const QStringList& fileNames, QStringList* openedFiles = nullptr, bool noDialog = false);
static bool openEclipseCaseShowTimeStepFilter(const QString& fileName);
static bool openMockModel(const QString& name);
@@ -35,6 +35,7 @@ public:
static bool addEclipseCases(const QStringList& fileNames);
private:
static bool openEclipseCaseFromFile(const QString& fileName);
static bool openEclipseCaseShowTimeStepFilterImpl(const QString& fileName, bool showTimeStepFilter);
};
@@ -45,12 +45,12 @@ class RiaDefaultConsoleLogger : public RiaLogger
public:
RiaDefaultConsoleLogger();
virtual int level() const override;
virtual void setLevel(int logLevel) override;
virtual void error( const char* message) override;
virtual void warning(const char* message) override;
virtual void info( const char* message) override;
virtual void debug( const char* message) override;
int level() const override;
void setLevel(int logLevel) override;
void error( const char* message) override;
void warning(const char* message) override;
void info( const char* message) override;
void debug( const char* message) override;
private:
static void writeMessageToConsole(const char* prefix, const char* message);
@@ -157,7 +157,7 @@ void RiaDefaultConsoleLogger::writeToConsole(const std::string& str)
DWORD stringLength = static_cast<DWORD>(str.length());
unsigned long iDum = 0;
WriteConsoleA(hStdOutputHandle, str.c_str(), stringLength, &iDum, NULL);
WriteConsoleA(hStdOutputHandle, str.c_str(), stringLength, &iDum, nullptr);
}
#else
fputs(str.c_str(), stderr);
@@ -192,7 +192,6 @@ void RiaLogging::setLoggerInstance(RiaLogger* loggerInstance)
delete sm_logger;
}
// VF_ASSERT(loggerInstance);
sm_logger = loggerInstance;
}
@@ -203,7 +202,7 @@ void RiaLogging::setLoggerInstance(RiaLogger* loggerInstance)
void RiaLogging::deleteLoggerInstance()
{
delete sm_logger;
sm_logger = NULL;
sm_logger = nullptr;
}
//--------------------------------------------------------------------------------------------------
@@ -213,6 +212,7 @@ void RiaLogging::error(const QString& message)
{
if (sm_logger && sm_logger->level() >= RI_LL_ERROR)
{
#pragma omp critical(critical_section_logging)
sm_logger->error(message.toLatin1().constData());
}
}
@@ -224,6 +224,7 @@ void RiaLogging::warning(const QString& message)
{
if (sm_logger && sm_logger->level() >= RI_LL_WARNING)
{
#pragma omp critical(critical_section_logging)
sm_logger->warning(message.toLatin1().constData());
}
}
@@ -235,6 +236,7 @@ void RiaLogging::info(const QString& message)
{
if (sm_logger && sm_logger->level() >= RI_LL_INFO)
{
#pragma omp critical(critical_section_logging)
sm_logger->info(message.toLatin1().constData());
}
}
@@ -246,6 +248,7 @@ void RiaLogging::debug(const QString& message)
{
if (sm_logger && sm_logger->level() >= RI_LL_DEBUG)
{
#pragma omp critical(critical_section_logging)
sm_logger->debug(message.toLatin1().constData());
}
}
@@ -0,0 +1,78 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <array>
#include "cvfVector3.h"
#include <cmath>
// Y - North, X - East, Z - up but depth is negative Z
// azi is measured from the Northing (Y) Axis in Clockwise direction looking down
// inc is measured from the negative Z (depth) axis
const double singularityEpsilon = 1.0e-5;
class RiaOffshoreSphericalCoords
{
public:
explicit RiaOffshoreSphericalCoords(const cvf::Vec3f& vec)
{
// Azimuth:
if ( fabs(vec[0]) < singularityEpsilon && fabs(vec[1]) < singularityEpsilon ) incAziR[1] = 0.0f;
else incAziR[1] = atan2(vec[0], vec[1]); // atan2(Y, X)
// R
incAziR[2] = vec.length();
// Inclination from vertical down
if (fabs( incAziR[2]) < singularityEpsilon) incAziR[0] = 0.0f;
else incAziR[0] = acos(-vec[2]/incAziR[2]);
}
explicit RiaOffshoreSphericalCoords(const cvf::Vec3d& vec)
{
// Azimuth:
if (fabs(vec[0]) < singularityEpsilon && fabs(vec[1]) < singularityEpsilon ) incAziR[1] = 0.0;
else incAziR[1] = atan2(vec[0], vec[1]); // atan2(Y, X)
// R
incAziR[2] = vec.length();
// Inclination from vertical down
if (fabs( incAziR[2]) < singularityEpsilon) incAziR[0] = 0.0;
else incAziR[0] = acos(-vec[2]/incAziR[2]);
}
double inc() const { return incAziR[0];}
double azi() const { return incAziR[1];}
double r() const { return incAziR[2];}
// Note that this is a double function, while the rest of the class is float.
// Todo: Convert class to a template to enable float and double versions of everything
static cvf::Vec3d unitVectorFromAziInc(double azimuth, double inclination)
{
return cvf::Vec3d(sin(azimuth)*sin(inclination),
cos(azimuth)*sin(inclination),
-cos(inclination));
}
private:
std::array<double, 3> incAziR;
};
@@ -0,0 +1,49 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaOptionItemFactory.h"
#include "Rim3dView.h"
#include "RimCase.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaOptionItemFactory::appendOptionItemFromViewNameAndCaseName(Rim3dView* view, QList<caf::PdmOptionItemInfo>* optionItems)
{
if (!view || !optionItems) return;
QString caseName;
RimCase* rimCase = nullptr;
view->firstAncestorOrThisOfType(rimCase);
if (rimCase)
{
caseName = rimCase->caseUserDescription();
}
else
{
caseName = "<Unnamed case>";
}
QString displayName = caseName + " : " + view->name();
QIcon icon = view->uiCapability()->uiIcon();
optionItems->push_back(caf::PdmOptionItemInfo(displayName, view, false, icon));
}
@@ -0,0 +1,31 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmUiItem.h"
#include <QList>
class Rim3dView;
class RiaOptionItemFactory
{
public:
static void appendOptionItemFromViewNameAndCaseName(Rim3dView* view, QList<caf::PdmOptionItemInfo>* optionItems);
};
@@ -23,6 +23,7 @@
#include "RimEclipseCaseCollection.h"
#include "RimEclipseInputCase.h"
#include "RimEclipseResultCase.h"
#include "RimGeoMechCase.h"
#include "RimIdenticalGridCaseGroup.h"
#include "RimOilField.h"
#include "RimProject.h"
@@ -125,7 +126,7 @@ void RiaProjectModifier::replaceSourceCases(RimProject* project)
{
for (RimOilField* oilField : project->oilFields())
{
RimEclipseCaseCollection* analysisModels = oilField ? oilField->analysisModels() : NULL;
RimEclipseCaseCollection* analysisModels = oilField ? oilField->analysisModels() : nullptr;
if (analysisModels)
{
for (RimIdenticalGridCaseGroup* caseGroup : analysisModels->caseGroups)
@@ -170,8 +171,9 @@ void RiaProjectModifier::replaceCase(RimProject* project)
for (RimCase* rimCase : allCases)
{
RimEclipseResultCase* resultCase = dynamic_cast<RimEclipseResultCase*>(rimCase);
if (resultCase)
RimEclipseResultCase* eclipseResultCase = dynamic_cast<RimEclipseResultCase*>(rimCase);
RimGeoMechCase* geomechCase = dynamic_cast<RimGeoMechCase*>(rimCase);
if (eclipseResultCase || geomechCase)
{
for (auto item : m_caseIdToGridFileNameMap)
{
@@ -181,11 +183,19 @@ void RiaProjectModifier::replaceCase(RimProject* project)
caseIdToReplace = firstCaseId(project);
}
if (caseIdToReplace == resultCase->caseId())
if (caseIdToReplace == rimCase->caseId())
{
QString replaceFileName = item.second;
resultCase->setGridFileName(replaceFileName);
resultCase->caseUserDescription = caseNameFromGridFileName(replaceFileName);
if (eclipseResultCase)
{
eclipseResultCase->setGridFileName(replaceFileName);
eclipseResultCase->caseUserDescription = caseNameFromGridFileName(replaceFileName);
}
else if (geomechCase)
{
geomechCase->setFileName(replaceFileName);
geomechCase->caseUserDescription = caseNameFromGridFileName(replaceFileName);
}
}
}
}
@@ -280,7 +290,7 @@ int RiaProjectModifier::firstGroupId(RimProject* project)
for (size_t oilFieldIdx = 0; oilFieldIdx < project->oilFields().size(); oilFieldIdx++)
{
RimOilField* oilField = project->oilFields[oilFieldIdx];
RimEclipseCaseCollection* analysisModels = oilField ? oilField->analysisModels() : NULL;
RimEclipseCaseCollection* analysisModels = oilField ? oilField->analysisModels() : nullptr;
if (analysisModels)
{
if (analysisModels->caseGroups.size() > 0)
@@ -18,13 +18,35 @@
#include "RiaQDateTimeTools.h"
#include <QString>
#include <QDateTime>
#include <QLocale>
#include <QString>
#include <cvfAssert.h>
#include <ctime>
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const DateTimeSpan RiaQDateTimeTools::TIMESPAN_DAY = DateTimeSpan(0, 0, 1);
const DateTimeSpan RiaQDateTimeTools::TIMESPAN_WEEK = DateTimeSpan(0, 0, 7);
const DateTimeSpan RiaQDateTimeTools::TIMESPAN_MONTH = DateTimeSpan(0, 1, 0);
const DateTimeSpan RiaQDateTimeTools::TIMESPAN_QUARTER = DateTimeSpan(0, 3, 0);
const DateTimeSpan RiaQDateTimeTools::TIMESPAN_HALFYEAR = DateTimeSpan(0, 6, 0);
const DateTimeSpan RiaQDateTimeTools::TIMESPAN_YEAR = DateTimeSpan(1, 0, 0);
const DateTimeSpan RiaQDateTimeTools::TIMESPAN_DECADE = DateTimeSpan(10, 0, 0);
const QString RiaQDateTimeTools::TIMESPAN_DAY_NAME = "Day";
const QString RiaQDateTimeTools::TIMESPAN_WEEK_NAME = "Week";
const QString RiaQDateTimeTools::TIMESPAN_MONTH_NAME = "Month";
const QString RiaQDateTimeTools::TIMESPAN_QUARTER_NAME = "Quarter";
const QString RiaQDateTimeTools::TIMESPAN_HALFYEAR_NAME = "Half Year";
const QString RiaQDateTimeTools::TIMESPAN_YEAR_NAME = "Year";
const QString RiaQDateTimeTools::TIMESPAN_DECADE_NAME = "Decade";
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -72,6 +94,16 @@ QDateTime RiaQDateTimeTools::fromYears(double years)
return RiaQDateTimeTools::addYears(dt, yearsAfterEpoch);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QDateTime RiaQDateTimeTools::fromTime_t(time_t t)
{
auto qdt = createUtcDateTime();
qdt.setTime_t(t);
return qdt;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -112,6 +144,44 @@ QDateTime RiaQDateTimeTools::addYears(const QDateTime& dt, double years)
return tmp;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QDateTime RiaQDateTimeTools::addSpan(const QDateTime& dt, DateTimeSpan span)
{
return createUtcDateTime(dt)
.addYears(span.years())
.addMonths(span.months())
.addDays(span.days());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QDateTime RiaQDateTimeTools::subtractSpan(const QDateTime& dt, DateTimeSpan span)
{
return createUtcDateTime(dt)
.addYears(-span.years())
.addMonths(-span.months())
.addDays(-span.days());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QDateTime RiaQDateTimeTools::addPeriod(const QDateTime& dt, DateTimePeriod period)
{
return addSpan(dt, timeSpan(period));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QDateTime RiaQDateTimeTools::subtractPeriod(const QDateTime& dt, DateTimePeriod period)
{
return subtractSpan(dt, timeSpan(period));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -155,3 +225,116 @@ QDateTime RiaQDateTimeTools::createUtcDateTime(const QDate& date, const QTime& t
auto qdt = QDateTime(date, time, currentTimeSpec());
return qdt;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QDateTime RiaQDateTimeTools::createUtcDateTime(const QDateTime& dt)
{
auto qdt = QDateTime(dt);
qdt.setTimeSpec(currentTimeSpec());
return qdt;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaQDateTimeTools::lessThan(const QDateTime& dt1, const QDateTime& dt2)
{
// dt1 < dt2
return dt1.secsTo(dt2) > 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const DateTimeSpan RiaQDateTimeTools::timeSpan(DateTimePeriod period)
{
switch (period)
{
case DateTimePeriod::DAY: return TIMESPAN_DAY;
case DateTimePeriod::WEEK: return TIMESPAN_WEEK;
case DateTimePeriod::MONTH: return TIMESPAN_MONTH;
case DateTimePeriod::QUARTER: return TIMESPAN_QUARTER;
case DateTimePeriod::HALFYEAR: return TIMESPAN_HALFYEAR;
case DateTimePeriod::YEAR: return TIMESPAN_YEAR;
case DateTimePeriod::DECADE: return TIMESPAN_DECADE;
}
CVF_ASSERT(false);
return DateTimeSpan();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QDateTime RiaQDateTimeTools::truncateTime(const QDateTime& dt, DateTimePeriod period)
{
int y = dt.date().year();
int m = dt.date().month();
int d = dt.date().day();
int dow = dt.date().dayOfWeek();
switch (period)
{
case DateTimePeriod::DAY: return createUtcDateTime(QDate(y, m, d));
case DateTimePeriod::WEEK: return createUtcDateTime(QDate(y, m, d).addDays(-dow + 1));
case DateTimePeriod::MONTH: return createUtcDateTime(QDate(y, m, 1));
case DateTimePeriod::QUARTER: return createUtcDateTime(QDate(y, ((m - 1) / 3) * 3 + 1, 1));
case DateTimePeriod::HALFYEAR: return createUtcDateTime(QDate(y, ((m - 1) / 6) * 6 + 1, 1));
case DateTimePeriod::YEAR: return createUtcDateTime(QDate(y, 1, 1));
case DateTimePeriod::DECADE: return createUtcDateTime(QDate((y / 10) * 10, 1, 1));
}
CVF_ASSERT(false);
return createUtcDateTime();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<DateTimePeriod> RiaQDateTimeTools::dateTimePeriods()
{
return std::vector<DateTimePeriod>(
{
DateTimePeriod::NONE,
DateTimePeriod::DAY,
DateTimePeriod::WEEK,
DateTimePeriod::MONTH,
DateTimePeriod::QUARTER,
DateTimePeriod::HALFYEAR,
DateTimePeriod::YEAR,
DateTimePeriod::DECADE,
});
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaQDateTimeTools::dateTimePeriodName(DateTimePeriod period)
{
switch (period)
{
case DateTimePeriod::DAY: return TIMESPAN_DAY_NAME;
case DateTimePeriod::WEEK: return TIMESPAN_WEEK_NAME;
case DateTimePeriod::MONTH: return TIMESPAN_MONTH_NAME;
case DateTimePeriod::QUARTER: return TIMESPAN_QUARTER_NAME;
case DateTimePeriod::HALFYEAR: return TIMESPAN_HALFYEAR_NAME;
case DateTimePeriod::YEAR: return TIMESPAN_YEAR_NAME;
case DateTimePeriod::DECADE: return TIMESPAN_DECADE_NAME;
default: return "None";
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaQDateTimeTools::toStringUsingApplicationLocale(const QDateTime& dt, const QString& format)
{
// Default application locale is set in RiaMain
// QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates));
//
// QDate/QDateTime use system locale for toString() functions
QLocale defaultApplicationLocale;
return defaultApplicationLocale.toString(dt, format);
}
@@ -21,34 +21,108 @@
#include <qglobal.h>
#include <qnamespace.h>
#include <QString>
#include <string>
#include <vector>
class QDateTime;
class QDate;
class QTime;
class DateTimeSpan;
//==================================================================================================
//
//==================================================================================================
enum class DateTimePeriod
{
NONE = -1,
DAY,
WEEK,
MONTH,
QUARTER,
HALFYEAR,
YEAR,
DECADE
};
//==================================================================================================
//
//==================================================================================================
class RiaQDateTimeTools
{
static const DateTimeSpan TIMESPAN_DAY;
static const DateTimeSpan TIMESPAN_WEEK;
static const DateTimeSpan TIMESPAN_MONTH;
static const DateTimeSpan TIMESPAN_QUARTER;
static const DateTimeSpan TIMESPAN_HALFYEAR;
static const DateTimeSpan TIMESPAN_YEAR;
static const DateTimeSpan TIMESPAN_DECADE;
public:
static const QString TIMESPAN_DAY_NAME;
static const QString TIMESPAN_WEEK_NAME;
static const QString TIMESPAN_MONTH_NAME;
static const QString TIMESPAN_QUARTER_NAME;
static const QString TIMESPAN_HALFYEAR_NAME;
static const QString TIMESPAN_YEAR_NAME;
static const QString TIMESPAN_DECADE_NAME;
static Qt::TimeSpec currentTimeSpec();
static QDateTime fromString(const QString& dateString, const QString& format);
static QDateTime fromYears(double years);
static QDateTime fromTime_t(time_t t);
static QDateTime addMSecs(const QDateTime& dt, double msecs);
static QDateTime addDays(const QDateTime& dt, double days);
static QDateTime addYears(const QDateTime& dt, double years);
static QDateTime addSpan(const QDateTime& dt, DateTimeSpan span);
static QDateTime subtractSpan(const QDateTime& dt, DateTimeSpan span);
static QDateTime addPeriod(const QDateTime& dt, DateTimePeriod period);
static QDateTime subtractPeriod(const QDateTime& dt, DateTimePeriod period);
static QDateTime epoch();
static QDateTime createUtcDateTime();
static QDateTime createUtcDateTime(const QDate& date);
static QDateTime createUtcDateTime(const QDate& date, const QTime& time);
static QDateTime createUtcDateTime(const QDateTime& dt);
static bool lessThan(const QDateTime& dt1, const QDateTime& dt2);
static const DateTimeSpan timeSpan(DateTimePeriod period);
static QDateTime truncateTime(const QDateTime& dt, DateTimePeriod period);
static std::vector<DateTimePeriod> dateTimePeriods();
static QString dateTimePeriodName(DateTimePeriod period);
// This function uses C locale to make sure the text representation of a date is stable, independent of the locale
// settings on local machine. Required for stable regression testing.
static QString toStringUsingApplicationLocale(const QDateTime& dt, const QString& format);
private:
static quint64 secondsInDay();
static quint64 secondsInYear();
};
//==================================================================================================
///
//==================================================================================================
class DateTimeSpan
{
public:
DateTimeSpan() : m_years(0), m_months(0), m_days(0) { }
DateTimeSpan(int years, int months, int days) : m_years(years), m_months(months), m_days(days) { }
int years() const { return m_years; }
int months() const { return m_months; }
int days() const { return m_days; }
bool isEmpty() { return m_years == 0 && m_months == 0 && m_days; }
private:
int m_years;
int m_months;
int m_days;
};
@@ -0,0 +1,44 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaQIconTools.h"
#include <QPainter>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QPixmap RiaQIconTools::appendPixmapUpperLeft(const QPixmap& pixmap, const QPixmap& overlayPixmap)
{
QPixmap scaledPixmap;
{
QSize size = pixmap.size() - pixmap.size() / 4;
scaledPixmap = overlayPixmap.scaled(size);
}
QPixmap combinedPixmap(pixmap);
QPainter painter(&combinedPixmap);
int x = 0;
int y = -4;
painter.drawPixmap(x, y, scaledPixmap);
return combinedPixmap;
}
@@ -0,0 +1,32 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QIcon>
//==================================================================================================
//
//
//
//==================================================================================================
class RiaQIconTools
{
public:
static QPixmap appendPixmapUpperLeft(const QPixmap& pixmap, const QPixmap& overlayPixmap);
};
@@ -1,60 +1,105 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaRegressionTest.h"
#include "cafPdmSettings.h"
#include "cafPdmUiFilePathEditor.h"
#include "cafPdmUiTextEditor.h"
CAF_PDM_SOURCE_INIT(RiaRegressionTest, "RiaRegressionTest");
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
RiaRegressionTest::RiaRegressionTest(void)
{
CAF_PDM_InitFieldNoDefault(&applicationWorkingFolder, "workingFolder", "Folder containing <b>compare</b>", "", "Location of compare tool from Image Magic suite", "");
applicationWorkingFolder.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&folderContainingCompareTool,
"workingFolder",
"Folder containing <b>compare</b>",
"",
"Location of compare tool from Image Magic suite",
"");
folderContainingCompareTool.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&folderContainingDiffTool,
"folderContainingDiffTool",
"Folder containing <b>diff</b>",
"",
"Location of diff tool used for text compare",
"");
folderContainingDiffTool.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&folderContainingGitTool,
"folderContainingGitTool",
"Folder containing <b>git</b>",
"",
"Location of git tool used for text compare",
"");
folderContainingGitTool.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&regressionTestFolder, "regressionTestFolder", "Regression Test Folder", "", "", "");
regressionTestFolder.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
CAF_PDM_InitField(&showInteractiveDiffImages, "showInteractiveDiffImages", false, "Interactive Diff Images", "", "", "");
CAF_PDM_InitFieldNoDefault(&testFilter, "testFilter", "Test Filter", "", "If empty, all tests are executed.\nTo execute a subset of tests, specify folder names separated by ;", "");
CAF_PDM_InitField(
&useOpenMPForGeometryCreation, "useOpenMPForGeometryCreation", true, "Use OpenMP For Geometry Creation", "", "", "");
CAF_PDM_InitFieldNoDefault(
&testFilter,
"testFilter",
"Test Filter",
"",
"If empty, all tests are executed.\nTo execute a subset of tests, specify folder names separated by ;",
"");
testFilter.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName());
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
RiaRegressionTest::~RiaRegressionTest(void)
{
RiaRegressionTest::~RiaRegressionTest(void) {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTest::writeSettingsToApplicationStore() const
{
caf::PdmSettings::writeFieldsToApplicationStore(this);
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTest::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
void RiaRegressionTest::readSettingsFromApplicationStore()
{
if (field == &applicationWorkingFolder || field == &regressionTestFolder)
caf::PdmSettings::readFieldsFromApplicationStore(this);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTest::defineEditorAttribute(const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute)
{
if (field == &folderContainingDiffTool || field == &folderContainingCompareTool || field == &regressionTestFolder ||
field == &folderContainingGitTool)
{
caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast<caf::PdmUiFilePathEditorAttribute*>(attribute);
if (myAttr)
@@ -63,5 +108,3 @@ void RiaRegressionTest::defineEditorAttribute(const caf::PdmFieldHandle* field,
}
}
}
@@ -1,28 +1,26 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmObject.h"
#include "cafPdmField.h"
#include "cafAppEnum.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
class RiaRegressionTest : public caf::PdmObject
{
@@ -30,14 +28,22 @@ class RiaRegressionTest : public caf::PdmObject
public:
RiaRegressionTest(void);
virtual ~RiaRegressionTest(void);
~RiaRegressionTest(void) override;
void writeSettingsToApplicationStore() const;
void readSettingsFromApplicationStore();
public:
caf::PdmField<QString> applicationWorkingFolder;
caf::PdmField<QString> regressionTestFolder;
caf::PdmField<QString> testFilter;
caf::PdmField<bool> showInteractiveDiffImages;
caf::PdmField<QString> folderContainingCompareTool;
caf::PdmField<QString> folderContainingDiffTool;
caf::PdmField<QString> folderContainingGitTool;
caf::PdmField<QString> regressionTestFolder;
caf::PdmField<QString> testFilter;
caf::PdmField<bool> showInteractiveDiffImages;
caf::PdmField<bool> useOpenMPForGeometryCreation;
protected:
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute);
void defineEditorAttribute(const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute) override;
};
@@ -0,0 +1,694 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaRegressionTestRunner.h"
#include "RiaApplication.h"
#include "RiaGitDiff.h"
#include "RiaImageCompareReporter.h"
#include "RiaImageFileCompare.h"
#include "RiaLogging.h"
#include "RiaRegressionTest.h"
#include "RiaTextFileCompare.h"
#include "RicfCommandFileExecutor.h"
#include "Rim3dView.h"
#include "RimCase.h"
#include "RimMainPlotCollection.h"
#include "RimProject.h"
#include "RiuMainWindow.h"
#include "RiuPlotMainWindow.h"
#include "RiuViewer.h"
#include "ExportCommands/RicSnapshotAllPlotsToFileFeature.h"
#include "ExportCommands/RicSnapshotAllViewsToFileFeature.h"
#include "cafUtils.h"
#include <QDateTime>
#include <QDebug>
#include <QDesktopServices>
#include <QDir>
#include <QMdiSubWindow>
#include <QSettings>
#include <QStatusBar>
#include <QString>
#include <QUrl>
namespace RegTestNames
{
const QString generatedFilesFolderName = "RegTestGeneratedFiles";
const QString baseFilesFolderName = "RegTestBaseFiles";
const QString generatedFolderName = "RegTestGeneratedImages";
const QString diffFolderName = "RegTestDiffImages";
const QString baseFolderName = "RegTestBaseImages";
const QString testProjectName = "RegressionTest";
const QString testFolderFilter = "TestCase*";
const QString imageCompareExeName = "compare";
const QString reportFileName = "ResInsightRegressionTestReport.html";
const QString commandFileFilter = "commandfile-*";
}; // namespace RegTestNames
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void logInfoTextWithTimeInSeconds(const QTime& time, const QString& msg)
{
double timeRunning = time.elapsed() / 1000.0;
QString timeText = QString("(%1 s) ").arg(timeRunning, 0, 'f', 1);
RiaLogging::info(timeText + msg);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaRegressionTestRunner::RiaRegressionTestRunner()
: m_runningRegressionTests(false)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaRegressionTestRunner* RiaRegressionTestRunner::instance()
{
static RiaRegressionTestRunner* singleton = new RiaRegressionTestRunner;
return singleton;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::runRegressionTest()
{
m_runningRegressionTests = true;
QString currentApplicationPath = QDir::currentPath();
RiaRegressionTest regressionTestConfig;
regressionTestConfig.readSettingsFromApplicationStore();
if (!regressionTestConfig.folderContainingCompareTool().isEmpty())
{
// Windows Only : The image compare tool requires current working directory to be at the folder
// containing the image compare tool
QDir::setCurrent(regressionTestConfig.folderContainingCompareTool());
}
QString generatedFolderName = RegTestNames::generatedFolderName;
QString diffFolderName = RegTestNames::diffFolderName;
QString baseFolderName = RegTestNames::baseFolderName;
QString regTestProjectName = RegTestNames::testProjectName;
QString regTestFolderFilter = RegTestNames::testFolderFilter;
QDir testDir(m_rootPath); // If string is empty it will end up as cwd
testDir.setFilter(QDir::Dirs);
QStringList dirNameFilter;
dirNameFilter.append(regTestFolderFilter);
testDir.setNameFilters(dirNameFilter);
QFileInfoList folderList = subDirectoriesForTestExecution(testDir);
// delete diff and generated images
for (const QFileInfo& fi : folderList)
{
QDir testCaseFolder(fi.filePath());
{
QDir genDir(testCaseFolder.filePath(generatedFolderName));
removeDirectoryWithContent(genDir);
}
{
QDir diffDir(testCaseFolder.filePath(diffFolderName));
removeDirectoryWithContent(diffDir);
}
{
QDir generatedFiles(testCaseFolder.filePath(RegTestNames::generatedFilesFolderName));
removeDirectoryWithContent(generatedFiles);
}
}
QString htmlReportFileName = generateHtmlReport(folderList, baseFolderName, generatedFolderName, diffFolderName, testDir);
QDesktopServices::openUrl(htmlReportFileName);
QTime timeStamp;
timeStamp.start();
logInfoTextWithTimeInSeconds(timeStamp, "Starting regression tests\n");
for (const QFileInfo& folderFileInfo : folderList)
{
QDir testCaseFolder(folderFileInfo.filePath());
bool anyCommandFilesExecuted = findAndExecuteCommandFiles(testCaseFolder, regressionTestConfig, htmlReportFileName);
if (!anyCommandFilesExecuted)
{
QString projectFileName;
if (testCaseFolder.exists(regTestProjectName + ".rip"))
{
projectFileName = regTestProjectName + ".rip";
}
if (testCaseFolder.exists(regTestProjectName + ".rsp"))
{
projectFileName = regTestProjectName + ".rsp";
}
if (!projectFileName.isEmpty())
{
logInfoTextWithTimeInSeconds(timeStamp, "Initializing test :" + testCaseFolder.absolutePath());
RiaApplication* app = RiaApplication::instance();
app->loadProject(testCaseFolder.filePath(projectFileName));
// Wait until all command objects have completed
app->waitUntilCommandObjectsHasBeenProcessed();
regressionTestConfigureProject();
resizeMaximizedPlotWindows();
QString fullPathGeneratedFolder = testCaseFolder.absoluteFilePath(generatedFolderName);
RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(fullPathGeneratedFolder);
RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(fullPathGeneratedFolder);
app->closeProject();
}
else
{
RiaLogging::error("Could not find a regression test file named : " + testCaseFolder.absolutePath() + "/" +
regTestProjectName + ".rsp");
}
}
QDir baseDir(testCaseFolder.filePath(baseFolderName));
QDir genDir(testCaseFolder.filePath(generatedFolderName));
QDir diffDir(testCaseFolder.filePath(diffFolderName));
if (!diffDir.exists()) testCaseFolder.mkdir(diffFolderName);
baseDir.setFilter(QDir::Files);
QStringList baseImageFileNames = baseDir.entryList();
for (int fIdx = 0; fIdx < baseImageFileNames.size(); ++fIdx)
{
QString fileName = baseImageFileNames[fIdx];
RiaImageFileCompare imgComparator(RegTestNames::imageCompareExeName);
bool ok =
imgComparator.runComparison(genDir.filePath(fileName), baseDir.filePath(fileName), diffDir.filePath(fileName));
if (!ok)
{
qDebug() << "Error comparing :" << imgComparator.errorMessage() << "\n" << imgComparator.errorDetails();
}
}
logInfoTextWithTimeInSeconds(timeStamp, "Completed test :" + testCaseFolder.absolutePath());
}
// Invoke git diff
{
QString folderContainingGit = regressionTestConfig.folderContainingGitTool();
RiaGitDiff gitDiff(folderContainingGit);
gitDiff.executeDiff(m_rootPath);
QString diffText = gitDiff.diffOutput();
if (!diffText.isEmpty())
{
QFile file(htmlReportFileName);
if (file.open(QIODevice::Append | QIODevice::Text))
{
QTextStream stream(&file);
QString divSectionForDiff = R"(
<div id = "destination-elem-id"[innerHtml] = "outputHtml">
original
</div>
)";
stream << divSectionForDiff;
stream << "</body>";
{
QString generateDiffString = R"(
<script type="text/javascript">
function generateDiff() {
return `
)";
generateDiffString += diffText;
generateDiffString += R"(
`;
};
)";
generateDiffString += R"(
var diffHtml = Diff2Html.getPrettyHtml(
generateDiff(),
{inputFormat: 'diff', showFiles: true, matching: 'lines', outputFormat: 'side-by-side'}
);
document.getElementById("destination-elem-id").innerHTML = diffHtml;
</script>
</html>
)";
stream << generateDiffString;
}
}
}
}
RiaLogging::info("\n");
logInfoTextWithTimeInSeconds(timeStamp, "Completed regression tests");
QDir::setCurrent(currentApplicationPath);
m_runningRegressionTests = false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaRegressionTestRunner::findAndExecuteCommandFiles(const QDir& testCaseFolder,
const RiaRegressionTest& regressionTestConfig,
const QString& htmlReportFileName)
{
QStringList filterList;
filterList << RegTestNames::commandFileFilter;
QFileInfoList commandFileEntries = testCaseFolder.entryInfoList(filterList);
if (commandFileEntries.empty())
{
return false;
}
QString currentAbsolutePath = QDir::current().absolutePath();
// Set current path to the folder containing the command file, as this is required when using file references
// in the command file
QDir::setCurrent(testCaseFolder.path());
for (const auto& fileInfo : commandFileEntries)
{
QString commandFile = fileInfo.absoluteFilePath();
QFile file(commandFile);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
RiaLogging::error("Failed to open command file : " + commandFile);
}
else
{
QTextStream in(&file);
RicfCommandFileExecutor::instance()->executeCommands(in);
}
}
QDir::setCurrent(currentAbsolutePath);
// Create diff based on generated folders
{
QString html;
RiaTextFileCompare textFileCompare(regressionTestConfig.folderContainingDiffTool());
QString baseFilesFolderName = testCaseFolder.filePath(RegTestNames::baseFilesFolderName);
QString generatedFilesFolderName = testCaseFolder.filePath(RegTestNames::generatedFilesFolderName);
QFileInfo fib(baseFilesFolderName);
QFileInfo fig(generatedFilesFolderName);
if (fib.exists() && fig.exists())
{
{
QString headerText = testCaseFolder.dirName();
html += "<table>\n";
html += " <tr>\n";
html += " <td colspan=\"3\" bgcolor=\"darkblue\" height=\"40\"> <b><font color=\"white\" size=\"3\"> " +
headerText + " </font></b> </td>\n";
html += " </tr>\n";
textFileCompare.runComparison(baseFilesFolderName, generatedFilesFolderName);
QString diff = textFileCompare.diffOutput();
if (diff.isEmpty())
{
html += " <tr>\n";
html += " <td colspan=\"3\" bgcolor=\"lightgray\"> <font color=\"green\">No text diff "
"detected</font> </td> \n";
html += " </tr>\n";
}
else
{
html += " <tr>\n";
html += " <td colspan=\"3\" bgcolor=\"lightgray\"> <font color=\"red\">Text diff detected - "
"output from diff tool : </font> </td> \n";
html += " </tr>\n";
}
// Table end
html += "</table>\n";
if (!diff.isEmpty())
{
html += QString("<code> %1 </code>").arg(diff);
}
}
QFile file(htmlReportFileName);
if (file.open(QIODevice::Append | QIODevice::Text))
{
QTextStream stream(&file);
stream << html;
}
}
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaRegressionTestRunner::generateHtmlReport(const QFileInfoList& folderList,
const QString& baseFolderName,
const QString& generatedFolderName,
const QString& diffFolderName,
const QDir& testDir)
{
RiaImageCompareReporter imageCompareReporter;
// Minor workaround
// Use registry to define if interactive diff images should be created
// Defined by user in RiaRegressionTest
{
QSettings settings;
bool useInteractiveDiff = settings.value("showInteractiveDiffImages").toBool();
if (useInteractiveDiff)
{
imageCompareReporter.showInteractiveOnly();
}
}
for (const QFileInfo& fi : folderList)
{
QDir testCaseFolder(fi.filePath());
QString testFolderName = testCaseFolder.dirName();
QString reportBaseFolderName = testCaseFolder.filePath(baseFolderName);
QString reportGeneratedFolderName = testCaseFolder.filePath(generatedFolderName);
QString reportDiffFolderName = testCaseFolder.filePath(diffFolderName);
imageCompareReporter.addImageDirectoryComparisonSet(testFolderName.toStdString(),
reportBaseFolderName.toStdString(),
reportGeneratedFolderName.toStdString(),
reportDiffFolderName.toStdString());
}
QString htmlReportFileName = testDir.filePath(RegTestNames::reportFileName);
QString htmldiff2htmlText = diff2htmlHeaderText(m_rootPath);
imageCompareReporter.generateHTMLReport(htmlReportFileName.toStdString(), htmldiff2htmlText.toStdString());
return htmlReportFileName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::removeDirectoryWithContent(QDir& dirToDelete)
{
caf::Utils::removeDirectoryAndFilesRecursively(dirToDelete.absolutePath());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::regressionTestConfigureProject()
{
RiuMainWindow* mainWnd = RiuMainWindow::instance();
if (!mainWnd) return;
RimProject* proj = RiaApplication::instance()->project();
if (!proj) return;
std::vector<RimCase*> projectCases;
proj->allCases(projectCases);
for (RimCase* cas : projectCases)
{
if (!cas) continue;
std::vector<Rim3dView*> views = cas->views();
for (Rim3dView* riv : views)
{
if (riv && riv->viewer())
{
// Make sure all views are maximized for snapshotting
QMdiSubWindow* subWnd = mainWnd->findMdiSubWindow(riv->viewer()->layoutWidget());
if (subWnd)
{
subWnd->showMaximized();
}
// This size is set to match the regression test reference images
riv->viewer()->setFixedSize(RiaRegressionTestRunner::regressionDefaultImageSize());
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::resizeMaximizedPlotWindows()
{
RimProject* proj = RiaApplication::instance()->project();
if (!proj) return;
RiuPlotMainWindow* plotMainWindow = RiaApplication::instance()->mainPlotWindow();
if (!plotMainWindow) return;
std::vector<RimViewWindow*> viewWindows;
proj->mainPlotCollection()->descendantsIncludingThisOfType(viewWindows);
for (auto viewWindow : viewWindows)
{
if (viewWindow->isMdiWindow())
{
RimMdiWindowGeometry wndGeo = viewWindow->mdiWindowGeometry();
if (wndGeo.isMaximized)
{
QWidget* viewWidget = viewWindow->viewWidget();
if (viewWidget)
{
QMdiSubWindow* mdiWindow = plotMainWindow->findMdiSubWindow(viewWidget);
if (mdiWindow)
{
mdiWindow->showNormal();
viewWidget->resize(RiaRegressionTestRunner::regressionDefaultImageSize());
}
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiaRegressionTestRunner::regressionDefaultImageSize()
{
return QSize(1000, 745);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaRegressionTestRunner::diff2htmlHeaderText(const QString& testRootPath)
{
QString html;
QString oldProjPath = QDir::fromNativeSeparators(testRootPath);
QStringList pathFolders = oldProjPath.split("/", QString::KeepEmptyParts);
QString path;
for (const auto& f : pathFolders)
{
if (f.compare("ProjectFiles", Qt::CaseInsensitive) == 0) break;
path += f;
path += "/";
}
{
html = R"(
<!-- CSS -->
<link rel = "stylesheet" type = "text/css" href = "dist/diff2html.css">
<!--Javascripts-->
<script type = "text/javascript" src = "dist/diff2html.js"></script>
<script type = "text/javascript" src = "dist/diff2html-ui.js"></script>
)";
QString pathToDiff2html = path + "diff2html/dist/";
html = html.replace("dist/", pathToDiff2html);
}
return html;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QFileInfoList RiaRegressionTestRunner::subDirectoriesForTestExecution(const QDir& directory)
{
if (m_testFilter.isEmpty())
{
QFileInfoList folderList = directory.entryInfoList();
return folderList;
}
QFileInfoList foldersMatchingTestFilter;
QFileInfoList folderList = directory.entryInfoList();
for (const auto& fi : folderList)
{
QString path = fi.path();
QString baseName = fi.baseName();
for (const auto& s : m_testFilter)
{
QString trimmed = s.trimmed();
if (baseName.contains(trimmed, Qt::CaseInsensitive))
{
foldersMatchingTestFilter.push_back(fi);
}
}
}
return foldersMatchingTestFilter;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::executeRegressionTests()
{
RiaRegressionTest testConfig;
testConfig.readSettingsFromApplicationStore();
QString testPath = testConfig.regressionTestFolder();
QStringList testFilter = testConfig.testFilter().split(";", QString::SkipEmptyParts);
executeRegressionTests(testPath, testFilter);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::executeRegressionTests(const QString& regressionTestPath, const QStringList& testFilter)
{
RiuMainWindow* mainWnd = RiuMainWindow::instance();
if (mainWnd)
{
mainWnd->hideAllDockWindows();
mainWnd->statusBar()->close();
mainWnd->setDefaultWindowSize();
m_regressionTestSettings.readSettingsFromApplicationStore();
m_rootPath = regressionTestPath;
m_testFilter = testFilter;
runRegressionTest();
mainWnd->loadWinGeoAndDockToolBarLayout();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaRegressionTestRunner::isRunningRegressionTests() const
{
return m_runningRegressionTests;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaRegressionTestRunner::useOpenMPForGeometryCreation() const
{
if (!m_runningRegressionTests) return false;
return m_regressionTestSettings.useOpenMPForGeometryCreation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::updateRegressionTest(const QString& testRootPath)
{
// Find all sub folders
QDir testDir(testRootPath); // If string is empty it will end up as cwd
testDir.setFilter(QDir::Dirs);
QStringList dirNameFilter;
dirNameFilter.append(RegTestNames::testFolderFilter);
testDir.setNameFilters(dirNameFilter);
QFileInfoList folderList = testDir.entryInfoList();
for (const auto& fi : folderList)
{
QDir testCaseFolder(fi.filePath());
QDir baseDir(testCaseFolder.filePath(RegTestNames::baseFolderName));
removeDirectoryWithContent(baseDir);
testCaseFolder.mkdir(RegTestNames::baseFolderName);
QDir genDir(testCaseFolder.filePath(RegTestNames::generatedFolderName));
QStringList imageFileNames = genDir.entryList();
for (int fIdx = 0; fIdx < imageFileNames.size(); ++fIdx)
{
QString fileName = imageFileNames[fIdx];
QFile::copy(genDir.filePath(fileName), baseDir.filePath(fileName));
}
}
}
@@ -0,0 +1,73 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiaRegressionTest.h"
#include <QFileInfo>
#include <QSize>
#include <QStringList>
class QDir;
class RiaRegressionTest;
//==================================================================================================
//
//==================================================================================================
class RiaRegressionTestRunner
{
public:
static RiaRegressionTestRunner* instance();
void executeRegressionTests(const QString& regressionTestPath, const QStringList& testFilter);
void executeRegressionTests();
bool isRunningRegressionTests() const;
bool useOpenMPForGeometryCreation() const;
static void updateRegressionTest(const QString& testRootPath);
static void regressionTestConfigureProject();
private:
RiaRegressionTestRunner();
void runRegressionTest();
bool findAndExecuteCommandFiles(const QDir& testCaseFolder,
const RiaRegressionTest& regressionTestConfig,
const QString& htmlReportFileName);
QString generateHtmlReport(const QFileInfoList& folderList,
const QString& baseFolderName,
const QString& generatedFolderName,
const QString& diffFolderName,
const QDir& testDir);
static void removeDirectoryWithContent(QDir& dirToDelete);
static void resizeMaximizedPlotWindows();
static QSize regressionDefaultImageSize();
static QString diff2htmlHeaderText(const QString& testRootPath);
QFileInfoList subDirectoriesForTestExecution(const QDir& directory);
private:
QString m_rootPath;
QStringList m_testFilter;
bool m_runningRegressionTests;
RiaRegressionTest m_regressionTestSettings;
};
@@ -0,0 +1,51 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaStatisticsTools.h"
#include "RifEclipseSummaryAddress.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QString RiaStatisticsTools::replacePercentileByPValueText(const QString& percentile)
{
QString result = percentile;
if (result == ENSEMBLE_STAT_P10_QUANTITY_NAME)
{
result = ENSEMBLE_STAT_P90_QUANTITY_NAME;
}
else if (result == ENSEMBLE_STAT_P90_QUANTITY_NAME)
{
result = ENSEMBLE_STAT_P10_QUANTITY_NAME;
}
else if (percentile.contains(QString("%1:").arg(ENSEMBLE_STAT_P10_QUANTITY_NAME)))
{
result.replace(ENSEMBLE_STAT_P10_QUANTITY_NAME, ENSEMBLE_STAT_P90_QUANTITY_NAME);
}
else if (percentile.contains(QString("%1:").arg(ENSEMBLE_STAT_P90_QUANTITY_NAME)))
{
result.replace(ENSEMBLE_STAT_P90_QUANTITY_NAME, ENSEMBLE_STAT_P10_QUANTITY_NAME);
}
return result;
}
@@ -0,0 +1,51 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <cmath>
class QString;
//==================================================================================================
//
//
//
//==================================================================================================
class RiaStatisticsTools
{
public:
static const QString replacePercentileByPValueText(const QString& percentile);
template<class NumberType> static bool isInvalidNumber(NumberType value)
{
return !isValidNumber<NumberType>(value);
}
template<class NumberType> static bool isValidNumber(NumberType value)
{
if (std::isinf(value)) return false;
if (std::isnan(value)) return false;
return true;
}
};
@@ -45,6 +45,14 @@ bool RiaStdStringTools::isNumber(const std::string& s, char decimalPoint)
return (s.find_first_not_of(matchChars) == std::string::npos);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int16_t RiaStdStringTools::toInt16(const std::string& s)
{
return (int16_t)toInt(s);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -76,6 +84,24 @@ double RiaStdStringTools::toDouble(const std::string& s)
return doubleValue;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaStdStringTools::containsAlphabetic(const std::string& s)
{
return std::find_if(s.begin(), s.end(), [](char c) { return isalpha(c); }) != s.end();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaStdStringTools::startsWithAlphabetic(const std::string& s)
{
if (s.empty()) return false;
return isalpha(s[0]) != 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -33,8 +33,11 @@ public:
static std::string trimString(const std::string& s);
static bool isNumber(const std::string& s, char decimalPoint);
static int16_t toInt16(const std::string& s);
static int toInt(const std::string& s);
static double toDouble(const std::string& s);
static bool containsAlphabetic(const std::string& s);
static bool startsWithAlphabetic(const std::string& s);
static std::vector<std::string> splitStringBySpace(const std::string& s);
@@ -130,7 +130,7 @@ std::vector<QString> RiaSummaryCurveAnalyzer::identifierTexts(RifEclipseSummaryA
///
//--------------------------------------------------------------------------------------------------
std::vector<RifEclipseSummaryAddress>
RiaSummaryCurveAnalyzer::addressesForCategory(const std::vector<RifEclipseSummaryAddress>& addresses,
RiaSummaryCurveAnalyzer::addressesForCategory(const std::set<RifEclipseSummaryAddress>& addresses,
RifEclipseSummaryAddress::SummaryVarCategory category)
{
std::vector<RifEclipseSummaryAddress> filteredAddresses;
@@ -50,7 +50,7 @@ public:
std::vector<QString> identifierTexts(RifEclipseSummaryAddress::SummaryVarCategory category) const;
static std::vector<RifEclipseSummaryAddress> addressesForCategory(const std::vector<RifEclipseSummaryAddress>& addresses,
static std::vector<RifEclipseSummaryAddress> addressesForCategory(const std::set<RifEclipseSummaryAddress>& addresses,
RifEclipseSummaryAddress::SummaryVarCategory category);
private:
@@ -22,8 +22,10 @@
#include "RifEclipseSummaryAddress.h"
#include "RimOilField.h"
#include "RimMainPlotCollection.h"
#include "RimProject.h"
#include "RimSummaryCaseMainCollection.h"
#include "RimSummaryCrossPlot.h"
#include "RimSummaryCurve.h"
#include "RimSummaryPlot.h"
@@ -42,6 +44,17 @@ RimSummaryPlotCollection* RiaSummaryTools::summaryPlotCollection()
return project->mainPlotCollection()->summaryPlotCollection();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCaseMainCollection* RiaSummaryTools::summaryCaseMainCollection()
{
RimProject* project = RiaApplication::instance()->project();
RimSummaryCaseMainCollection* summaryCaseMainCollection = project->activeOilField()->summaryCaseMainCollection();
CVF_ASSERT(summaryCaseMainCollection);
return summaryCaseMainCollection;
}
//--------------------------------------------------------------------------------------------------
/// Update the summary curves referencing this curve, as the curve is identified by the name
//--------------------------------------------------------------------------------------------------
@@ -58,7 +71,7 @@ void RiaSummaryTools::notifyCalculatedCurveNameHasChanged(const QString& previou
{
if (adr.quantityName() == previousCurveName.toStdString())
{
RifEclipseSummaryAddress updatedAdr = RifEclipseSummaryAddress::calculatedCurveAddress(currentCurveName.toStdString());
RifEclipseSummaryAddress updatedAdr = RifEclipseSummaryAddress::calculatedAddress(currentCurveName.toStdString());
curve->setSummaryAddressY(updatedAdr);
}
}
@@ -22,6 +22,7 @@ class RimSummaryPlotCollection;
class RimSummaryPlot;
class RimSummaryCrossPlot;
class RimSummaryCrossPlotCollection;
class RimSummaryCaseMainCollection;
class QString;
@@ -35,8 +36,9 @@ namespace caf {
class RiaSummaryTools
{
public:
static RimSummaryPlotCollection* summaryPlotCollection();
static void notifyCalculatedCurveNameHasChanged(const QString& previousCurveName,
static RimSummaryPlotCollection* summaryPlotCollection();
static RimSummaryCaseMainCollection* summaryCaseMainCollection();
static void notifyCalculatedCurveNameHasChanged(const QString& previousCurveName,
const QString& currentCurveName);
static RimSummaryPlot* parentSummaryPlot(caf::PdmObject* object);
@@ -0,0 +1,140 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaTextFileCompare.h"
#include "cafUtils.h"
#include <QProcess>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaTextFileCompare::RiaTextFileCompare(const QString& pathToDiffTool)
: m_pathToDiffTool(pathToDiffTool)
{
reset();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaTextFileCompare::~RiaTextFileCompare() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaTextFileCompare::reset()
{
m_lastError = IC_NO_ERROR;
m_errorMsg.clear();
m_errorDetails.clear();
m_diffOutput.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaTextFileCompare::runComparison(const QString& baseFolder, const QString& generatedFolder)
{
reset();
QString fullFilePath = "diff";
if (!m_pathToDiffTool.isEmpty())
{
fullFilePath = m_pathToDiffTool + "/" + fullFilePath;
}
// Command line arguments used when invoking 'diff'
// See https://docs.freebsd.org/info/diff/diff.info.diff_Options.html
QString args = "-r -u --strip-trailing-cr";
QString completeCommand = QString("\"%1\" %2 %3 %4").arg(fullFilePath).arg(baseFolder).arg(generatedFolder).arg(args);
// Launch process and wait
QProcess proc;
proc.start(completeCommand);
proc.waitForFinished(30000);
QProcess::ProcessError procError = proc.error();
if (procError != QProcess::UnknownError)
{
m_lastError = SEVERE_ERROR;
m_errorMsg = "Error running 'diff' tool process";
m_errorDetails = completeCommand;
return false;
}
QByteArray stdErr = proc.readAllStandardError();
int procExitCode = proc.exitCode();
if (procExitCode == 0)
{
return true;
}
else if (procExitCode == 1)
{
QByteArray stdOut = proc.readAllStandardOutput();
m_diffOutput = stdOut;
return false;
}
else
{
stdErr = stdErr.simplified();
// Report non-severe error
m_lastError = IC_ERROR;
m_errorMsg = "Error running 'diff' tool process";
m_errorDetails = stdErr;
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaTextFileCompare::ErrorType RiaTextFileCompare::error() const
{
return m_lastError;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaTextFileCompare::errorMessage() const
{
return m_errorMsg;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaTextFileCompare::errorDetails() const
{
return m_errorDetails;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaTextFileCompare::diffOutput() const
{
return m_diffOutput;
}
@@ -0,0 +1,57 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QString>
//==================================================================================================
//
// Execute text compare between to folders recursively using the external tool 'diff'
//
//==================================================================================================
class RiaTextFileCompare
{
public:
enum ErrorType
{
IC_NO_ERROR, // No error occurred
IC_ERROR, // An error occurred
SEVERE_ERROR // Severe error occurred, it is likely that another call to compare() will also fail
};
public:
explicit RiaTextFileCompare(const QString& pathToDiffTool);
~RiaTextFileCompare();
bool runComparison(const QString& baseFolder, const QString& generatedFolder);
ErrorType error() const;
QString errorMessage() const;
QString errorDetails() const;
QString diffOutput() const;
private:
void reset();
private:
const QString m_pathToDiffTool;
ErrorType m_lastError;
QString m_errorMsg;
QString m_errorDetails;
QString m_diffOutput;
};
@@ -0,0 +1,58 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaTextStringTools.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaTextStringTools::compare(const QString& expected, const QString& actual)
{
// Suggestions for improvement
// 1. report line number for first change
// 2. report line numbers for all changes
// 3. add support for compare with content of a text file on disk
if (expected.compare(actual) == 0)
{
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaTextStringTools::trimAndRemoveDoubleSpaces(const QString& s)
{
int length;
QString trimmed = s.trimmed();
do
{
length = trimmed.size();
trimmed = trimmed.replace(" ", " ");
} while (trimmed.size() < length);
return trimmed;
}
@@ -0,0 +1,30 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
class QString;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
namespace RiaTextStringTools
{
bool compare(const QString& expected, const QString& actual);
QString trimAndRemoveDoubleSpaces(const QString& s);
}
@@ -16,7 +16,7 @@
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigTimeHistoryCurveMerger.h"
#include "RiaTimeHistoryCurveMerger.h"
#include <cmath> // Needed for HUGE_VAL on Linux
@@ -25,7 +25,7 @@
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigTimeHistoryCurveMerger::RigTimeHistoryCurveMerger()
RiaTimeHistoryCurveMerger::RiaTimeHistoryCurveMerger()
{
}
@@ -33,7 +33,7 @@ RigTimeHistoryCurveMerger::RigTimeHistoryCurveMerger()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigTimeHistoryCurveMerger::addCurveData(const std::vector<double>& values, const std::vector<time_t>& timeSteps)
void RiaTimeHistoryCurveMerger::addCurveData(const std::vector<double>& values, const std::vector<time_t>& timeSteps)
{
CVF_ASSERT(values.size() == timeSteps.size());
@@ -43,7 +43,7 @@ void RigTimeHistoryCurveMerger::addCurveData(const std::vector<double>& values,
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigCurveDataTools::CurveIntervals RigTimeHistoryCurveMerger::validIntervalsForAllTimeSteps() const
RiaCurveDataTools::CurveIntervals RiaTimeHistoryCurveMerger::validIntervalsForAllTimeSteps() const
{
return m_validIntervalsForAllTimeSteps;
}
@@ -51,7 +51,7 @@ RigCurveDataTools::CurveIntervals RigTimeHistoryCurveMerger::validIntervalsForAl
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<time_t>& RigTimeHistoryCurveMerger::allTimeSteps() const
const std::vector<time_t>& RiaTimeHistoryCurveMerger::allTimeSteps() const
{
return m_allTimeSteps;
}
@@ -59,7 +59,7 @@ const std::vector<time_t>& RigTimeHistoryCurveMerger::allTimeSteps() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>& RigTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) const
const std::vector<double>& RiaTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) const
{
CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size());
@@ -69,7 +69,7 @@ const std::vector<double>& RigTimeHistoryCurveMerger::interpolatedCurveValuesFor
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double>& RigTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx)
std::vector<double>& RiaTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx)
{
CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size());
@@ -79,7 +79,7 @@ std::vector<double>& RigTimeHistoryCurveMerger::interpolatedCurveValuesForAllTim
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigTimeHistoryCurveMerger::computeInterpolatedValues()
void RiaTimeHistoryCurveMerger::computeInterpolatedValues()
{
m_validIntervalsForAllTimeSteps.clear();
m_allTimeSteps.clear();
@@ -111,7 +111,7 @@ void RigTimeHistoryCurveMerger::computeInterpolatedValues()
for (size_t valueIndex = 0; valueIndex < dataValueCount; valueIndex++)
{
double interpolValue = interpolationValue(m_allTimeSteps[valueIndex], m_originalValues[curveIdx].first, m_originalValues[curveIdx].second);
if (!RigCurveDataTools::isValidValue(interpolValue, false))
if (!RiaCurveDataTools::isValidValue(interpolValue, false))
{
accumulatedValidValues[valueIndex] = HUGE_VAL;
}
@@ -120,13 +120,13 @@ void RigTimeHistoryCurveMerger::computeInterpolatedValues()
}
}
m_validIntervalsForAllTimeSteps = RigCurveDataTools::calculateIntervalsOfValidValues(accumulatedValidValues, false);
m_validIntervalsForAllTimeSteps = RiaCurveDataTools::calculateIntervalsOfValidValues(accumulatedValidValues, false);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigTimeHistoryCurveMerger::computeUnionOfTimeSteps()
void RiaTimeHistoryCurveMerger::computeUnionOfTimeSteps()
{
m_allTimeSteps.clear();
@@ -149,7 +149,7 @@ void RigTimeHistoryCurveMerger::computeUnionOfTimeSteps()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigTimeHistoryCurveMerger::interpolationValue(const time_t& interpolationTimeStep,
double RiaTimeHistoryCurveMerger::interpolationValue(const time_t& interpolationTimeStep,
const std::vector<double>& curveValues,
const std::vector<time_t>& curveTimeSteps)
{
@@ -162,7 +162,7 @@ double RigTimeHistoryCurveMerger::interpolationValue(const time_t& interpolation
if (curveTimeSteps.at(firstI) == interpolationTimeStep)
{
const double& firstValue = curveValues.at(firstI);
if (!RigCurveDataTools::isValidValue(firstValue, removeInterpolatedValues))
if (!RiaCurveDataTools::isValidValue(firstValue, removeInterpolatedValues))
{
return HUGE_VAL;
}
@@ -179,7 +179,7 @@ double RigTimeHistoryCurveMerger::interpolationValue(const time_t& interpolation
if (curveTimeSteps.at(secondI) == interpolationTimeStep)
{
const double& secondValue = curveValues.at(secondI);
if (!RigCurveDataTools::isValidValue(secondValue, removeInterpolatedValues))
if (!RiaCurveDataTools::isValidValue(secondValue, removeInterpolatedValues))
{
return HUGE_VAL;
}
@@ -190,10 +190,10 @@ double RigTimeHistoryCurveMerger::interpolationValue(const time_t& interpolation
const double& firstValue = curveValues.at(firstI);
const double& secondValue = curveValues.at(secondI);
bool isFirstValid = RigCurveDataTools::isValidValue(firstValue, removeInterpolatedValues);
bool isFirstValid = RiaCurveDataTools::isValidValue(firstValue, removeInterpolatedValues);
if (!isFirstValid) return HUGE_VAL;
bool isSecondValid = RigCurveDataTools::isValidValue(secondValue, removeInterpolatedValues);
bool isSecondValid = RiaCurveDataTools::isValidValue(secondValue, removeInterpolatedValues);
if (!isSecondValid) return HUGE_VAL;
double firstDiff = fabs(difftime(interpolationTimeStep, curveTimeSteps.at(firstI)));
@@ -204,7 +204,7 @@ double RigTimeHistoryCurveMerger::interpolationValue(const time_t& interpolation
double val = (firstValue * firstWeight) + (secondValue * secondWeight);
CVF_ASSERT(RigCurveDataTools::isValidValue(val, removeInterpolatedValues));
CVF_ASSERT(RiaCurveDataTools::isValidValue(val, removeInterpolatedValues));
return val;
}
@@ -18,7 +18,7 @@
#pragma once
#include "RigCurveDataTools.h"
#include "RiaCurveDataTools.h"
#include <ctime>
@@ -26,10 +26,10 @@
//==================================================================================================
///
//==================================================================================================
class RigTimeHistoryCurveMerger
class RiaTimeHistoryCurveMerger
{
public:
RigTimeHistoryCurveMerger();
RiaTimeHistoryCurveMerger();
void addCurveData(const std::vector<double>& values,
@@ -37,7 +37,7 @@ public:
void computeInterpolatedValues();
RigCurveDataTools::CurveIntervals validIntervalsForAllTimeSteps() const;
RiaCurveDataTools::CurveIntervals validIntervalsForAllTimeSteps() const;
const std::vector<time_t>& allTimeSteps() const;
const std::vector<double>& interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) const;
@@ -61,7 +61,7 @@ private:
private:
std::vector<std::pair<std::vector<double>, std::vector<time_t>>> m_originalValues;
RigCurveDataTools::CurveIntervals m_validIntervalsForAllTimeSteps;
RiaCurveDataTools::CurveIntervals m_validIntervalsForAllTimeSteps;
std::vector<time_t> m_allTimeSteps;
std::vector<std::vector<double>> m_interpolatedValuesForAllCurves;
@@ -0,0 +1,274 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include <cvfConfigCore.h>
#include <cvfAssert.h>
#include "RiaTimeHistoryCurveResampler.h"
#include <limits>
//QString tostring(const QDateTime& dt)
//{
// int y = dt.date().year();
// int m = dt.date().month();
// int d = dt.date().day();
//
// int h = dt.time().hour();
// int mm = dt.time().minute();
// int s = dt.time().second();
//
// return QString("%1.%2.%3 %4:%5:%6").arg(y).arg(m).arg(d).arg(h).arg(mm).arg(s);
//}
//--------------------------------------------------------------------------------------------------
/// Internal constants
//--------------------------------------------------------------------------------------------------
#define DOUBLE_INF std::numeric_limits<double>::infinity()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaTimeHistoryCurveResampler::RiaTimeHistoryCurveResampler()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaTimeHistoryCurveResampler::setCurveData(const std::vector<double>& values, const std::vector<time_t>& timeSteps)
{
CVF_ASSERT(values.size() == timeSteps.size());
clearData();
m_originalValues = std::make_pair(values, timeSteps);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaTimeHistoryCurveResampler::resampleAndComputePeriodEndValues(DateTimePeriod period)
{
computePeriodEndValues(period);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaTimeHistoryCurveResampler::resampleAndComputeWeightedMeanValues(DateTimePeriod period)
{
computeWeightedMeanValues(period);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<time_t>& RiaTimeHistoryCurveResampler::resampledTimeSteps() const
{
return m_timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>& RiaTimeHistoryCurveResampler::resampledValues() const
{
return m_values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<time_t> RiaTimeHistoryCurveResampler::timeStepsFromTimeRange(DateTimePeriod period, time_t minTime, time_t maxTime)
{
if(minTime > maxTime) return std::vector<time_t>();
auto firstOriginalTimeStep = QDT::fromTime_t(minTime);
auto lastOriginalTimeStep = QDT::fromTime_t(maxTime);
auto currTimeStep = firstResampledTimeStep(firstOriginalTimeStep, period);
std::vector<time_t> timeSteps;
while (QDT::lessThan(currTimeStep, lastOriginalTimeStep))
{
timeSteps.push_back(currTimeStep.toTime_t());
currTimeStep = QDT::addPeriod(currTimeStep, period);
}
timeSteps.push_back(currTimeStep.toTime_t());
return timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaTimeHistoryCurveResampler::computeWeightedMeanValues(DateTimePeriod period)
{
size_t origDataSize = m_originalValues.second.size();
size_t oi = 0;
auto& origTimeSteps = m_originalValues.second;
auto& origValues = m_originalValues.first;
computeResampledTimeSteps(period);
m_values.reserve(m_timeSteps.size());
for (size_t i = 0; i < m_timeSteps.size(); i++)
{
double wMean = 0.0;
time_t periodStart = i > 0 ? m_timeSteps[i - 1] :
QDT::subtractPeriod(QDT::fromTime_t(m_timeSteps[0]), period).toTime_t();
time_t periodEnd = m_timeSteps[i];
time_t periodLength = periodEnd - periodStart;
while(true)
{
time_t origTimeStep = 0;
double origValue = 0.0;
if (oi > origDataSize) break;
if (oi < origDataSize)
{
origTimeStep = origTimeSteps[oi];
origValue = origValues[oi] != DOUBLE_INF ? origValues[oi] : 0.0;
}
else
{
origTimeStep = periodEnd;
origValue = 0.0;
}
if (oi == 0)
{
if (origTimeStep == m_timeSteps[i])
{
wMean += origValue;
oi++;
break;
}
origValue = 0.0;
}
time_t startTime = oi > 0 ? std::max(origTimeSteps[oi - 1], periodStart) : periodStart;
time_t endTime = std::min(origTimeStep, periodEnd);
wMean += origValue * (endTime - startTime) / periodLength;
if (origTimeStep > m_timeSteps[i]) break;
if (origTimeStep == m_timeSteps[i])
{
oi++;
break;
}
oi++;
}
m_values.push_back(wMean);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaTimeHistoryCurveResampler::computePeriodEndValues(DateTimePeriod period)
{
size_t origDataSize = m_originalValues.second.size();
size_t oi = 0;
auto& origTimeSteps = m_originalValues.second;
auto& origValues = m_originalValues.first;
computeResampledTimeSteps(period);
m_values.reserve(m_timeSteps.size());
for (size_t i = 0; i < m_timeSteps.size(); i++)
{
while (oi < origDataSize && origTimeSteps[oi] < m_timeSteps[i]) oi++;
time_t origTimeStep = oi < origDataSize ? origTimeSteps[oi] : m_timeSteps[i];
double origValue = oi < origDataSize ? origValues[oi] : origValues[oi - 1];
double value;
if (oi > 0 && origTimeStep >= m_timeSteps[i])
{
value = interpolatedValue(m_timeSteps[i], origTimeSteps[oi - 1], origValues[oi - 1], origTimeStep, origValue);
}
else
{
value = origValue;
}
m_values.push_back(value);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaTimeHistoryCurveResampler::clearData()
{
m_timeSteps.clear();
m_values.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaTimeHistoryCurveResampler::computeResampledTimeSteps(DateTimePeriod period)
{
CVF_ASSERT(period != DateTimePeriod::NONE && m_originalValues.second.size() > 0);
auto firstOriginalTimeStep = QDT::fromTime_t(m_originalValues.second.front());
auto lastOriginalTimeStep = QDT::fromTime_t(m_originalValues.second.back());
clearData();
auto currTimeStep = firstResampledTimeStep(firstOriginalTimeStep, period);
while (QDT::lessThan(currTimeStep, lastOriginalTimeStep))
{
m_timeSteps.push_back(currTimeStep.toTime_t());
currTimeStep = QDT::addPeriod(currTimeStep, period);
}
// Add last time step
m_timeSteps.push_back(currTimeStep.toTime_t());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QDateTime RiaTimeHistoryCurveResampler::firstResampledTimeStep(const QDateTime& firstTimeStep, DateTimePeriod period)
{
QDateTime truncatedTime = QDT::truncateTime(firstTimeStep, period);
if (QDT::lessThan(truncatedTime, firstTimeStep)) return QDT::addPeriod(truncatedTime, period);
return truncatedTime;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaTimeHistoryCurveResampler::interpolatedValue(time_t t, time_t t1, double v1, time_t t2, double v2)
{
CVF_ASSERT(t2 >= t1);
if (t <= t1) return v1;
if (t >= t2) return v2;
return (v2 - v1) * (double)(t - t1) / (double)(t2 - t1) + v1;
}
@@ -0,0 +1,61 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiaCurveDataTools.h"
#include "RiaQDateTimeTools.h"
#include <QDateTime>
using QDT = RiaQDateTimeTools;
//==================================================================================================
///
//==================================================================================================
class RiaTimeHistoryCurveResampler
{
public:
RiaTimeHistoryCurveResampler();
void setCurveData(const std::vector<double>& values,
const std::vector<time_t>& timeSteps);
void resampleAndComputePeriodEndValues(DateTimePeriod period);
void resampleAndComputeWeightedMeanValues(DateTimePeriod period);
const std::vector<time_t>& resampledTimeSteps() const;
const std::vector<double>& resampledValues() const;
static std::vector<time_t> timeStepsFromTimeRange(DateTimePeriod period, time_t minTime, time_t maxTime);
private:
void computeWeightedMeanValues(DateTimePeriod period);
void computePeriodEndValues(DateTimePeriod period);
void clearData();
void computeResampledTimeSteps(DateTimePeriod period);
static QDateTime firstResampledTimeStep(const QDateTime& firstTimestep, DateTimePeriod period);
inline double interpolatedValue(time_t t, time_t t1, double v1, time_t t2, double v2);
private:
std::pair<std::vector<double>, std::vector<time_t>> m_originalValues;
std::vector<time_t> m_timeSteps;
std::vector<double> m_values;
};
@@ -0,0 +1,73 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaWeightedGeometricMeanCalculator.h"
#include "cvfAssert.h"
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaWeightedGeometricMeanCalculator::RiaWeightedGeometricMeanCalculator()
: m_aggregatedWeightedValue(0.0)
, m_aggregatedWeight(0.0)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaWeightedGeometricMeanCalculator::addValueAndWeight(double value, double weight)
{
CVF_ASSERT(weight >= 0.0);
// This can be a very big number, consider other algorithms if that becomes a problem
m_aggregatedWeightedValue += (std::log(value) * weight);
m_aggregatedWeight += weight;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaWeightedGeometricMeanCalculator::weightedMean() const
{
if (m_aggregatedWeight > 1e-7)
{
return std::exp(m_aggregatedWeightedValue / m_aggregatedWeight);
}
return 0.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaWeightedGeometricMeanCalculator::aggregatedWeight() const
{
return m_aggregatedWeight;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaWeightedGeometricMeanCalculator::validAggregatedWeight() const
{
return m_aggregatedWeight > 1.0e-12;
}
@@ -0,0 +1,38 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaWeightedGeometricMeanCalculator
{
public:
RiaWeightedGeometricMeanCalculator();
void addValueAndWeight(double value, double weight);
double weightedMean() const;
double aggregatedWeight() const;
bool validAggregatedWeight() const;
private:
double m_aggregatedWeightedValue;
double m_aggregatedWeight;
};
@@ -0,0 +1,72 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaWeightedHarmonicMeanCalculator.h"
#include "cvfAssert.h"
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaWeightedHarmonicMeanCalculator::RiaWeightedHarmonicMeanCalculator()
: m_aggregatedWeightedValue(0.0)
, m_aggregatedWeight(0.0)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaWeightedHarmonicMeanCalculator::addValueAndWeight(double value, double weight)
{
CVF_ASSERT(weight > 1.0e-12 && std::abs(value) > 1.0e-12);
m_aggregatedWeightedValue += weight / value;
m_aggregatedWeight += weight;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaWeightedHarmonicMeanCalculator::weightedMean() const
{
if (validAggregatedWeight())
{
return m_aggregatedWeight / m_aggregatedWeightedValue;
}
CVF_ASSERT(false);
return 0.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaWeightedHarmonicMeanCalculator::aggregatedWeight() const
{
return m_aggregatedWeight;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaWeightedHarmonicMeanCalculator::validAggregatedWeight() const
{
return m_aggregatedWeight > 1.0e-12;
}
@@ -0,0 +1,38 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaWeightedHarmonicMeanCalculator
{
public:
RiaWeightedHarmonicMeanCalculator();
void addValueAndWeight(double value, double weight);
double weightedMean() const;
double aggregatedWeight() const;
bool validAggregatedWeight() const;
private:
double m_aggregatedWeightedValue;
double m_aggregatedWeight;
};
@@ -0,0 +1,40 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template<class T>
class RiaWeightedMeanCalculator
{
public:
RiaWeightedMeanCalculator();
void addValueAndWeight(T value, double weight);
T weightedMean() const;
double aggregatedWeight() const;
bool validAggregatedWeight() const;
private:
T m_aggregatedValue;
double m_aggregatedWeight;
};
#include "RiaWeightedMeanCalculator.inl"
@@ -0,0 +1,75 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "cvfAssert.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template<class T>
RiaWeightedMeanCalculator<T>::RiaWeightedMeanCalculator()
: m_aggregatedValue(T{})
, m_aggregatedWeight(0.0)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template<class T>
void RiaWeightedMeanCalculator<T>::addValueAndWeight(T value, double weight)
{
CVF_ASSERT(weight >= 0.0);
m_aggregatedValue = m_aggregatedValue + value * weight;
m_aggregatedWeight += weight;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template<class T>
T RiaWeightedMeanCalculator<T>::weightedMean() const
{
bool validWeights = validAggregatedWeight();
CVF_TIGHT_ASSERT(validWeights);
if (validWeights)
{
return m_aggregatedValue * (1.0 / m_aggregatedWeight);
}
return T{};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template<class T>
double RiaWeightedMeanCalculator<T>::aggregatedWeight() const
{
return m_aggregatedWeight;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template<class T>
bool RiaWeightedMeanCalculator<T>::validAggregatedWeight() const
{
return m_aggregatedWeight > 1.0e-12;
}
@@ -33,9 +33,10 @@ public:
static QString tryFindMatchingSimWellName(QString searchName);
static QString tryFindMatchingWellPath(QString wellName);
private:
static QString tryMatchNameInList(QString searchName,
const std::vector<QString>& nameList);
private:
static QString tryMatchName(QString searchName,
const std::vector<QString>& nameList,
std::function<QString(QString)> stringFormatter = nullptr);
@@ -0,0 +1,34 @@
set (SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaPolyArcLineSampler.h
${CMAKE_CURRENT_LIST_DIR}/RiaWellPlanCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RiaSCurveCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RiaArcCurveCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RiaJCurveCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RiaLineArcWellPathCalculator.h
)
set (SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaPolyArcLineSampler.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaWellPlanCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaSCurveCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaArcCurveCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaJCurveCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaLineArcWellPathCalculator.cpp
)
list(APPEND CODE_HEADER_FILES
${SOURCE_GROUP_HEADER_FILES}
)
list(APPEND CODE_SOURCE_FILES
${SOURCE_GROUP_SOURCE_FILES}
)
set (QT_MOC_HEADERS
${QT_MOC_HEADERS}
)
source_group( "Application\\Tools\\WellPathTools" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )
@@ -0,0 +1,103 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaArcCurveCalculator.h"
#include "RiaOffshoreSphericalCoords.h"
#include "cvfGeometryTools.h"
//--------------------------------------------------------------------------------------------------
/// + p1
/// t1 //
/// | + C
/// \
/// + p2
//--------------------------------------------------------------------------------------------------
RiaArcCurveCalculator::RiaArcCurveCalculator(cvf::Vec3d p1, cvf::Vec3d t1, cvf::Vec3d p2)
: m_radius(std::numeric_limits<double>::infinity())
, m_arcCS(cvf::Mat4d::ZERO)
, m_endAzi(0)
, m_endInc(0)
, m_curveStatus(OK)
{
bool isOk = t1.normalize();
if (!isOk)
{
// No tangent. Bail out
m_curveStatus = FAILED_INPUT_OVERLAP;
return;
}
cvf::Vec3d p1p2 = p2 - p1;
cvf::Vec3d t12 = p1p2.getNormalized(&isOk);
if (!isOk)
{
// p1 and p2 in the same place.
m_curveStatus = FAILED_INPUT_OVERLAP;
return;
}
cvf::Vec3d N = (t1 ^ t12).getNormalized(&isOk);
if (!isOk)
{
// P2 is on the p1 + k*t1 line. We have a straight line
m_curveStatus = OK_STRAIGHT_LINE;
RiaOffshoreSphericalCoords endTangent(t1);
m_endTangent = t1;
m_endAzi = endTangent.azi();
m_endInc = endTangent.inc();
m_radius = std::numeric_limits<double>::infinity();
m_arcAngle = 0;
m_arcLength = p1p2.length();
return;
}
cvf::Vec3d tr1 = (N ^ t1).getNormalized();
m_radius = 0.5 * p1p2.length() / (tr1.dot(t12));
cvf::Vec3d C = p1 + m_radius * tr1;
cvf::Vec3d nTr1 = -tr1;
m_arcCS = cvf::Mat4d::fromCoordSystemAxes( &nTr1, &t1, &N );
m_arcCS.setTranslation(C);
m_arcAngle = cvf::GeometryTools::getAngle(N, p1 - C, p2 - C);
m_arcLength = m_radius*m_arcAngle;
m_endTangent = N ^ (p2 - C).getNormalized();
RiaOffshoreSphericalCoords endTangent(m_endTangent);
m_endAzi = endTangent.azi();
m_endInc = endTangent.inc();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaArcCurveCalculator::RiaArcCurveCalculator(cvf::Vec3d p1, double azi1, double inc1, cvf::Vec3d p2)
{
cvf::Vec3d t1( RiaOffshoreSphericalCoords::unitVectorFromAziInc(azi1,inc1));
(*this) = RiaArcCurveCalculator(p1, t1, p2);
}
@@ -0,0 +1,69 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfBase.h"
#include "cvfVector3.h"
#include "cvfMatrix4.h"
//--------------------------------------------------------------------------------------------------
/// + p1
/// t1 //
/// | + C
/// \
/// + p2
//--------------------------------------------------------------------------------------------------
class RiaArcCurveCalculator
{
public:
RiaArcCurveCalculator(cvf::Vec3d p1, cvf::Vec3d t1, cvf::Vec3d p2);
RiaArcCurveCalculator(cvf::Vec3d p1, double azi1, double inc1, cvf::Vec3d p2);
enum CurveStatus
{
OK,
OK_STRAIGHT_LINE,
FAILED_INPUT_OVERLAP
};
CurveStatus curveStatus() const { return m_curveStatus;}
cvf::Mat4d arcCS() const { return m_arcCS; }
double radius() const { return m_radius;}
double arcAngle() const { return m_arcAngle; }
double arcLength() const { return m_arcLength; }
cvf::Vec3d center() const { return m_arcCS.translation();}
cvf::Vec3d normal() const { return cvf::Vec3d(m_arcCS.col(2));}
double endAzimuth() const { return m_endAzi; }
double endInclination() const { return m_endInc; }
cvf::Vec3d endTangent() const { return m_endTangent; }
private:
CurveStatus m_curveStatus;
double m_radius;
double m_arcLength;
double m_arcAngle;
cvf::Mat4d m_arcCS;
double m_endAzi;
double m_endInc;
cvf::Vec3d m_endTangent;
};
@@ -0,0 +1,100 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaJCurveCalculator.h"
#include "RiaOffshoreSphericalCoords.h"
#include "cvfMatrix3.h"
#include "RiaArcCurveCalculator.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaJCurveCalculator::RiaJCurveCalculator(cvf::Vec3d p1, double azi1, double inc1, double r1,
cvf::Vec3d p2)
: m_c1( cvf::Vec3d::UNDEFINED)
, m_n1( cvf::Vec3d::UNDEFINED)
, m_radius( std::numeric_limits<double>::infinity())
, m_curveStatus(OK)
{
cvf::Vec3d t1 (RiaOffshoreSphericalCoords::unitVectorFromAziInc(azi1, inc1));
cvf::Vec3d p1p2 = p2 - p1;
cvf::Vec3d tr1 = p1p2 - (p1p2.dot(t1)) * t1;
double tr1Length = tr1.length();
if (tr1Length < 1e-9)
{
// p2 is on the p1 + t12 line. Degenerates to a line.
m_curveStatus = OK_STRAIGHT_LINE;
m_firstArcEndpoint = p2;
m_endAzi = azi1;
m_endInc = inc1;
return;
}
tr1 /= tr1Length;
cvf::Vec3d c1 = p1 + r1 * tr1;
cvf::Vec3d p2c1 = c1 - p2;
double p2c1Length = p2c1.length();
if (p2c1Length < r1 || r1 == std::numeric_limits<double>::infinity())
{
// Radius is too big. We can not get to point 2 using the requested radius.
m_curveStatus = FAILED_RADIUS_TOO_LARGE;
RiaArcCurveCalculator arc(p1, t1, p2);
if ( arc.curveStatus() == RiaArcCurveCalculator::OK
|| arc.curveStatus() == RiaArcCurveCalculator::OK_STRAIGHT_LINE )
{
m_c1 = arc.center();
m_n1 = arc.normal();
m_firstArcEndpoint = p2;
m_endAzi = arc.endAzimuth();
m_endInc = arc.endInclination();
m_radius = arc.radius();
}
else
{
m_firstArcEndpoint = p2;
m_endAzi = azi1;
m_endInc = inc1;
}
return;
}
double d = sqrt( p2c1Length * p2c1Length - r1 * r1);
double betha = asin( r1/p2c1Length );
cvf::Vec3d tp2c1 = p2c1/p2c1Length;
cvf::Vec3d nc1 = t1 ^ tr1;
cvf::Vec3d tp11p2 = -tp2c1.getTransformedVector(cvf::Mat3d::fromRotation(nc1, betha));
m_firstArcEndpoint = p2 - d*tp11p2;
m_c1 = c1;
m_n1 = nc1;
RiaOffshoreSphericalCoords endTangent(tp11p2);
m_endAzi = endTangent.azi();
m_endInc = endTangent.inc();
}
@@ -0,0 +1,69 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfBase.h"
#include "cvfVector3.h"
//--------------------------------------------------------------------------------------------------
/// + p1
/// t1 //
/// | r1 + C
/// \
/// + firstArcEndpoint
/// \
/// \
/// + p2
//--------------------------------------------------------------------------------------------------
class RiaJCurveCalculator
{
public:
RiaJCurveCalculator(cvf::Vec3d p1, double azi1, double inc1, double r1,
cvf::Vec3d p2);
enum CurveStatus
{
OK,
OK_STRAIGHT_LINE,
FAILED_INPUT_OVERLAP,
FAILED_RADIUS_TOO_LARGE
};
CurveStatus curveStatus() const { return m_curveStatus;}
cvf::Vec3d firstArcEndpoint() const { return m_firstArcEndpoint; }
double radius() const { return m_radius; }
cvf::Vec3d firstCenter() const { return m_c1; }
cvf::Vec3d firstNormal() const { return m_n1; }
double endAzimuth() const { return m_endAzi; }
double endInclination() const { return m_endInc; }
private:
CurveStatus m_curveStatus;
cvf::Vec3d m_firstArcEndpoint;
double m_radius;
cvf::Vec3d m_c1;
cvf::Vec3d m_n1;
double m_endAzi;
double m_endInc;
};
@@ -0,0 +1,281 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaLineArcWellPathCalculator.h"
#include "cvfBase.h"
#include "cvfAssert.h"
#include "RiaOffshoreSphericalCoords.h"
#include "RiaJCurveCalculator.h"
#include "RiaSCurveCalculator.h"
#define M_PI 3.14159265358979323846 // pi
cvf::Vec3d smootheningTargetTangent(const cvf::Vec3d& p1, const cvf::Vec3d& p2, const cvf::Vec3d& p3);
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaLineArcWellPathCalculator::RiaLineArcWellPathCalculator(const cvf::Vec3d& referencePointXyz,
const std::vector<WellTarget>& activeWellPathTargets)
{
// Handle incomplete input
if (activeWellPathTargets.size() < 2)
{
m_startTangent = cvf::Vec3d::ZERO;
if (activeWellPathTargets.size() == 1)
{
m_lineArcEndpoints.push_back( activeWellPathTargets[0].targetPointXYZ + referencePointXyz );
m_targetStatuses.resize(activeWellPathTargets.size(),
{ !activeWellPathTargets[0].isTangentConstrained, 0.0, 0.0,
true, std::numeric_limits<double>::infinity(),
true, std::numeric_limits<double>::infinity() });
}
return;
}
m_targetStatuses.resize(activeWellPathTargets.size(), { false, 0.0, 0.0,
false, std::numeric_limits<double>::infinity(),
false, std::numeric_limits<double>::infinity() });
std::vector<WellTarget> adjustedWellPathTargets = activeWellPathTargets;
// Calculate sensible tangents for targets without a fixed one
if ( activeWellPathTargets.size() > 2 )
{
for ( size_t tIdx = 0; tIdx < activeWellPathTargets.size() - 2; ++tIdx )
{
if ( !activeWellPathTargets[tIdx+1].isTangentConstrained )
{
cvf::Vec3d tangent = smootheningTargetTangent(activeWellPathTargets[tIdx ].targetPointXYZ,
activeWellPathTargets[tIdx+1].targetPointXYZ,
activeWellPathTargets[tIdx+2].targetPointXYZ);
RiaOffshoreSphericalCoords tangentSphCS(tangent);
adjustedWellPathTargets[tIdx+1].azimuth = tangentSphCS.azi();
adjustedWellPathTargets[tIdx+1].inclination = tangentSphCS.inc();
adjustedWellPathTargets[tIdx+1].isTangentConstrained = true;
m_targetStatuses[tIdx+1].hasDerivedTangent = true;
m_targetStatuses[tIdx+1].resultAzimuth = tangentSphCS.azi();
m_targetStatuses[tIdx+1].resultInclination = tangentSphCS.inc();
}
}
}
m_lineArcEndpoints.push_back( activeWellPathTargets[0].targetPointXYZ + referencePointXyz );
// Handle first segment if it is not an S-Curve
size_t startSSegmentIdx = 0;
size_t endSSegementIdx = activeWellPathTargets.size() - 1;
if (!adjustedWellPathTargets[0].isTangentConstrained)
{
startSSegmentIdx = 1;
const WellTarget& target1 = adjustedWellPathTargets[0];
const WellTarget& target2 = adjustedWellPathTargets[1];
WellTargetStatus& target1Status = m_targetStatuses[0];
WellTargetStatus& target2Status = m_targetStatuses[1];
if (adjustedWellPathTargets[1].isTangentConstrained)
{
// Create an upside down J curve from target 2 back to 1
RiaJCurveCalculator jCurve(target2.targetPointXYZ,
target2.azimuth + M_PI,
M_PI - target2.inclination,
target2.radius1,
target1.targetPointXYZ);
if ( jCurve.curveStatus() == RiaJCurveCalculator::OK )
{
m_lineArcEndpoints.push_back(jCurve.firstArcEndpoint() + referencePointXyz);
}
else if ( jCurve.curveStatus() == RiaJCurveCalculator::FAILED_RADIUS_TOO_LARGE )
{
target2Status.hasOverriddenRadius1 = true;
target2Status.resultRadius1 = jCurve.radius();
}
m_lineArcEndpoints.push_back(target2.targetPointXYZ + referencePointXyz);
target1Status.hasDerivedTangent = true;
target1Status.resultAzimuth = jCurve.endAzimuth() + M_PI;
target1Status.resultInclination = M_PI - jCurve.endInclination();
}
else // The complete wellpath is a straight line from target 1 to 2
{
m_lineArcEndpoints.push_back(target2.targetPointXYZ + referencePointXyz );
cvf::Vec3d t12 = target2.targetPointXYZ - target1.targetPointXYZ;
RiaOffshoreSphericalCoords t12Sph(t12);
target1Status.hasDerivedTangent = true;
target1Status.resultAzimuth = t12Sph.azi();
target1Status.resultInclination = t12Sph.inc();
target2Status.hasDerivedTangent = true;
target2Status.resultAzimuth = t12Sph.azi();
target2Status.resultInclination = t12Sph.inc();
}
m_startTangent = RiaOffshoreSphericalCoords::unitVectorFromAziInc( target1Status.resultAzimuth, target1Status.resultInclination);
}
else
{
m_startTangent = RiaOffshoreSphericalCoords::unitVectorFromAziInc( activeWellPathTargets[0].azimuth, activeWellPathTargets[0].inclination);
}
if (!adjustedWellPathTargets.back().isTangentConstrained)
{
endSSegementIdx -= 1;
}
// Calculate S-curves
if ( activeWellPathTargets.size() > 1 )
{
for ( size_t tIdx = startSSegmentIdx; tIdx < endSSegementIdx; ++tIdx )
{
const WellTarget& target1 = adjustedWellPathTargets[tIdx];
const WellTarget& target2 = adjustedWellPathTargets[tIdx+1];
WellTargetStatus& target1Status = m_targetStatuses[tIdx];
WellTargetStatus& target2Status = m_targetStatuses[tIdx+1];
// Ignore targets in the same place
if ( (target1.targetPointXYZ - target2.targetPointXYZ).length() < 1e-6 ) continue;
if ( target1.isTangentConstrained
&& target2.isTangentConstrained )
{
RiaSCurveCalculator sCurveCalc(target1.targetPointXYZ,
target1.azimuth,
target1.inclination,
target1.radius2,
target2.targetPointXYZ,
target2.azimuth,
target2.inclination,
target2.radius1);
if ( sCurveCalc.solveStatus() != RiaSCurveCalculator::CONVERGED )
{
double p1p2Length = (target2.targetPointXYZ - target1.targetPointXYZ).length();
sCurveCalc = RiaSCurveCalculator::fromTangentsAndLength(target1.targetPointXYZ,
target1.azimuth,
target1.inclination,
0.2*p1p2Length,
target2.targetPointXYZ,
target2.azimuth,
target2.inclination,
0.2*p1p2Length);
//RiaLogging::warning("Using fall-back calculation of well path geometry between active target number: " + QString::number(tIdx+1) + " and " + QString::number(tIdx+2));
target1Status.hasOverriddenRadius2 = true;
target1Status.resultRadius2 = sCurveCalc.firstRadius();
target2Status.hasOverriddenRadius1 = true;
target2Status.resultRadius1 = sCurveCalc.secondRadius();
}
m_lineArcEndpoints.push_back(sCurveCalc.firstArcEndpoint() + referencePointXyz);
m_lineArcEndpoints.push_back(sCurveCalc.secondArcStartpoint() + referencePointXyz);
m_lineArcEndpoints.push_back(target2.targetPointXYZ + referencePointXyz);
}
}
}
// Handle last segment if (its not the same as the first) and it has not been handled as an S-Curve
if ( adjustedWellPathTargets.size() > 2 && endSSegementIdx < (adjustedWellPathTargets.size() - 1) )
{
size_t targetCount = adjustedWellPathTargets.size();
const WellTarget& target1 = adjustedWellPathTargets[targetCount-2];
const WellTarget& target2 = adjustedWellPathTargets[targetCount-1];
WellTargetStatus& target1Status = m_targetStatuses[targetCount-2];
WellTargetStatus& target2Status = m_targetStatuses[targetCount-1];
// Create an ordinary J curve
RiaJCurveCalculator jCurve(target1.targetPointXYZ,
target1.azimuth,
target1.inclination,
target1.radius2,
target2.targetPointXYZ);
if ( jCurve.curveStatus() == RiaJCurveCalculator::OK )
{
m_lineArcEndpoints.push_back(jCurve.firstArcEndpoint() + referencePointXyz);
}
else if ( jCurve.curveStatus() == RiaJCurveCalculator::FAILED_RADIUS_TOO_LARGE )
{
target1Status.hasOverriddenRadius2 = true;
target1Status.resultRadius2 = jCurve.radius();
}
m_lineArcEndpoints.push_back(target2.targetPointXYZ + referencePointXyz);
target2Status.hasDerivedTangent = true;
target2Status.resultAzimuth = jCurve.endAzimuth();
target2Status.resultInclination = jCurve.endInclination();
}
}
cvf::Vec3d smootheningTargetTangent(const cvf::Vec3d& p1, const cvf::Vec3d& p2, const cvf::Vec3d& p3)
{
cvf::Vec3d t12 = p2 - p1;
cvf::Vec3d t23 = p3 - p2;
double length12 = t12.length();
double length23 = t23.length();
t12 /= length12; // Normalize
t23 /= length23; // Normalize
cvf::Vec3d t1t2Hor(t12);
t1t2Hor.z() = 0.0;
double t12HorLength = t1t2Hor.length();
cvf::Vec3d t23Hor(t23);
t23Hor.z() = 0.0;
double t23HorLength = t23Hor.length();
// Calculate weights as combo of inverse distance and horizontal component
double w12 = t12HorLength * 1.0/length12;
double w23 = t23HorLength * 1.0/length23;
// Weight the tangents
t12 *= w12; // Weight
t23 *= w23; // Weight
// Sum and normalization of weights
cvf::Vec3d averageTangent = 1.0/(w12 + w23) * (t12 + t23);
return averageTangent;
}
@@ -0,0 +1,63 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfBase.h"
#include "cvfVector3.h"
#include <vector>
class RiaLineArcWellPathCalculator
{
public:
struct WellTarget
{
cvf::Vec3d targetPointXYZ;
bool isTangentConstrained;
double azimuth;
double inclination;
double radius1;
double radius2;
};
RiaLineArcWellPathCalculator(const cvf::Vec3d& referencePointXyz,
const std::vector<RiaLineArcWellPathCalculator::WellTarget>& targets);
struct WellTargetStatus
{
bool hasDerivedTangent;
double resultAzimuth;
double resultInclination;
bool hasOverriddenRadius1;
double resultRadius1;
bool hasOverriddenRadius2;
double resultRadius2;
};
cvf::Vec3d startTangent() const { return m_startTangent; }
const std::vector<cvf::Vec3d>& lineArcEndpoints() const { return m_lineArcEndpoints;}
const std::vector<WellTargetStatus>& targetStatuses() const { return m_targetStatuses;}
private:
cvf::Vec3d m_startTangent;
std::vector<cvf::Vec3d> m_lineArcEndpoints;
std::vector<WellTargetStatus> m_targetStatuses;
};
@@ -0,0 +1,189 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaPolyArcLineSampler.h"
#include "RiaArcCurveCalculator.h"
#include "cvfGeometryTools.h"
#include "cvfMatrix4.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaPolyArcLineSampler::RiaPolyArcLineSampler(const cvf::Vec3d& startTangent, const std::vector<cvf::Vec3d>& lineArcEndPoints)
: m_startTangent(startTangent)
, m_lineArcEndPoints(lineArcEndPoints)
, m_samplingsInterval(0.15)
, m_isResamplingLines(true)
, m_totalMD(0.0)
, m_points(nullptr)
, m_meshDs(nullptr)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaPolyArcLineSampler::sampledPointsAndMDs(double sampleInterval,
bool isResamplingLines,
std::vector<cvf::Vec3d>* points,
std::vector<double>* mds)
{
CVF_ASSERT(sampleInterval > 0.0);
m_samplingsInterval = sampleInterval;
m_isResamplingLines = isResamplingLines;
double startMD = 0.0;
points->clear();
mds->clear();
std::vector<cvf::Vec3d> pointsNoDuplicates = RiaPolyArcLineSampler::pointsWithoutDuplicates(m_lineArcEndPoints);
if (pointsNoDuplicates.size() < 2) return;
m_points = points;
m_meshDs = mds;
m_totalMD = startMD;
cvf::Vec3d p1 = pointsNoDuplicates[0];
cvf::Vec3d p2 = pointsNoDuplicates[1];
m_points->push_back(p1);
m_meshDs->push_back(m_totalMD);
cvf::Vec3d t2 = m_startTangent;
for (size_t pIdx = 0; pIdx < pointsNoDuplicates.size() - 1; ++pIdx)
{
sampleSegment(t2, pointsNoDuplicates[pIdx], pointsNoDuplicates[pIdx + 1], &t2);
}
return;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaPolyArcLineSampler::sampleSegment(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent)
{
cvf::Vec3d p1p2 = p2 - p1;
CVF_ASSERT(p1p2.lengthSquared() > 1e-20);
if (cvf::GeometryTools::getAngle(t1, p1p2) < 1e-5)
{
sampleLine(p1, p2, endTangent);
}
else // resample arc
{
sampleArc(t1, p1, p2, endTangent);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RiaPolyArcLineSampler::pointsWithoutDuplicates(const std::vector<cvf::Vec3d>& points)
{
std::vector<cvf::Vec3d> outputPoints;
cvf::Vec3d previousPoint = cvf::Vec3d::UNDEFINED;
const double threshold = 1e-6;
for (const auto& p : points)
{
if (previousPoint.isUndefined() || ((previousPoint - p).lengthSquared()) > threshold)
{
outputPoints.push_back(p);
previousPoint = p;
}
}
return outputPoints;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaPolyArcLineSampler::sampleLine(cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent)
{
cvf::Vec3d p1p2 = p2 - p1;
double p1p2Length = p1p2.length();
if (p1p2Length > m_samplingsInterval && m_isResamplingLines)
{
cvf::Vec3d tp1p2 = p1p2 / p1p2Length;
double mdInc = m_samplingsInterval;
while (mdInc < p1p2Length)
{
cvf::Vec3d ps = p1 + mdInc * tp1p2;
m_points->push_back(ps);
m_meshDs->push_back(m_totalMD + mdInc);
mdInc += m_samplingsInterval;
}
}
m_totalMD += p1p2Length;
m_points->push_back(p2);
m_meshDs->push_back(m_totalMD);
(*endTangent) = p1p2.getNormalized();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaPolyArcLineSampler::sampleArc(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent)
{
// Find arc CS
RiaArcCurveCalculator CS_rad(p1, t1, p2);
double radius = CS_rad.radius();
cvf::Mat4d arcCS = CS_rad.arcCS();
double angleInc = m_samplingsInterval / radius;
cvf::Vec3d C = CS_rad.center();
cvf::Vec3d N = CS_rad.normal();
// Sample arc by
// Rotate vector an increment, and transform to arc CS
double arcAngle = cvf::GeometryTools::getAngle(N, p1 - C, p2 - C);
if (arcAngle / angleInc > 5000)
{
angleInc = arcAngle / 5000;
}
for (double angle = angleInc; angle < arcAngle; angle += angleInc)
{
cvf::Vec3d C_to_incP = cvf::Vec3d::X_AXIS;
C_to_incP *= radius;
C_to_incP.transformVector(cvf::Mat3d::fromRotation(cvf::Vec3d::Z_AXIS, angle));
C_to_incP.transformPoint(arcCS);
m_points->push_back(C_to_incP);
m_meshDs->push_back(m_totalMD + angle * radius);
}
m_totalMD += arcAngle * radius;
m_points->push_back(p2);
m_meshDs->push_back(m_totalMD);
(*endTangent) = CS_rad.endTangent();
}
@@ -0,0 +1,51 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfBase.h"
#include "cvfVector3.h"
#include <vector>
class RiaPolyArcLineSampler
{
public:
RiaPolyArcLineSampler(const cvf::Vec3d& startTangent, const std::vector<cvf::Vec3d>& lineArcEndPoints);
void sampledPointsAndMDs(double sampleInterval,
bool isResamplingLines,
std::vector<cvf::Vec3d>* points,
std::vector<double>* mds);
static std::vector<cvf::Vec3d> pointsWithoutDuplicates(const std::vector<cvf::Vec3d>& points);
private:
void sampleLine(cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent);
void sampleArc(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent);
void sampleSegment(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent);
std::vector<cvf::Vec3d>* m_points; // Internal temporary pointers to collections beeing filled.
std::vector<double>* m_meshDs;
double m_samplingsInterval;
bool m_isResamplingLines;
double m_totalMD;
cvf::Vec3d m_startTangent;
std::vector<cvf::Vec3d> m_lineArcEndPoints;
};
@@ -0,0 +1,454 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaSCurveCalculator.h"
#include "RiaOffshoreSphericalCoords.h"
#include "cvfMatrix4.h"
#include <cmath>
#include <iostream>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaSCurveCalculator::RiaSCurveCalculator(cvf::Vec3d p1, double azi1, double inc1, double rad1,
cvf::Vec3d p2, double azi2, double inc2, double rad2)
: m_isCalculationOK(false)
, m_p1(p1)
, m_p2(p2)
, m_firstArcEndpoint(p1 + 0.3*(p2-p1))
, m_secondArcStartpoint(p1 + 0.6*(p2-p1))
, m_r1(rad1)
, m_r2(rad2)
, m_ctrlPpointCurveStatus(NOT_SET)
, m_solveStatus(NOT_SOLVED)
{
initializeByFinding_q1q2(p1, azi1, inc1, rad1, p2, azi2, inc2, rad2);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaSCurveCalculator::RiaSCurveCalculator(cvf::Vec3d p1, cvf::Vec3d q1,
cvf::Vec3d p2, cvf::Vec3d q2)
: m_isCalculationOK(true)
, m_p1(p1)
, m_p2(p2)
, m_ctrlPpointCurveStatus(NOT_SET)
, m_solveStatus(NOT_SOLVED)
{
using Vec3d = cvf::Vec3d;
bool isOk = true;
m_isCalculationOK = true;
Vec3d tq1q2 = (q2 - q1).getNormalized(&isOk); // !ok means the control points are in the same place. Could fallback to use only one circle segment + one line.
m_isCalculationOK = m_isCalculationOK && isOk;
Vec3d t1 = (q1 - p1).getNormalized(&isOk); // !ok means no tangent specified. Could fallback to use only one circle segment + one line.
m_isCalculationOK = m_isCalculationOK && isOk;
Vec3d t2 = (p2 - q2).getNormalized(&isOk); // !ok means no tangent specified. Could fallback to use only one circle segment + one line or only one straight line if both tangents are missing
m_isCalculationOK = m_isCalculationOK && isOk;
if (!m_isCalculationOK)
{
m_ctrlPpointCurveStatus = FAILED_INPUT_OVERLAP;
}
{
Vec3d td1 = (tq1q2 - t1);
double td1Length = td1.length();
if ( td1Length > 1e-10 )
{
td1 /= td1Length;
m_c1 = q1 + ((q1 - p1).length() / (td1 * (-t1))) * td1;
m_r1 = (m_c1 - p1).length();
}
else // both control points are along t1. First curve has infinite radius
{
m_c1 = cvf::Vec3d::UNDEFINED;
m_r1 = std::numeric_limits<double>::infinity();
if (m_ctrlPpointCurveStatus == NOT_SET)
{
m_ctrlPpointCurveStatus = OK_INFINITE_RADIUS1;
}
}
}
{
Vec3d td2 = (-tq1q2 + t2);
double td2Length = td2.length();
if ( td2Length > 1e-10 )
{
td2 /= td2Length;
m_c2 = q2 + ((q2 - p2).length() / (td2 * (t2))) * td2;
m_r2 = (m_c2 - p2).length();
}
else // both control points are along t2. Second curve has infinite radius
{
m_c2 = cvf::Vec3d::UNDEFINED;
m_r2 = std::numeric_limits<double>::infinity();
if (m_ctrlPpointCurveStatus == NOT_SET)
{
m_ctrlPpointCurveStatus = OK_INFINITE_RADIUS2;
}
else if (m_ctrlPpointCurveStatus == OK_INFINITE_RADIUS1)
{
m_ctrlPpointCurveStatus = OK_INFINITE_RADIUS12;
}
}
}
m_firstArcEndpoint = q1 + (q1 - p1).length() * tq1q2;
m_secondArcStartpoint = q2 - (q2 - p2).length() * tq1q2;
if (((q1 - p1).length() + (q2 - p2).length()) > (q2 - q1).length()) // first arc end and second arc start is overlapping
{
m_ctrlPpointCurveStatus = FAILED_ARC_OVERLAP;
m_isCalculationOK = false;
}
if (m_ctrlPpointCurveStatus == NOT_SET)
{
m_ctrlPpointCurveStatus = OK;
}
// The Circle normals. Will be set to cvf::Vec3d::ZERO if undefined.
m_n1 = (t1 ^ tq1q2).getNormalized();
m_n2 = (tq1q2 ^ t2).getNormalized();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaSCurveCalculator RiaSCurveCalculator::fromTangentsAndLength(cvf::Vec3d p1, double azi1, double inc1, double lengthToQ1,
cvf::Vec3d p2, double azi2, double inc2, double lengthToQ2)
{
cvf::Vec3d t1(RiaOffshoreSphericalCoords::unitVectorFromAziInc(azi1,inc1));
cvf::Vec3d t2(RiaOffshoreSphericalCoords::unitVectorFromAziInc(azi2,inc2));
cvf::Vec3d Q1 = p1 + lengthToQ1 * t1;
cvf::Vec3d Q2 = p2 - lengthToQ2 * t2;
RiaSCurveCalculator curveFromControlPoints(p1, Q1,
p2, Q2);
return curveFromControlPoints;
}
//--------------------------------------------------------------------------------------------------
///
/// Needs to calculate J^-1 * [R1_error, R2_error]
/// | dR1_dq1 dR1_dq2 | 1 | dR2_dq2 -dR1_dq2 |
/// J = | | J^-1 = ---------------------------------- | |
/// | dR2_dq1 dR2_dq2 | dR1_dq1*dR2_dq2 - dR1_dq2*dR2_dq1 | -dR2_dq1 dR1_dq1 |
///
/// | q1_step | | R1_Error |
/// | | = - J^-1 | |
/// | q2_step | | R2_Error |
///
//--------------------------------------------------------------------------------------------------
void calculateNewStepsFromJacobi(double dR1_dq1, double dR1_dq2,
double dR2_dq1, double dR2_dq2,
double R1_error,
double R2_error,
double * newStepq1,
double * newStepq2)
{
double invJacobiScale = 1.0/ (dR1_dq1*dR2_dq2 - dR2_dq1*dR1_dq2);
double invJacobi_R1q1 = invJacobiScale * dR2_dq2;
double invJacobi_R1q2 = invJacobiScale * -dR1_dq2;
double invJacobi_R2q1 = invJacobiScale * -dR2_dq1;
double invJacobi_R2q2 = invJacobiScale * dR1_dq1;
(*newStepq1) = - (invJacobi_R1q1 * R1_error + invJacobi_R1q2 * R2_error);
(*newStepq2) = - (invJacobi_R2q1 * R1_error + invJacobi_R2q2 * R2_error) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool isZeroCrossing(double newError, double oldError, double maxError)
{
if ( (newError < -maxError && maxError < oldError) || (newError > maxError && -maxError > oldError) )
{
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
/// Iterating with changing q1, q2 (lengths along tangent) to find solution with R1 = r1 and R2 = r2
/// R1(q1, q2), R2(q1, q2)
///
//--------------------------------------------------------------------------------------------------
void RiaSCurveCalculator::initializeByFinding_q1q2(cvf::Vec3d p1, double azi1, double inc1, double r1,
cvf::Vec3d p2, double azi2, double inc2, double r2)
{
// Algorithm options
const int maxIterations = 40;
const double maxError = 0.01;
const double closeError = 40*maxError;
const double maxStepSize = 1.0e9;
const double maxLengthToQ = 1.0e10;
bool enableBackstepping = false;
//#define USE_JACOBI_UPDATE
//#define DEBUG_OUTPUT_ON
// Needs the initial partial derivatives to see the direction of change
// dR1/dq1, dR1/dq2, dR2/dq1, dR2/dq2
// Selects a sensible point in the domain for the evaluation
double p1p2Length = (p2 - p1).length();
double delta = 0.01 * p1p2Length;
double initialq1q2 = 0.2 * p1p2Length;
double deltaPos = initialq1q2 + delta;
RiaSCurveCalculator ev_0 = RiaSCurveCalculator::fromTangentsAndLength(p1, azi1, inc1, initialq1q2,
p2, azi2, inc2, initialq1q2);
if ( ev_0.curveStatus() == RiaSCurveCalculator::OK_INFINITE_RADIUS12 )
{
*this = ev_0;
this->m_solveStatus = CONVERGED;
return;
} // Todo: Handle infinite radius in one place
RiaSCurveCalculator ev_dq1 = RiaSCurveCalculator::fromTangentsAndLength(p1, azi1, inc1, deltaPos,
p2, azi2, inc2, initialq1q2);
RiaSCurveCalculator ev_dq2 = RiaSCurveCalculator::fromTangentsAndLength(p1, azi1, inc1, initialq1q2,
p2, azi2, inc2, deltaPos);
// Initial Jacobi
double dR1_dq1 = ((r1 - ev_dq1.firstRadius()) - (r1 - ev_0.firstRadius()))/delta;
double dR2_dq2 = ((r2 - ev_dq2.secondRadius()) - (r2 - ev_0.secondRadius()))/delta;
// Initial function value (error)
double R1_error = r1 - ev_0.firstRadius();
double R2_error = r2 - ev_0.secondRadius();
// First steps
double q1Step = -R1_error/dR1_dq1;
double q2Step = -R2_error/dR2_dq2;
#ifdef USE_JACOBI_UPDATE
double dR1_dq2 = ((r1 - ev_dq2.firstRadius()) - (r1 - ev_0.firstRadius()))/delta;
double dR2_dq1 = ((r2 - ev_dq1.secondRadius()) - (r2 - ev_0.secondRadius()))/delta;
calculateNewStepsFromJacobi(dR1_dq1, dR1_dq2,
dR2_dq1, dR2_dq2,
R1_error, R2_error,
&q1Step, &q2Step);
#endif
double q1 = initialq1q2;
double q2 = initialq1q2;
#ifdef DEBUG_OUTPUT_ON
std::cout << std::endl;
std::cout << "Targets: R1, R2: " << r1 << " , " << r2 << std::endl;
std::cout << 0 << ": " << q1Step << " , " << q2Step
<< " : " << q1 << " , " << q2 << " | "
<< ev_0.isOk() << " : " << ev_0.firstRadius() << " , " << ev_0.secondRadius()
<< " : " << R1_error << " , " << R2_error << std::endl;
#endif
SolveStatus solveResultStatus = NOT_SOLVED;
int backstepLevel = 0;
int iteration = 1;
for ( iteration = 1; iteration < maxIterations; ++iteration)
{
if ( fabs(q1Step) > maxStepSize || fabs(q2Step) > maxStepSize )
{
solveResultStatus = FAILED_MAX_TANGENT_STEP_REACHED;
break;
}
std::string q1R1StepCorrMarker;
std::string q2R2StepCorrMarker;
if (q1 + q1Step < 0) { q1Step = -0.9*q1; q1R1StepCorrMarker = "*";}
if (q2 + q2Step < 0) { q2Step = -0.9*q2; q2R2StepCorrMarker = "*"; }
q1 += q1Step;
q2 += q2Step;
if (fabs(q1) > maxLengthToQ || fabs(q2) > maxLengthToQ)
{
/// Max length along tangent reached
solveResultStatus = FAILED_MAX_LENGTH_ALONG_TANGENT_REACHED;
break;
}
RiaSCurveCalculator ev_1 = RiaSCurveCalculator::fromTangentsAndLength(p1, azi1, inc1, q1,
p2, azi2, inc2, q2);
double R1_error_new = r1 - ev_1.firstRadius();
double R2_error_new = r2 - ev_1.secondRadius();
#ifdef DEBUG_OUTPUT_ON
std::cout << iteration << ": " << q1Step << q1R1StepCorrMarker << " , " << q2Step<< q2R2StepCorrMarker
<< " : " << q1 << " , " << q2 << " | "
<< ev_1.isOk() << " : " << ev_1.firstRadius() << " , " << ev_1.secondRadius()
<< " : " << R1_error_new << " , " << R2_error_new ;
#endif
if ( ( fabs(R1_error_new) < maxError || ev_1.curveStatus() == OK_INFINITE_RADIUS1 )
&& ( fabs(R2_error_new) < maxError || ev_1.curveStatus() == OK_INFINITE_RADIUS2 ) )
{
ev_0 = ev_1;
// Result ok !
solveResultStatus = CONVERGED;
#ifdef DEBUG_OUTPUT_ON
std::cout << std::endl;
#endif
break;
}
if (enableBackstepping) // Experimental back-stepping
{
bool isZeroCrossingR1 = isZeroCrossing(R1_error_new, R1_error, maxError);
bool isZeroCrossingR2 = isZeroCrossing(R2_error_new, R2_error, maxError);
if ( isZeroCrossingR2 || isZeroCrossingR1 )
{
q1 -= q1Step;
q2 -= q2Step;
//if (isZeroCrossingR1)
q1Step = 0.9* q1Step * fabs(R1_error) /(fabs(R1_error_new) + fabs(R1_error));
//if (isZeroCrossingR2)
q2Step = 0.9* q2Step * fabs(R2_error) /(fabs(R2_error_new) + fabs(R2_error));
++backstepLevel;
#ifdef DEBUG_OUTPUT_ON
std::cout << " Backstep needed. "<< std::endl;
#endif
continue;
}
else
{
backstepLevel = 0;
}
}
#ifdef DEBUG_OUTPUT_ON
std::cout << std::endl;
#endif
#ifdef USE_JACOBI_UPDATE
/// Update Jacobi using Broyden
// (R_error_n-Rerror_n-1) - Jn-1*dq
// J_n = Jn-1 + --------------------------------- (dq)T
// | dqn |^2
//
double dR1_error = R1_error_new - R1_error;
double dR2_error = R2_error_new - R2_error;
R1_error = R1_error_new;
R2_error = R2_error_new;
double stepNormScale = 1.0/(q1Step*q1Step + q2Step*q2Step);
dR1_dq1 = dR1_dq1 + stepNormScale * (q1Step * (dR1_error - q1Step * dR1_dq1 + q2Step * dR1_dq2) );
dR1_dq2 = dR1_dq2 + stepNormScale * (q2Step * (dR1_error - q1Step * dR1_dq1 + q2Step * dR1_dq2) );
dR2_dq1 = dR2_dq1 + stepNormScale * (q1Step * (dR2_error - q1Step * dR2_dq1 + q2Step * dR2_dq2) );
dR2_dq2 = dR2_dq2 + stepNormScale * (q2Step * (dR2_error - q1Step * dR2_dq1 + q2Step * dR2_dq2) );
calculateNewStepsFromJacobi(dR1_dq1, dR1_dq2,
dR2_dq1, dR2_dq2,
R1_error, R2_error,
&q1Step, &q2Step);
#else
dR1_dq1 = ((r1 - ev_1.firstRadius()) - (r1 - ev_0.firstRadius()))/q1Step;
dR2_dq2 = ((r2 - ev_1.secondRadius()) - (r2 - ev_0.secondRadius()))/q2Step;
R1_error = R1_error_new;
R2_error = R2_error_new;
q1Step = -R1_error/dR1_dq1;
q2Step = -R2_error/dR2_dq2;
#endif
ev_0 = ev_1;
}
*this = ev_0;
if ( iteration >= maxIterations )
{
m_solveStatus = FAILED_MAX_ITERATIONS_REACHED;
// Max iterations reached
}
else
{
m_solveStatus = solveResultStatus;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaSCurveCalculator::dump() const
{
cvf::Vec3d v_C1 = firstCenter();
cvf::Vec3d v_C2 = secondCenter();
cvf::Vec3d v_N1 = firstNormal();
cvf::Vec3d v_N2 = secondNormal();
cvf::Vec3d v_P11 = firstArcEndpoint();
cvf::Vec3d v_P22 = secondArcStartpoint();
std::cout << " P1: " << "[ " << m_p1[0] << " " << m_p1[1] << " " << m_p1[2] << " " << std::endl;
std::cout << " P11: " << "[ " << v_P11[0] << " " << v_P11[1] << " " << v_P11[2] << " " << std::endl;
std::cout << " P22: " << "[ " << v_P22[0] << " " << v_P22[1] << " " << v_P22[2] << " " << std::endl;
std::cout << " P2: " << "[ " << m_p2[0] << " " << m_p2[1] << " " << m_p2[2] << " " << std::endl;
std::cout << " C1: " << "[ " << v_C1[0] << " " << v_C1[1] << " " << v_C1[2] << " " << std::endl;
std::cout << " C2: " << "[ " << v_C2[0] << " " << v_C2[1] << " " << v_C2[2] << " " << std::endl;
std::cout << " N1: " << "[ " << v_N1[0] << " " << v_N1[1] << " " << v_N1[2] << " " << std::endl;
std::cout << " N2: " << "[ " << v_N2[0] << " " << v_N2[1] << " " << v_N2[2] << " " << std::endl;
std::cout << " R1: " << "[ " << firstRadius() << " ]" << std::endl;
std::cout << " R2: " << "[ " << secondRadius() << " ]" << std::endl;
std::cout << " CtrPointStatus: " << m_ctrlPpointCurveStatus << " SolveStatus: " << m_solveStatus << std::endl;
}
@@ -0,0 +1,90 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfBase.h"
#include "cvfVector3.h"
class RiaSCurveCalculator
{
public:
RiaSCurveCalculator( cvf::Vec3d p1, double azi1, double inc1, double r1,
cvf::Vec3d p2, double azi2, double inc2, double r2 );
RiaSCurveCalculator( cvf::Vec3d p1, cvf::Vec3d q1,
cvf::Vec3d p2, cvf::Vec3d q2 );
enum CurveStatus
{
NOT_SET,
OK,
OK_INFINITE_RADIUS1,
OK_INFINITE_RADIUS2,
OK_INFINITE_RADIUS12,
FAILED_INPUT_OVERLAP,
FAILED_ARC_OVERLAP
};
enum SolveStatus
{
NOT_SOLVED,
CONVERGED,
FAILED_MAX_LENGTH_ALONG_TANGENT_REACHED,
FAILED_MAX_TANGENT_STEP_REACHED,
FAILED_MAX_ITERATIONS_REACHED
};
bool isOk() const { return m_isCalculationOK; }
CurveStatus curveStatus() const { return m_ctrlPpointCurveStatus;}
SolveStatus solveStatus() const { return m_solveStatus;}
cvf::Vec3d firstArcEndpoint() const { return m_firstArcEndpoint; }
cvf::Vec3d secondArcStartpoint() const { return m_secondArcStartpoint; }
cvf::Vec3d firstCenter() const { return m_c1; }
cvf::Vec3d secondCenter() const { return m_c2; }
cvf::Vec3d firstNormal() const { return m_n1; }
cvf::Vec3d secondNormal() const { return m_n2; }
double firstRadius() const { return m_r1; }
double secondRadius() const { return m_r2; }
void dump() const;
static RiaSCurveCalculator fromTangentsAndLength(cvf::Vec3d p1, double azi1, double inc1, double lengthToQ1,
cvf::Vec3d p2, double azi2, double inc2, double lengthToQ2 );
private:
void initializeByFinding_q1q2( cvf::Vec3d p1, double azi1, double inc1, double r1,
cvf::Vec3d p2, double azi2, double inc2, double r2 );
bool m_isCalculationOK;
CurveStatus m_ctrlPpointCurveStatus;
SolveStatus m_solveStatus;
cvf::Vec3d m_p1;
cvf::Vec3d m_p2;
cvf::Vec3d m_firstArcEndpoint;
cvf::Vec3d m_secondArcStartpoint;
cvf::Vec3d m_c1;
cvf::Vec3d m_c2;
cvf::Vec3d m_n1;
cvf::Vec3d m_n2;
double m_r1;
double m_r2;
};
Loaded 100 of 2847 files, more files were not shown because too many files have changed in this diff. Show more